📄 wd.c
字号:
} return 0; case GET_BIOS_GEOMETRY: { geometry_t geom; if (args == NULL) return EINVAL; geom = (geometry_t) args; geom->flags = GF_PARTITIONED; geom->tracks = (((bootparams.sec_cyl_hi & 0xc0) << 2) | bootparams.cyl_lo) + 1; geom->heads = bootparams.hd + 1; geom->sectorspertrack = bootparams.sec_cyl_hi & 0x3f; geom->bytespersector = SECTOR_SIZE; } return 0; case READ_PART_TAB: { part_t parttab; if (args == NULL) return EINVAL; parttab = (part_t) args; bcopy(WD0.parttab, parttab, PARTS * sizeof(struct part)); } return 0; case WRITE_PART_TAB: { part_t parttab; struct seek seekargs; buf_t b; int result; if (args == NULL) return EINVAL; parttab = (part_t) args; /* Write new partition table to disk */ b = bget(SECTOR_SIZE); blen(b) = SECTOR_SIZE; seekargs.offset = 0; seekargs.whence = SEEK_SET; if ((result = wd_ioctl(SEEK_BLOCK, &seekargs)) < 0) {#if _DEBUG kprintf("wd_ioctl: seek failed (%s)\n", strerror(result));#endif brel(b); return result; } else if ((result = wd_read(&b)) < 0) {#if _DEBUG kprintf("wd_ioctl: read failed (%s)\n", strerror(result));#endif brel(b); return result; } bcopy(parttab, WD0.parttab, PARTS * sizeof(struct part)); write_parttab(parttab, bstart(b)); if ((result = wd_write(&b)) < 0) {#if _DEBUG kprintf("wd_ioctl: write failed (%s)\n", strerror(result));#endif brel(b); return result; } } return 0; case GET_BUFFER_SIZE: if (args == NULL) return EINVAL; *((u_long *) args) = SECTOR_SIZE; return 0; case SEEK_BLOCK: { seek_t seekargs = (seek_t) args; if (args == NULL || seekargs->whence != SEEK_SET) return EINVAL; WD0.blkno = seekargs->offset; WD0.track = WD0.blkno / (WD0.heads * WD0.sectorspertrack); WD0.head = (WD0.blkno / WD0.sectorspertrack) % WD0.heads; WD0.sector = WD0.blkno % WD0.sectorspertrack + 1; } return 0; default: } return ENOTTY;}intwd_read(buf_t * b){ u_short *wdbuf; int nsectors, i, result; if (b == NULL || *b == NULL || blen(*b) % SECTOR_SIZE != 0) return EINVAL; nsectors = blen(*b) / SECTOR_SIZE; /* Issue read sectors command */ if ((result = wd_wait(WDCMD_READ, WDCS_DRDY, WDTIMEOUT_DRDY)) < 0) {#if _DEBUG kprintf("wd_read: no drdy (%s)\n", strerror(result));#endif return result; } outb(WD0.wdc->iobase + WDC_SECTORCNT, nsectors); outb(WD0.wdc->iobase + WDC_SECTOR, (u_char) WD0.sector); outb(WD0.wdc->iobase + WDC_TRACKLSB, (u_char) WD0.track); outb(WD0.wdc->iobase + WDC_TRACKMSB, (u_char) (WD0.track >> 8)); outb(WD0.wdc->iobase + WDC_DRVHD, ((u_char) WD0.head & 0x0f) | 0xa0); outb(WD0.wdc->iobase + WDC_COMMAND, WDCMD_READ); for (i = 0; i < nsectors; i++) { /* Wait for data ready */ if (!(inb(WD0.wdc->iobase + WDC_ALT_STATUS) & WDCS_DRQ) && (result = wd_wait(WDCMD_READ, WDCS_DRQ, WDTIMEOUT_DRQ)) < 0) {#if _DEBUG kprintf("wd_read: no drq (%s)\n", strerror(result));#endif return result; } /* Read sector data */ wdbuf = (u_short *) (bstart(*b) + i * SECTOR_SIZE); insw(WD0.wdc->iobase + WDC_DATA, wdbuf, SECTOR_SIZE / 2); /* Clear drive interrupt */ inb(WD0.wdc->iobase + WDC_STATUS); /* Clear interrupt controllers */ outb(I8259_SLV_CTRL, I8259_EOI_HD); outb(I8259_MSTR_CTRL, I8259_EOI_CAS); } return 0;}intwd_write(buf_t * b){ u_short *wdbuf; int nsectors, i, j, result; if (b == NULL || *b == NULL || blen(*b) % SECTOR_SIZE != 0) return EINVAL; nsectors = blen(*b) / SECTOR_SIZE; /* Issue write sectors command */ if ((result = wd_wait(WDCMD_WRITE, WDCS_DRDY, WDTIMEOUT_DRDY)) < 0) {#if _DEBUG kprintf("wd_write: no drdy (%s)\n", strerror(result));#endif return result; } outb(WD0.wdc->iobase + WDC_SECTORCNT, nsectors); outb(WD0.wdc->iobase + WDC_SECTOR, (u_char) WD0.sector); outb(WD0.wdc->iobase + WDC_TRACKLSB, (u_char) WD0.track); outb(WD0.wdc->iobase + WDC_TRACKMSB, (u_char) (WD0.track >> 8)); outb(WD0.wdc->iobase + WDC_DRVHD, ((u_char) WD0.head & 0x0f) | 0xa0); outb(WD0.wdc->iobase + WDC_COMMAND, WDCMD_WRITE); for (i = 0; i < nsectors; i++) { /* Wait for data ready */ if (!(inb(WD0.wdc->iobase + WDC_ALT_STATUS) & WDCS_DRQ) && (result = wd_wait(WDCMD_READ, WDCS_DRQ, WDTIMEOUT_DRQ)) < 0) {#if _DEBUG kprintf("wd_write: no drq (%s)\n", strerror(result));#endif return result; } /* Write sector data */ wdbuf = (u_short *) (bstart(*b) + i * SECTOR_SIZE); for (j = 0; j < SECTOR_SIZE / 2; j++) outw(WD0.wdc->iobase + WDC_DATA, wdbuf[j]); /* Clear drive interrupt */ inb(WD0.wdc->iobase + WDC_STATUS); /* Clear interrupt controllers */ outb(I8259_SLV_CTRL, I8259_EOI_HD); outb(I8259_MSTR_CTRL, I8259_EOI_CAS); } brel(*b); *b = NULL; return 0;}intwd0a_init(){ /* No partition specific initialization required */ return 0;}intwd0a_shut(){ /* No partition specific shutdown required */ return 0;}intwd0a_ioctl(int cmd, void *args){ if (cmd == SEEK_BLOCK) { seek_t seekargs; if (args == NULL || WD0.parttab[0].off == 0) return EINVAL; seekargs = (seek_t) args; seekargs->offset += WD0.parttab[0].off; } return wd_ioctl(cmd, args);}intwd0a_read(buf_t * b){ return wd_read(b);}intwd0a_write(buf_t * b){ return wd_write(b);}intwd0b_init(){ /* No partition specific initialization required */ return 0;}intwd0b_shut(){ /* No partition specific shutdown required */ return 0;}intwd0b_ioctl(int cmd, void *args){ if (cmd == SEEK_BLOCK) { seek_t seekargs; if (args == NULL || WD0.parttab[1].off == 0) return EINVAL; seekargs = (seek_t) args; seekargs->offset += WD0.parttab[1].off; } return wd_ioctl(cmd, args);}intwd0b_read(buf_t * b){ return wd_read(b);}intwd0b_write(buf_t * b){ return wd_write(b);}intwd0c_init(){ /* No partition specific initialization required */ return 0;}intwd0c_shut(){ /* No partition specific shutdown required */ return 0;}intwd0c_ioctl(int cmd, void *args){ if (cmd == SEEK_BLOCK) { seek_t seekargs; if (args == NULL || WD0.parttab[2].off == 0) return EINVAL; seekargs = (seek_t) args; seekargs->offset += WD0.parttab[2].off; } return wd_ioctl(cmd, args);}intwd0c_read(buf_t * b){ return wd_read(b);}intwd0c_write(buf_t * b){ return wd_write(b);}intwd0d_init(){ /* No partition specific initialization required */ return 0;}intwd0d_shut(){ /* No partition specific shutdown required */ return 0;}intwd0d_ioctl(int cmd, void *args){ if (cmd == SEEK_BLOCK) { seek_t seekargs; if (args == NULL || WD0.parttab[3].off == 0) return EINVAL; seekargs = (seek_t) args; seekargs->offset += WD0.parttab[3].off; } return wd_ioctl(cmd, args);}intwd0d_read(buf_t * b){ return wd_read(b);}intwd0d_write(buf_t * b){ return wd_write(b);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -