static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
{
- blkno_t block;
- uint16_t dptr;
int ct = 0;
int tries;
uint8_t err = 0;
uint8_t *driveptr = fd_tab + minor;
- uint8_t nblock;
if(rawflag == 2)
goto bad2;
fd_reset(driveptr);
fd_map = rawflag;
- if (rawflag == 0) {
- dptr = (uint16_t)udata.u_buf->bf_data;
- block = udata.u_buf->bf_blk;
- nblock = 2;
- } else {
- if (((uint16_t)udata.u_offset|udata.u_count) & BLKMASK)
- goto bad2;
- dptr = (uint16_t)udata.u_base;
- block = udata.u_offset >> 9;
- nblock = udata.u_count >> 8;
- }
+ if (rawflag && d_blkoff(BLKSHIFT))
+ return -1;
+
+ udata.u_nblock *= 2;
fd_cmd[0] = is_read ? FD_READ : FD_WRITE;
- fd_cmd[1] = block / 9; /* 2 sectors per block */
- fd_cmd[2] = ((block % 9) << 1) + 1; /*eww.. */
+ fd_cmd[1] = udata.u_block / 9; /* 2 sectors per block */
+ fd_cmd[2] = ((udata.u_block % 9) << 1) + 1; /*eww.. */
fd_cmd[3] = is_read ? OPDIR_READ: OPDIR_WRITE;
- fd_cmd[4] = dptr & 0xFF;
- fd_cmd[5] = dptr >> 8;
+ fd_cmd[4] = ((uint16_t)udata.u_dptr) & 0xFF;
+ fd_cmd[5] = ((uint16_t)udata.u_dptr) >> 8;
- while (ct < nblock) {
+ while (ct < udata.u_nblock) {
for (tries = 0; tries < 4 ; tries++) {
err = fd_operation(driveptr);
if (err == 0)
fd_cmd[2]++; /* Next sector for 2nd block */
ct++;
}
- return 1;
+ return udata.u_nblock << 8;
bad:
kprintf("fd%d: error %x\n", minor, err);
bad2:
return st;
}
-uint8_t hd_xfer(bool is_read, uint16_t addr)
+uint8_t hd_xfer(bool is_read)
{
/* Error ? */
if (hd_status & 0x01)
return hd_status;
if (is_read)
- hd_xfer_in(addr);
+ hd_xfer_in(udata.u_dptr);
else
- hd_xfer_out(addr);
+ hd_xfer_out(udata.u_dptr);
/* Should be returning READY, and maybe SEEKDONE */
return hd_status;
}
int hd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
{
- blkno_t block;
- staticfast uint16_t dptr;
uint16_t ct = 0;
staticfast uint8_t tries;
uint8_t err = 0;
uint8_t cmd = HDCMD_READ;
uint8_t head;
uint8_t sector;
- uint16_t nblock;
staticfast uint16_t cyl;
uint8_t dev = minor >> 4;
staticfast struct minipart *p;
p = &parts[dev];
- if (rawflag == 0) {
- dptr = (uint16_t)udata.u_buf->bf_data;
- block = udata.u_buf->bf_blk;
- nblock = 2;
- hd_page = 0; /* Kernel */
- } else if (rawflag == 1) {
- if (((uint16_t)udata.u_offset|udata.u_count) & BLKMASK)
- goto bad2;
- dptr = (uint16_t)udata.u_base;
- nblock = udata.u_count >> 8;
- block = udata.u_offset >> 9;
- hd_page = udata.u_page;
- } else if (rawflag == 2) {
- nblock = swapcnt >> 8; /* in 256 byte chunks */
- dptr = (uint16_t)swapbase;
+ /* FIXME: We only support 512 byte access chunks even for raw I/O */
+ hd_page = 0;
+ if (rawflag == 1) {
+ if (d_blkoff(BLKSHIFT))
+ return -1;
+ hd_page = udata.u_page; /* Kernel */
+ } else if (rawflag == 2)
hd_page = swappage;
- block = swapblk;
- } else
- goto bad2;
+
+ udata.u_nblock *= 2;
if (!is_read)
cmd = HDCMD_WRITE;
hd_precomp = p->g.precomp;
hd_seccnt = 1;
- sector = block;
+ sector = udata.u_block;
sector = (sector << 1) & 0x1E;
- cyl = block >> 4;
+ cyl = udata.u_block >> 4;
/* Do the maths once and on 16 bit numbers */
head = cyl % p->g.head;
if (minor)
cyl += p->cyl[(minor-1)&0x0F];
- while (ct < nblock) {
+ while (ct < udata.u_nblock) {
/* Head next bits, plus drive */
hd_sdh = 0x80 | head | (dev << 3);
hd_secnum = sector;
for us */
err = hd_waitdrq();
if (!(err & 1)) {
- err = hd_xfer(is_read, dptr);
+ err = hd_xfer(is_read);
/* Ready, no error ? */
if ((err & 0x41) == 0x40)
break;
if (tries == 3)
goto bad;
ct++;
- dptr += 256;
+ udata.u_dptr += 256;
sector++;
/* Cheaper than division! */
if (sector == 32) {
extern uint8_t hd_waitready(void);
extern uint8_t hd_waitdrq(void);
-extern uint8_t hd_xfer(bool is_read, uint16_t addr);
+extern uint8_t hd_xfer(bool is_read);
/* helpers in common memory for the block transfers */
-extern int hd_xfer_in(uint16_t addr);
-extern int hd_xfer_out(uint16_t addr);
+extern int hd_xfer_in(uint8_t *addr);
+extern int hd_xfer_out(uint8_t *addr);
#endif
#endif /* __DEVHD_DOT_H__ */
{
unsigned int dev = 0;
unsigned int i;
- uint8_t *d = tmpbuf();
/* Second half of second block */
- struct minipart *p = (struct minipart *)(d + 128);
+ struct minipart *p;
+
+ udata.u_dptr = tmpbuf();
+ p = (struct minipart *)(udata.u_dptr + 128);
+
for (dev = 0; dev < 4; dev++) {
hd_sdh = 0x80 | (dev << 3);
hd_cmd = HDCMD_RESTORE | RATE_4MS;
hd_cmd = HDCMD_READ;
if (hd_waitdrq() & 1)
continue;
- if((hd_xfer(1, (uint16_t)d) & 0x41) != 0x40)
+ if((hd_xfer(1) & 0x41) != 0x40)
continue;
kprintf("hd%c: ", dev + 'a');
if (p->g.magic != MP_SIG_0) {
hd_waitready();
memcpy(&parts[dev], p, sizeof(parts[dev]));
}
- brelse((bufptr)d);
+ brelse((bufptr)udata.u_dptr);
}