📄 sd.c
字号:
if ((media_in == 0) || ((sdc->sdc_firmware & SDCFW_MO) == 0)) return (index); } /****************/ /* HD & MO only */ /****************/ /* * Get drive capacity * (by READ CAPACITY command) */ retrycnt = 0;loop_rcap: if (retrycnt++ > MAXPROBERETRY) return (-4); scop_rcap(intr, sc, slave, SCSI_INTDIS, 8, (caddr_t)0); sc->sc_tstatus &= TGSTMASK; if (sc->sc_istatus != INST_EP) return (-5); if (sc->sc_tstatus == TGST_CC) { bzero((caddr_t)sce, RSEN_CNT); scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT, (caddr_t)sce); sc->sc_tstatus &= TGSTMASK; if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) return (-6); if (sderrordisp((caddr_t)sce, ii) == FORMAT_MODE_CORRUPTED) { scr->scr_nblock = 0; scr->scr_blocklen = DEV_BSIZE; sdd->sdd_flags |= SDDF_NONFMT; } else { DELAY(D100MSEC); /* wait 100 ms. */ goto loop_rcap; } } else if (sc->sc_tstatus != TGST_GOOD) { DELAY(D100MSEC); /* wait 100 ms. */ goto loop_rcap; } sdd->sdd_nsect = scr->scr_nblock + 1; sdd->sdd_sectsize = scr->scr_blocklen; index = identity_check(sci, scr->scr_nblock +1, unit); return (index);}staticsd_tstdrv(ii, sc) register struct iop/**/_device *ii; register struct scsi *sc;{ register struct sc_extnd *sce; register int intr; register int slave; register int retrycnt; struct sdc_softc *sdc; struct sdd_softc *sdd; sdc = &sdc_softc[ii->ii_ctlr]; sdd = &sdd_softc[ii->ii_unit]; intr = ii->ii_intr; slave = ii->ii_slave; sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0]; retrycnt = 0;loop_tst: if (retrycnt++ > MAXPROBERETRY) return (-1); scop_tst(intr, sc, slave, SCSI_INTDIS); sc->sc_tstatus &= TGSTMASK; if (sc->sc_istatus != INST_EP) { DELAY(D100MSEC); /* wait 100 ms. */ goto loop_tst; } switch (sc->sc_tstatus) { case TGST_CC: /* Get error code */ bzero((caddr_t)sce, RSEN_CNT); scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT, (caddr_t)sce); sc->sc_tstatus &= TGSTMASK; if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) { DELAY(D100MSEC); /* wait 100 ms. */ goto loop_tst; } if (sce->sce_extend != 0x70) goto loop_tst; switch (sce->sce_skey) { case 0x0: /* No Sense */ case 0x4: /* Hardware error */ case 0x6: /* Unit attention */ goto loop_tst; case 0x2: /* Not ready */ switch (sce->sce_sdecode) { case 0x04: /* Not ready */ /* * Drive not ready... so start.. */ scop_stst(intr, sc, slave, SCSI_INTDIS, SDSS_START); DELAY(D100MSEC * 10); /* wait 1 sec. */ goto loop_tst; case 0x0a: /* No Disk *//*MO*/ default: DELAY(D100MSEC); goto loop_tst; } break; case 0x03: if (sce->sce_sdecode == FORMAT_MODE_CORRUPTED) return (1); /* ignore error */ /* fall through */ default: return (-2); } break; case TGST_BUSY: goto loop_tst; case TGST_GOOD: break; default: return (-3); } return (1);}staticsd_other_pages(ii, sc) register struct iop/**/_device *ii; register struct scsi *sc;{ register struct sddevinfo *sdi; char **p; char *page; int length; int retrycnt; int len; sdi = &sddevinfo[ii->ii_type]; if ((p = sdi->other_pages) == NULL) return (0); /* * set other parameters */ while (page = *p++) { retrycnt = 0;loop_other_pages: bzero((caddr_t)sdtmp, 4); length = *(page + 1) + 2; bcopy(page, &sdtmp[4], length); if (retrycnt++ > MAXPROBERETRY) return (-1); scop_mselect(ii->ii_intr, sc, ii->ii_slave, SCSI_INTDIS, (SDM_PF<<24) + length +4, (caddr_t)sdtmp); sc->sc_tstatus &= TGSTMASK; if ((sc->sc_istatus != INST_EP) || (sc->sc_tstatus != TGST_GOOD)) { struct sc_extnd *sce; sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0]; scop_rsense(ii->ii_intr, sc, ii->ii_slave, SCSI_INTDIS, RSEN_CNT, (caddr_t)sce); switch (sce->sce_skey) { case 0x00: case 0x02: case 0x04: case 0x06: DELAY(D100MSEC); /* 100 ms. */ goto loop_other_pages; default: return (-1); } } } if (sdi->firm_flags & FIRM_CACHE_ON) sdc_softc[ii->ii_ctlr].sdc_firmware |= SDCFW_CACHE; else sdc_softc[ii->ii_ctlr].sdc_firmware &= ~SDCFW_CACHE; return (1);}staticsd_err_rcv(ii, sc) register struct iop/**/_device *ii; register struct scsi *sc;{ register struct sdc_softc *sdc; register int intr; register int slave; register int len; struct sc_extnd *sce; struct sdd_softc *sdd; struct sddevinfo *sdi; int retrycnt; char *erp_page; intr = ii->ii_intr; slave = ii->ii_slave; sdc = &sdc_softc[ii->ii_ctlr]; sdd = &sdd_softc[ii->ii_unit]; sdi = &sddevinfo[ii->ii_type]; sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0]; /* * set Default DISK sector size */ if (sdd->sdd_sectsize == 0) sdd->sdd_sectsize = DEV_BSIZE; if (sdi->ERP_page == NULL) { /* * use default error recovery parameters */ sdc->sdc_firmware |= SDCFW_DEFMODE; return (0); } if (sdi->firm_flags & FIRM_AWRE) sdc->sdc_firmware |= SDCFW_AWRE; if (sdi->firm_flags & FIRM_ARRE) sdc->sdc_firmware |= SDCFW_ARRE; /* * set ERROR RECOVERY PARAMETERS */loop_err_rcv: bzero((caddr_t)sdtmp, 4); erp_page = sdi->ERP_page; len = *(erp_page + 1) + 2; bcopy(erp_page, &sdtmp[4], len); scop_mselect(intr, sc, slave, SCSI_INTDIS, (SDM_PF<<24) + len +4, (caddr_t)sdtmp); sc->sc_tstatus &= TGSTMASK; if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) { if (sc->sc_tstatus == TGST_CC) { bzero((caddr_t)sce, RSEN_CNT); scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT, (caddr_t)sce); if (sce->sce_sdecode == 0x2a) { /* mode select parameter changed */ goto ercv_done; } else if (sce->sce_skey == 0x6) { /* unit attention */ goto loop_err_rcv; } } /* * use default ERROR RECOVERY mode */ sdc->sdc_firmware |= SDCFW_DEFMODE; sdc->sdc_firmware &= ~(SDCFW_AWRE|SDCFW_ARRE); }ercv_done: return (1);}staticsd_synctr_on(ii, sc) register struct iop/**/_device *ii; register struct scsi *sc;{ register struct sddevinfo *sdi; register struct sync_param *syncp; sdi = &sddevinfo[ii->ii_type]; if (sdi->firm_flags & FIRM_SYNCTR) { scinit(sc, ii->ii_slave, DEV_BSIZE); sc->sc_opcode = SCOP_TST; sc->sc_message = MSG_EXTND; /* extended message */ sc->sc_param[0] = MSG_EXTND; sc->sc_param[1] = 0x03; sc->sc_param[2] = 0x01; /* synchronous transfer */ sc->sc_param[3] = sdi->tr_period; /* transfer period */ sc->sc_param[4] = sdi->tr_offset; /* REQ offset */ if (sdc_softc[ii->ii_ctlr].sdc_firmware & SDCFW_CACHE) sc->sc_tstatus |= TS_CONTR_ON; /* contiguous TR ON */ else sc->sc_tstatus |= TS_CONTR_OFF; /* contiguous TR OFF */#ifdef news1800 if (scsi_berr_bug() != 0) { sc->sc_tstatus &= ~TS_CONTR_ON; sc->sc_tstatus |= TS_CONTR_OFF; }#endif if (sc->sc_tstatus & TS_CONTR_OFF) sdc_softc[ii->ii_ctlr].sdc_firmware &= ~SDCFW_CONTR; else sdc_softc[ii->ii_ctlr].sdc_firmware |= SDCFW_CONTR; sc_go(ii->ii_intr, sc, SCSI_INTDIS); syncp = &sd_sync_param[ii->ii_unit]; syncp->tr_period = sc->sc_param[3]; syncp->tr_offset = sc->sc_param[4]; if (sc->sc_param[4]) sdd_softc[ii->ii_unit].sdd_flags |= SDDF_SYNCTR; }}sdattach(ii) register struct iop/**/_device *ii;{ register int unit; register int i; struct sdc_softc *sdc; struct sdd_softc *sdd; int dummy; sdc = &sdc_softc[ii->ii_ctlr]; sdc->sdc_timeo = 60; /* timeout 60 sec */ unit = ii->ii_unit; sdd = &sdd_softc[unit]; sdd->sdd_stoptime = OD_STOPTIME; /* REMOVABLE MEDIA */ sdd->sdd_start = -2; sdmaptype(ii); if (sdwstart == 0) { sdwstart++; timeout(sdwatch, (caddr_t)0, hz); timeout(sdstop, (caddr_t)0, hz); } /* * initialize open flag */ for (i = 0; i < PNUM; i++) { sd_b_openf[unit][i] = 0; sd_c_openf[unit][i] = 0; } if (re_init_done > 0) return; if (sdc->sdc_firmware & SDCFW_HD) { /* * If device is Hard Disk, * then get partition information. */ sdrpartinfo(ii); dummy = DEV_BSIZE * sdstdrv[unit].rps * sdstdrv[unit].nsect; } else dummy = DEV_BSIZE * 40 * 31; if (ii->ii_dk >= 0 && dummy) dk_wpms[ii->ii_dk] = dummy / (2 * 1000000);}sdmaptype(ii) register struct iop/**/_device *ii;{ printf("sd%d: %s\n", ii->ii_unit, sddevinfo[ii->ii_type].call_name);}int sd_b_major = -1;sd_b_open(dev, flag) dev_t dev; int flag;{ sd_b_major = major(dev); return (_sdopen(dev, flag, S_IFBLK));}int sd_c_major = -1;sd_c_open(dev, flag) dev_t dev; int flag;{ sd_c_major = major(dev); return (_sdopen(dev, flag, S_IFCHR));}_sdopen(dev, flag, fmt) register dev_t dev; int flag; int fmt;{ register struct iop/**/_device *ii; register struct sdd_softc *sdd; register struct sdc_softc *sdc; register struct sddevinfo *sdi; register int unit; register int i; u_char *sdopfp; u_char old_sdopf; int media_changed; int s; int stat; struct scsi uscsi; unit = dev2unit(dev); if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0) return (ENXIO); sdd = &sdd_softc[unit]; sdc = &sdc_softc[ii->ii_ctlr]; sdi = &sddevinfo[ii->ii_type]; if (sdd->sdd_flags & SDDF_XUSE) return (EBUSY); /* * LOCK while sdstop() running. */ s = splclock(); while (sdc->sdc_state & SDCS_SCUNLOCK) { sdc->sdc_state |= SDCS_OPEN_WAIT; sleep((caddr_t)sdc, PRIBIO); } splx(s); /* * LOCK sdtmp buffer */ s = splclock(); while (sdtmp_stat & B_BUSY) { sdtmp_stat |= B_WANTED; sleep((caddr_t)sdtmp, PRIBIO); } sdtmp_stat |= B_BUSY; splx(s); sdd->sdd_flags |= SDDF_GETTMP; if ((fmt & S_IFMT) == S_IFBLK) sdopfp = &sd_b_openf[unit][dev2part(dev)]; else sdopfp = &sd_c_openf[unit][dev2part(dev)]; old_sdopf = *sdopfp; if (old_sdopf <= 1) *sdopfp += 1; /* 1: 1st open (ONLY_ONE) */ /* 2: already opened */ stat = 0; media_changed = 0; /* * From here on until pre_open_done is only for removable devices */ if ((sdc->sdc_firmware & SDCFW_RMB) == 0) goto pre_open_done; if ((minor(dev) & 0x80) || (dev == rootdev)) sdd->sdd_stoptime = 0x7fffffff; /*XXX*/ /* * Start Unit */ s = splclock(); /* inhibit clock interrupt */ i = sdd->sdd_start; sdd->sdd_start = sdd->sdd_stoptime; splx(s); if (i <= 0) { scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); uscsi.sc_opcode = SCOP_STST; uscsi.sc_count = SDSS_START; if (sdcmd(dev, &uscsi)) { sdd->sdd_start = i; if ((flag & FWRITE) == 0) goto sdopen_setup; stat = EIO; goto pre_open_done; } } /* * prevent medium removal */ scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); uscsi.sc_opcode = SCOP_MEDRMV; uscsi.sc_count = SDRMV_PREV; if (sdcmd(dev, &uscsi)) { stat = EIO; goto pre_open_done; } sdd->sdd_flags |= SDDF_INHRMV;sdopen_setup: if ((sdd->sdd_flags & SDDF_SAMEDSK) == SDDF_DSKCHGD) { sdd->sdd_flags |= SDDF_SAMEDSK; media_changed = 1; /* * From here on until mo_check_done is only for MO device */ if ((sdc->sdc_firmware & SDCFW_MO) == 0) goto mo_check_done; /* * Mode Sense */ bzero(sdtmp, 36); scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize); uscsi.sc_cpoint = sdtmp; uscsi.sc_ctrnscnt = 36; uscsi.sc_opcode = SCOP_MSENSE; uscsi.sc_lad = (SDM_PF << 16)|((SDM_PC_CUR|SDM_PCODE_ALL) << 8); uscsi.sc_count = 36; if (sdcmd(dev, &uscsi) == 0) { /* * check Write Protect mode */ if (sdtmp[2] & 0x80) sdd->sdd_flags |= SDDF_WPROTECT; else sdd->sdd_flags &= ~SDDF_WPROTECT; /* * check Format Mode */ if (sdtmp[26] == 2) { ii->ii_type = search_index(SMO_S501); if (mo_disp_format) printf("sd%d: format mode 2 (original format)\n", unit); } else if (sdtmp[26] == 3) { int spare; spare = *(short *)&sdtmp[32]; if (spare == 2048) ii->ii_type = search_index(SMO_S501_ISO2); else ii->ii_type = search_index(SMO_S501_ISO); if (mo_disp_format) printf("sd%d: format mode 3 (ISO format) spare=%d\n", unit, spare); } else { sdd->sdd_flags |= SDDF_NONFMT; if (mo_disp_format) printf("sd%d: Non format\n", unit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -