📄 sd.c
字号:
{ register struct sd_softc *sc = &sd_softc[unit]; register struct hp_device *hp = sc->sc_hd; if (hp->hp_dk >= 0) { dk_busy |= 1 << hp->hp_dk; } scstart(hp->hp_ctlr);}/* * Return: * 0 if not really an error * <0 if we should do a retry * >0 if a fatal error */static intsderror(unit, sc, hp, stat) int unit, stat; register struct sd_softc *sc; register struct hp_device *hp;{ int cond = 1; sdsense[unit].status = stat; if (stat & STS_CHECKCOND) { struct scsi_xsense *sp; sc_request_sense(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, sdsense[unit].sense, sizeof(sdsense[unit].sense)); sp = (struct scsi_xsense *)sdsense[unit].sense; printf("sd%d: scsi sense class %d, code %d", unit, sp->class, sp->code); if (sp->class == 7) { printf(", key %d", sp->key); if (sp->valid) printf(", blk %d", *(int *)&sp->info1); switch (sp->key) { /* no sense, try again */ case 0: cond = -1; break; /* recovered error, not a problem */ case 1: cond = 0; break; } } printf("\n"); } return(cond);}/* * Interrupt */intsdintr(unit, stat) register int unit; int stat;{ register struct sd_softc *sc = &sd_softc[unit]; register struct hp_device *hp = sc->sc_hd; register struct scsi_queue *dq = &sc->sc_dq; register struct buf *bp = dq->dq_bp; int cond; if (stat == SC_IO_TIMEOUT) { printf("sdintr: sd%d timeout error\n", unit, stat); } if (hp->hp_dk >= 0) { dk_busy &=~ (1 << hp->hp_dk); if (stat == 0) { ++dk_seek[hp->hp_dk]; ++dk_xfer[hp->hp_dk]; dk_wds[hp->hp_dk] += bp->b_bcount >> 6; } } if (bp->b_flags & B_READ) { sd_iostat[unit].imin = min(dq->dq_imin, sd_iostat[unit].imin); if (dq->dq_imax > sd_iostat[unit].imax) { sd_iostat[unit].imax = dq->dq_imax;#ifdef SD_IOSTAT printf("sdintr: sd%d INPUT MAX = %d, MIN = %d\n", unit, sd_iostat[unit].imax, sd_iostat[unit].imin);#endif } } else { sd_iostat[unit].omin = min(dq->dq_omin, sd_iostat[unit].omin); if (dq->dq_omax > sd_iostat[unit].omax) { sd_iostat[unit].omax = dq->dq_omax;#ifdef SD_IOSTAT printf("sdintr: sd%d OUTPUT MAX = %d, MIN = %d\n", unit, sd_iostat[unit].omax, sd_iostat[unit].omin);#endif } } if (stat != 0) { if (stat > 0) {#ifdef DEBUGPRINT dbgprintall(); printf("\n");#endif cond = sderror(unit, sc, hp, stat); if (cond) { if (cond < 0 && sdtab[unit].b_errcnt++ < SDRETRY) { sdstart(unit); return; } } } else { if (sdtab[unit].b_errcnt++ < SDRETRY) { printf("sdintr: sd%d restart IO request\n", unit); sdstart(unit); return; } } bp->b_flags |= B_ERROR; bp->b_error = EIO; } sdtab[unit].b_errcnt = 0; sdtab[unit].b_actf = bp->b_actf; bp->b_resid = 0; biodone(bp); scfree(dq); if (sdtab[unit].b_actf) { sdustart(unit); } else { sdtab[unit].b_active = 0; }}/* * RAW Device Routines */intsdread(dev, uio, flags) dev_t dev; struct uio *uio; int flags;{ register int unit = sdunit(dev); return (physio(sdstrategy, NULL, dev, B_READ, minphys, uio));}intsdwrite(dev, uio, flags) dev_t dev; struct uio *uio; int flags;{ register int unit = sdunit(dev); return (physio(sdstrategy, NULL, dev, B_WRITE, minphys, uio));}intsdioctl(dev, cmd, data, flag, p) dev_t dev; int cmd; caddr_t data; int flag; struct proc *p;{ int unit = sdunit(dev); register struct sd_softc *sc = &sd_softc[unit]; register struct disklabel *lp = &sdlabel[unit]; int error = 0; switch (cmd) { case DIOCGDINFO: *(struct disklabel *)data = *lp; break; case DIOCGPART: ((struct partinfo *)data)->disklab = lp; ((struct partinfo *)data)->part = &lp->d_partitions[sdpart(dev)]; break; case DIOCWLABEL: case DIOCSDINFO: case DIOCWDINFO: break; default: error = ENOTTY; break; } return (error);}/* * Size */intsdsize(dev) dev_t dev;{ register int unit = sdunit(dev); register struct sd_softc *sc = &sd_softc[unit]; if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0) return(-1); return(sdlabel[unit].d_partitions[sdpart(dev)].p_size);}/* * Dump */intsddump(dev) dev_t dev;{}/* * Disk Subs *//* * Attempt to read a disk label from a device * using the indicated stategy routine. * The label must be partly set up before this: * secpercyl and anything required in the strategy routine * (e.g., sector size) must be filled in before calling us. * Returns null on success and an error string on failure. */char *sdreadlabel(dev, strat, lp) dev_t dev; int (*strat)(); register struct disklabel *lp;{ register struct buf *bp; struct disklabel *dlp; char *msg = NULL; if (lp->d_secperunit == 0) lp->d_secperunit = 0x1fffffff; lp->d_npartitions = 1; if (lp->d_partitions[0].p_size == 0) lp->d_partitions[0].p_size = 0x1fffffff; lp->d_partitions[0].p_offset = 0; bp = geteblk((int)lp->d_secsize); bp->b_dev = dev; bp->b_blkno = LABELSECTOR; bp->b_bcount = lp->d_secsize; bp->b_flags = B_BUSY | B_READ; (*strat)(bp); if (biowait(bp)) { msg = "I/O error"; } else { for (dlp = (struct disklabel *)bp->b_un.b_addr; dlp <= (struct disklabel *)(bp->b_un.b_addr+DEV_BSIZE-sizeof(*dlp)); dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { if (msg == NULL) msg = "no disk label"; } else if (dlp->d_npartitions > MAXPARTITIONS || dkcksum(dlp) != 0) msg = "disk label corrupted"; else { *lp = *dlp; msg = NULL; break; } } } bp->b_flags = B_INVAL | B_AGE; brelse(bp); return (msg);}#ifdef notyet/* * Checksum routine for OMRON native disklabel */#define OMRON_LBLSIZE 512u_shortomcksum(omp) register char *omp;{ register u_short *start, *end; register u_short sum = 0; start = (u_short *) omp; end = (u_short *) &start[(OMRON_LBLSIZE/sizeof(u_short) - 1)]; while (start < end) sum ^= *start++; printf("omcksum: saved ... 0x%s\n", hexstr(*end, 4)); printf("omcksum: calced ... 0x%s\n", hexstr(sum, 4)); return (sum);}/* * Write disk label back to device after modification. */sdwritelabel(dev, strat, lp) dev_t dev; int (*strat)(); register struct disklabel *lp;{ struct buf *bp; struct disklabel *dlp; int labelpart; int error = 0; labelpart = sdpart(dev); if (lp->d_partitions[labelpart].p_offset != 0) { if (lp->d_partitions[0].p_offset != 0) return (EXDEV); /* not quite right */ labelpart = 0; } bp = geteblk((int)lp->d_secsize); bp->b_dev = makedev(major(dev), sdminor(sdunit(dev), labelpart)); bp->b_blkno = LABELSECTOR; bp->b_bcount = lp->d_secsize; bp->b_flags = B_READ; (*strat)(bp); if (error = biowait(bp)) goto done; for (dlp = (struct disklabel *)bp->b_un.b_addr; dlp <= (struct disklabel *) (bp->b_un.b_addr + lp->d_secsize - sizeof(*dlp)); dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC && dkcksum(dlp) == 0) { omcksum(bp->b_un.b_addr);/* *dlp = *lp; bp->b_flags = B_WRITE; (*strat)(bp); error = biowait(bp); goto done; */ } } error = ESRCH;done: brelse(bp); return (error);}#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -