⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -