📄 idc.c
字号:
} if (idcustart(ui)) { sc->sc_softas = as; return; } } else { /* drive spun down */#ifdef IDCDEBUG printd(", drive not ready");#endif IDCDEBUG sc->sc_flags[ui->ui_unit] |= DEV_OFFLINE; sc->sc_offline[ui->ui_unit]++; } } else {#ifdef IDCDEBUG printd(", unsol. intr. unit %d", unit);#endif IDCDEBUG } }#ifdef IDCDEBUG printd("\n");#endif IDCDEBUG if (um->um_tab.b_actf && um->um_tab.b_active == 0) {#ifdef IDCDEBUG trace("stum",um->um_tab.b_actf);#endif IDCDEBUG (void) idcstart(um); }}idcwait(addr, n) register struct idcdevice *addr; register int n;{ register int i; while (--n && (addr->idccsr & IDC_CRDY) == 0) for (i = 10; i; i--) ; return (n);}idcread(dev, uio) register dev_t dev; register struct uio *uio;{ register int unit = minor(dev) >> 3; return (physio(idcstrategy, &ridcbuf[unit], dev, B_READ, minphys, uio));}idcwrite(dev, uio) register dev_t dev; register struct uio *uio;{ register int unit = minor(dev) >> 3; return (physio(idcstrategy, &ridcbuf[unit], dev, B_WRITE, minphys, uio));}/*ARGSUSED*/idcioctl(dev, cmd, data, flag) dev_t dev; int cmd; caddr_t data; int flag;{ register int unit = minor(dev) >> 3; register struct uba_device *ui = idcdinfo[unit]; register struct pt *pt = (struct pt *)data; register struct idc_softc *sc = &idc_softc; struct dkop *dkop; struct dkget *dkget; struct devget *devget; register int i; int error; int nspc; switch (cmd) { case DKIOCHDR: /* do header read/write */ break; case DIOCGETPT: /* 001 get partition table info */ /* * Do a structure copy into the user's data area */ *pt = idc_part[unit]; break; case DIOCDGTPT: /* return default partition table */ /* * Get number of sectors per cylinder */ nspc = idcst[ui->ui_type].nspc; /* * Get default block count and offset */ for( i = 0; i <= 7; i++ ) { pt->pt_part[i].pi_nblocks = idcst[ui->ui_type].sizes[i].nblocks; pt->pt_part[i].pi_blkoff = idcst[ui->ui_type].sizes[i].cyloff * nspc; } break; case DIOCSETPT: /* 001 set the driver partition tables */ /* * Only super users can set the pack's partition * table */ if ( !suser() ) return(EACCES); /* * Before we set the new partition tables make sure * that it will no corrupt any of the kernel data * structures */ if ( ( error = ptcmp( dev, &idc_part[unit], pt ) ) != 0 ) return(error); /* * Using the user's data to set the partition table * for the pack */ idc_part[unit] = *pt; /* * See if we need to update the superblock of the * "a" partition of this disk */ ssblk(dev,pt); /* * Just make sure that we set the valid bit */ idc_part[unit].pt_valid = PT_VALID; break; case DKIOCDOP: /* Disk operation */ if ( !suser() ) return(EACCES); break; case DKIOCGET: /* Get disk status */ break; case DEVIOCGET: /* Device status */ devget = (struct devget *)data; bzero(devget,sizeof(struct devget)); devget->category = DEV_DISK; /* Disk */ devget->bus = DEV_UB; /* Unibus */ bcopy(DEV_IDC,devget->interface, strlen(DEV_IDC)); /* IDC */ bcopy(sc->sc_device[unit], devget->device, strlen(sc->sc_device[unit])); /* RB?? */ devget->adpt_num = ui->ui_adpt; /* which adapter*/ devget->nexus_num = ui->ui_nexus; /* which nexus */ devget->bus_num = ui->ui_ubanum; /* which UBA */ devget->ctlr_num = ui->ui_ctlr; /* IDC 0 only */ devget->slave_num = ui->ui_slave; /* which plug */ bcopy(ui->ui_driver->ud_dname, devget->dev_name, strlen(ui->ui_driver->ud_dname)); /* Ultrix "rb" */ devget->unit_num = unit; /* which rb?? */ devget->soft_count = sc->sc_softcnt[unit]; /* soft er. cnt.*/ devget->hard_count = sc->sc_hardcnt[unit]; /* hard er. cnt.*/ devget->stat = sc->sc_flags[unit]; /* status */ devget->category_stat = DEV_DISKPART; /* which prtn. */ break; default: return (ENXIO); } return(0);}idcecc(ui) register struct uba_device *ui;{ register struct idcdevice *idc = (struct idcdevice *)ui->ui_addr; register struct buf *bp = idcutab[ui->ui_unit].b_actf; register struct uba_ctlr *um = ui->ui_mi; register struct idcst *st; register int i; struct idc_softc *sc = &idc_softc; struct uba_regs *ubp = ui->ui_hd->uh_uba; int bit, byte, mask; caddr_t addr; int reg, npf, o; int cn, tn, sn; npf = btop(idc->idcbcr + sc->sc_bcnt) - 1;; reg = btop(sc->sc_ubaddr) + npf; o = (int)bp->b_un.b_addr & PGOFSET; st = &idcst[ui->ui_type]; cn = sc->sc_cyl; tn = sc->sc_trk; sn = sc->sc_sect; um->um_tab.b_active = 1; /* Either complete or continuing... */ mprintf("rb%d%c: soft ecc sn%d\n", dkunit(bp), 'a'+(minor(bp->b_dev)&07), (cn*st->ntrak + tn) * st->nsect + sn + npf); mask = idc->idceccpat; i = idc->idceccpos - 1; /* -1 makes 0 origin */ bit = i&07; i = (i&~07)>>3; byte = i + o; while (i < 512 && (int)ptob(npf)+i < sc->sc_bcnt && bit > -11) { struct pte pte; pte = ubp->uba_map[reg + btop(byte)]; addr = ptob(pte.pg_pfnum)+ (byte & PGOFSET); putmemc(addr, getmemc(addr)^(mask<<bit)); byte++; i++; bit -= 8; } sc->sc_bcnt += idc->idcbcr; um->um_tab.b_errcnt = 0; /* error has been corrected */ return;}idcreset(uban) int uban;{ register struct uba_ctlr *um; register struct uba_device *ui; register unit; if ((um = idcminfo[0]) == 0 || um->um_ubanum != uban || um->um_alive == 0) return; printf(" idc0"); um->um_tab.b_active = 0; um->um_tab.b_actf = um->um_tab.b_actl = 0; if (um->um_ubinfo) { printf("<%d>", (um->um_ubinfo>>28)&0xf); um->um_ubinfo = 0; } for (unit = 0; unit < nNRB; unit++) { if ((ui = idcdinfo[unit]) == 0 || ui->ui_alive == 0) continue; idcutab[unit].b_active = 0; (void) idcustart(ui); } (void) idcstart(um);}idcwatch(){ register struct uba_ctlr *um; register unit; timeout(idcwatch, (caddr_t)0, hz); um = idcminfo[0]; if (um == 0 || um->um_alive == 0) return; if (um->um_tab.b_active == 0) { for (unit = 0; unit < nNRB; unit++) if (idcutab[unit].b_active) goto active; idcwticks = 0; return; }active: idcwticks++; if (idcwticks >= 20) { idcwticks = 0; printf("idc0: lost interrupt\n"); idcintr(0); }}/*ARGSUSED*/idcdump(dev, dumpinfo) dev_t dev; /* dump device */ struct dumpinfo dumpinfo; /* dump info */{#ifdef notdef struct idcdevice *idcaddr; char *start; char *start_tmp; int blk, unit; register struct uba_regs *uba; register struct uba_device *ui; struct idcst *st; union idc_dar dar; int nspg,ubatype; unit = minor(dev) >> 3; if (unit >= nNRB) return (ENXIO);#define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) ui = phys(struct uba_device *, idcdinfo[unit]); if (ui->ui_alive == 0) return (ENXIO); uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; ubatype = phys(struct uba_hd *, ui->ui_hd)->uba_type; ubainit(uba,ubatype); idcaddr = (struct idcdevice *)ui->ui_physaddr; if (idcwait(idcaddr, 100) == 0) return (EFAULT); /* * Since we can only transfer one track at a time, and * the rl02 has 256 byte sectors, all the calculations * are done in terms of physical sectors (i.e. num and blk * are in sectors not NBPG blocks. */ st = phys(struct idcst *, &idcst[ui->ui_type]); nspg = NBPG / st->nbps; dumpinfo.size_to_dump *= nspg; start = start_tmp = 0; /* * If a full dump is being performed, then this loop * will dump all of core. If a partial dump is being * performed, then as much of core as possible will be * dumped, leaving room for the u_area and the error logger * buffer. Please note that dumpsys predetermined what * type of dump will be performed. */ while ((dumpinfo.size_to_dump > 0) || (dumpinfo.partial_dump)) { register struct pte *io; register int i; daddr_t bn; bn = (dumplo + btop(start_tmp)) * nspg; dar.dar_cyl = bn / st->nspc + dumpinfo.blkoffs / st->nspc; bn %= st->nspc; dar.dar_trk = bn / st->nsect; dar.dar_sect = bn % st->nsect; blk = st->nsect - dar.dar_sect; if (dumpinfo.size_to_dump < blk) blk = dumpinfo.size_to_dump; io = uba->uba_map; for (i = 0; i < (blk + nspg - 1) / nspg; i++) *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; *(int *)io = 0; idcaddr->idccsr = IDC_CRDY | IDC_SEEK | unit<<8; if ((idcaddr->idccsr&IDC_DRDY) == 0) return (EFAULT); idcaddr->idcdar = dar.dar_dar; idcaddr->idccsr = IDC_SEEK | unit << 8; while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY)) != (IDC_CRDY|IDC_DRDY)) ; if (idcaddr->idccsr & IDC_ERR) { printf("rb%d: seek, csr=%b\n", unit, idcaddr->idccsr, IDCCSR_BITS); return (EIO); } idcaddr->idccsr = IDC_CRDY | IDC_WRITE | unit<<8; if ((idcaddr->idccsr&IDC_DRDY) == 0) return (EFAULT); idcaddr->idcbar = 0; /* start addr 0 */ idcaddr->idcbcr = - (blk * st->nbps); idcaddr->idcdar = dar.dar_dar; idcaddr->idccsr = IDC_WRITE | unit << 8; while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY)) != (IDC_CRDY|IDC_DRDY)) ; if (idcaddr->idccsr & IDC_ERR) { printf("rb%d: write, csr=%b\n", unit, idcaddr->idccsr, IDCCSR_BITS); return (EIO); } start += blk * st->nbps; start_tmp += blk * st->nbps; dumpinfo.size_to_dump -= blk; if ((dumpinfo.size_to_dump <= 0) && (dumpinfo.partial_dump)) { /* * If a partial dump is being performed.... */ /* Set size_to_dump to the number of pages to dump */ dumpinfo.size_to_dump = dumpinfo.pdump[NUM_TO_DUMP-dumpinfo.partial_dump].num_blks * nspg; /* Set start to starting address */ start = 0; start += dumpinfo.pdump[NUM_TO_DUMP-dumpinfo.partial_dump].start_addr; dumpinfo.partial_dump--; } } return (0);#endif notdef}idcsize(dev) dev_t dev;{ int unit = minor(dev) >> 3; struct uba_device *ui; struct idcst *st; if (unit >= nNRB || (ui = idcdinfo[unit]) == 0 || ui->ui_alive == 0) return (-1); /* * Sanity check 001 */ if ( idc_part[unit].pt_valid != PT_VALID ) panic("idcsize: invalid partition table "); return (idc_part[unit].pt_part[minor(dev) & 07].pi_nblocks);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -