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

📄 sd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		break;	/****************************************/	/*					*/	/*	REQUEST SENSE analysis		*/	/*					*/	/****************************************/	case SDCS_RSENSE:	case SDCS_PREVRMB|SDCS_RSENSE:	case SDCS_ECC|SDCS_RASREAD|SDCS_RSENSE:	case SDCS_ECC|SDCS_RASWRITE|SDCS_RSENSE:	case SDCS_ECCOFF|SDCS_RSENSE:	case SDCS_ECCOFF|SDCS_RASBLK|SDCS_RSENSE:	case SDCS_ECCOFF|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE:	case SDCS_ECC|SDCS_RASBLK|SDCS_RSENSE:	case SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE:		if (tstatus != TGST_GOOD) {			printf("sd%d: bad target status 0x%x\n",						unit, sc->sc_tstatus);			goto sdintr_error;		}		/*		 * error message print out		 */		code = sderrordisp(sce, ii);		if ((sdc->sdc_state == (SDCS_ECC|SDCS_RASBLK|SDCS_RSENSE)) ||		    (sdc->sdc_state == (SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE))) {			printf("sd%d: cannot reassign block %d\n",						unit, sdd->sdd_badsect);			goto sdintr_error;		}		if (sdc->sdc_state == (SDCS_PREVRMB|SDCS_RSENSE)) {			if (sce->sce_skey == 0x2) {				/*				 * Not ready				 */				sdc->sdc_state = SDCS_PREVRMB;				timeout(delay_medrmv, (caddr_t)ii, hz);				return;			}		}		/*			*/		/* RSENSE error handler	*/		/*			*/		switch (code) {		/********************************/		/*	continue		*/		/********************************/		/* NO SENSE */		case 0x00:	/* No Additional Sense Information */		/* RECOVERED ERROR */		case 0x38:	/* Recovered with Auto-Reallocation */			sdc->sdc_state &= ~SDCS_RSENSE;			goto check_target_status;		/********************************/		/*	continue or error	*/		/********************************/		/* ILLEGAL REQUEST */		case 0x21:	/* illegal Logical Block Address */			if (&st->sizes[dev2part(bp->b_dev)] == NULL)				goto sdintr_error;			if (bp->b_bcount > 0) {				bp->b_resid = bp->b_bcount				    - (sdd->sdd_badsect * sdd->sdd_sectsize				    - (st->sizes[dev2part(bp->b_dev)].sd_blkoff				    + dkblock(bp)) * DEV_BSIZE);			}			if (bp->b_resid >= bp->b_bcount || bp->b_resid <= 0) {				/*				 * all I/O failure				 */				bp->b_resid = bp->b_bcount;				goto sdintr_error;			}			/* Ignore error */			break;		/* MEDIUM ERROR */		case 0x31:	/* Medium Format Corrupted */			sdd->sdd_flags |= SDDF_NONFMT;			/* Ignore error */			break;		/********************************/		/*	more retry		*/		/********************************/		/* MEDIUM or RECOVERED ERROR */		case 0x10:	/* ID CRC Error */		case 0x12:	/* No Address Mark found in ID field */		case 0x13:	/* No Address Mark found in Data field */		case 0x14:	/* No recode found */		/* H/W or MEDIUM or RECOVERED ERROR */		case 0x15:	/* Seek Positioning Error */			if (sd_ignore_error) {				sdc->sdc_state = SDCS_NORMAL;				goto check_target_status;			}			/* fall through */		/* H/W ERROR */		case 0x01:	/* No Index/Address Mark Found signal */		case 0x02:	/* No Seek Complete */		case 0x06:	/* No Track Zero found */		/* H/W ERROR or RECOVERED ERROR */		case 0x03:	/* Write Fault */		case 0x08:	/* Logical Unit Communication Failure */		case 0x09:	/* Track Following Error */		case 0x0b:	/* Load/Unload Failure */		case 0x0c:	/* Spindle Failure */		case 0x0d:	/* Focus Failure */		case 0x0e:	/* Tracking Failure */		case 0x0f:	/* Drive Initialization Failure */			sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD|SDCS_REZERO;			scinit(sc, slave, sdd->sdd_sectsize); 			/* sc_cdb */			sc->sc_opcode = SCOP_REZERO;			sddgo(im);			return;		/********************************/		/*	re-allocate & retry	*/		/********************************/		/* MEDIUM or RECOVERED ERROR */		case 0x11:	/* Unrecovered Read Error */			if (sdc->sdc_state & SDCS_RASREAD) {sdintr_lostdata:				sdc->sdc_state =					SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA;				im->im_tab.b_active = 2;				scop_rasblk(intr, sc, slave,					SCSI_INTEN, sdd->sdd_badsect);				sdd->sdd_flags &= ~SDDF_VBADSECT;				return;			}			/* fall through */		/* RECOVERED ERROR */		case 0x17:	/* Recovered read data with retries */		case 0x18:	/* Recovered read data with ECC */			/*			 * set ECC ON & more retry			 */			if (sdc->sdc_firmware & SDCFW_DEFMODE)				goto sdintr_ecc;			if (sdc->sdc_state & SDCS_RASREAD)				goto sdintr_rasblk;			sdc->sdc_state = SDCS_ECC;			goto sdintr_msel_set;		/********************************/		/*	unit start & retry	*/		/********************************/		/* NOT READY */		case 0x04:	/* Drive Not Ready */			if (sdc->sdc_state & SDCS_ECC)				sdc->sdc_state = SDCS_ECCOFF|SDCS_RETRY;			else				sdc->sdc_state = SDCS_RETRY;			goto sdintr_stst;		/********************************/		/*	retry			*/		/********************************/		/* UNIT ATTENTION */		case 0x28:	/* Medium Changed */			sdd->sdd_flags &= ~(SDDF_NONFMT					    |SDDF_SAMEDSK					    |SDDF_REQ_EJECT					    |SDDF_XUSE					    |SDDF_INHRMV					    |SDDF_ERASEOFF);			/* fall through */		case 0x29: /* Power On or Reset or Bus Device Reset */			if (sdc->sdc_firmware & SDCFW_RMB) {				/***************************/				/* medium removable device */				/***************************/				sdc->sdc_state = SDCS_PREVRMB;				im->im_tab.b_active = 2;				scop_medrmv(intr, sc, slave,					    SCSI_INTEN, SDRMV_PREV);				return;			}		case 0x2a:	/* Mode Select Parameter Changed */		case 0x47:	/* SCSI interface bus parity error */			if (sdc->sdc_state & SDCS_ECC) {				sdc->sdc_state = SDCS_RETRY;				goto sdintr_msel_reset;			}			sdc->sdc_state = SDCS_NORMAL;			goto sdintr_exec;		/********************************/		/*	set error flag		*/		/********************************/		case 0x40:	/* RAM failure */		case 0x41:	/* Data Path diagnostic failure */		case 0x42:	/* Power On diagnostic failure */		case 0xb2:	/* Caddy load/eject failed */		case 0xb4:	/* Focus servo failure */		case 0xb5:	/* Spindle servo failure */		case 0xb6:	/* Caddy load mechanism failed */			goto sdintr_error;/*MO*/		case 0x80:	/* Limit Laser Life *//*MO*/		case 0x81:	/* Focus Coil Over-current Failure *//*MO*/		case 0x82:	/* Tracking Coil Over-current Failure *//*MO*/		case 0x83:	/* Temperature Alarm *//*CD*/	/*	case 0x80: */	/* Prevent bit is set *//*CD*/	/*	case 0x81: */	/* Logical unit is reserved *//*CD*/	/*	case 0x82: */	/* End of usr area encountered *//*CD*/	/*	case 0x83: */	/* Overlapped commands attempted */			goto sdintr_error;		default:			/*			 *	error detect, but what shall we do ?			 */	/*	case 0x05: */	/* Drive Not Selected */	/*	case 0x07: */	/* Multiple Drives Selected */	/*	case 0x0a: */	/* No disk */	/*	case 0x1a: */	/* Parameter overrun */	/*	case 0x1b: */	/* Synchronous transfer error */	/*	case 0x1d: */	/* Compare error */	/*	case 0x22: */	/* Illegal function for device type */	/*	case 0x23: */	/* Illegal function for Medium type */	/*	case 0x25: */	/* Illegal LUN */	/*	case 0x27: */	/* Write Protected */	/*	case 0x2b: */	/* Firmware has been downloaded */	/*	case 0x39: */	/* Automatic Reallocation Failure */	/*	case 0x43: */	/* Message Reject Error */	/*	case 0x45: */	/* Selection/Reselection failure */	/*	case 0x48: */	/* Initiator detected error */	/*	case 0x49: */	/* Inappropriate/illegal message */	/*	case 0x60: */	/* COPY: STATUS error */	/*	case 0x85: */	/* Audio address not valid */	/*	case 0xb0: */	/* Caddy not inserted in drive */	/*	case 0xb1: */	/* Unable to recover TOC */	/*	case 0xb3: */	/* CIRC unrecovered data error(L-EC off) */	/*	case 0xc3: */	/* COPY: Illegale CDB length */	/*	case 0xc5: */	/* COPY: Catastrophic error */	/*	case 0xc6: */	/* COPY: Illegal phase change */	/*	case 0xfc: */	/* COPY: MODE SENSE failed */			/*			 *	medium error			 */	/*	case 0x19: */	/* Defect list error */	/*	case 0x1c: */	/* Primary Defect List not found */	/*	case 0x30: */	/* Incompatible Cartridge */	/*	case 0x32: */	/* No Spare Defect Location Available */	/*	case 0x3a: */	/* Defect List Update Failure */	/*	case 0x3d: */	/* Defect List Not Available */			goto sdintr_error;		}		/*		 * No error detected or ignored.		 */		break;	/************************************************/	/*						*/	/*	PREVENT MEDIUM REMOVABLE COMMAND	*/	/*						*/	/************************************************/	case SDCS_PREVRMB:		if (tstatus == TGST_CC) {			sdc->sdc_state = SDCS_PREVRMB|SDCS_RSENSE;			goto sdintr_rsense;		}		sdd->sdd_flags |= SDDF_INHRMV;		if (sdc->sdc_state & SDCS_ECC) {			sdc->sdc_state = SDCS_RETRY;			goto sdintr_msel_reset;		}		sdc->sdc_state = SDCS_NORMAL;		goto sdintr_exec;		break;	/****************************************/	/*					*/	/*	REZERO done & RETRY COMMAND	*/	/*					*/	/****************************************/	case SDCS_ECC|SDCS_ECC_HOLD|SDCS_REZERO:		if (sdc->sdc_firmware & SDCFW_DEFMODE) {			sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD|SDCS_RETRY;			goto sdintr_stst;		}		sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD;		goto sdintr_msel_set;	/********************************/	/*				*/	/*	RETRY COMMAND		*/	/*				*/	/********************************/	case SDCS_RETRY:		sdc->sdc_state = SDCS_NORMAL;		goto sdintr_exec;	/************************************************/	/*						*/	/*	ERROR CORRECTION ON MODE SELECT result	*/	/*						*/	/************************************************/	case SDCS_ECC:		if (tstatus != TGST_GOOD) {			printf("sd%d: bad target status 0x%x\n",						unit, sc->sc_tstatus);			goto sdintr_error;		}sdintr_ecc:		if (bp->b_flags & B_READ) {			sdc->sdc_state = SDCS_ECC|SDCS_RASREAD;			im->im_tab.b_active = 2;			scop_rdwr(intr, sc, slave, SCSI_INTEN,					B_READ, sdwork,					sdd->sdd_badsect, sdd->sdd_sectsize);			return;		}		goto sdintr_rasblk;	/************************************************/	/*						*/	/*	READ DATA from BAD BLOCK result		*/	/*						*/	/************************************************/	case SDCS_ECC|SDCS_RASREAD:		if (tstatus == TGST_CC) {			sdc->sdc_state = SDCS_ECC|SDCS_RASREAD|SDCS_RSENSE;			goto sdintr_rsense;		} else if (tstatus != TGST_GOOD) {			printf("sd%d: bad target status 0x%x\n",						unit, sc->sc_tstatus);			printf("sd%d: cannot read block\n", unit);			goto sdintr_error;		}sdintr_rasblk:		if (sdd->sdd_flags & SDDF_WPROTECT)			goto sdintr_error;		sdc->sdc_state = SDCS_ECC|SDCS_RASBLK;		im->im_tab.b_active = 2;		scop_rasblk(intr, sc, slave, SCSI_INTEN, sdd->sdd_badsect);		sdd->sdd_flags &= ~SDDF_VBADSECT;		return;	/****************************************/	/*					*/	/*	REASSIGN BLOCK result		*/	/*					*/	/****************************************/	case SDCS_ECC|SDCS_RASBLK:		if (tstatus == TGST_CC) {			sdc->sdc_state = SDCS_ECC|SDCS_RASBLK|SDCS_RSENSE;			goto sdintr_rsense;		} else if (tstatus != TGST_GOOD) {			printf("sd%d: bad target status 0x%x\n",						unit, sc->sc_tstatus);			goto sdintr_error;		}		printf("sd%d: block %d is reassigned\n",			unit, sdd->sdd_badsect);		if (bp->b_flags & B_READ) {sdintr_raswrite:			sdc->sdc_state = SDCS_ECC|SDCS_RASWRITE;			im->im_tab.b_active = 2;			scop_rdwr(intr, sc, slave, SCSI_INTEN,					B_WRITE, sdwork,					sdd->sdd_badsect, sdd->sdd_sectsize);			return;		}		sdc->sdc_state = SDCS_RETRY;		goto sdintr_msel_reset;	/************************************************/	/*						*/	/*	WRITE DATA to REASSIGNED BLOCK result	*/	/*						*/	/************************************************/	case SDCS_ECC|SDCS_RASWRITE:		if (tstatus == TGST_CC) {			sdc->sdc_state = SDCS_ECC|SDCS_RASWRITE|SDCS_RSENSE;			goto sdintr_rsense;		} else if (tstatus != TGST_GOOD) {			printf("sd%d: bad target status 0x%x\n",						unit, sc->sc_tstatus);			goto sdintr_error;		}		sdc->sdc_state = SDCS_RETRY;		goto sdintr_msel_reset;	/****************************************/	/*					*/	/*	reset ECC & RETRY TIMES		*/	/*					*/	/****************************************/	case SDCS_ECCOFF|SDCS_RETRY:		sdc->sdc_state = SDCS_RETRY;		goto sdintr_msel_reset;	/********************************************************/	/*							*/	/*	READ DATA from BAD BLOCK result in faliure	*/	/*							*/	/********************************************************/	case SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA:		if (tstatus == TGST_CC) {			sdc->sdc_state =				SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE;			goto sdintr_rsense;		} else if (tstatus != TGST_GOOD) {			printf("sd%d: rasblk: bad target status 0x%x\n",				unit, sc->sc_tstatus);			goto sdintr_error;		}		bzero(sdwork, sdd->sdd_sectsize);		scop_rdwr(intr, sc, slave, SCSI_INTDIS,			B_WRITE, sdwork, sdd->sdd_badsect, sdd->sdd_sectsize);		printf("sd%d: block %d is reassigned (lost data)\n",			unit, sdd->sdd_badsect);		goto sdintr_error;	/****************************************/	/*					*/	/*	issue START UNIT command	*/	/*					*/	/****************************************/	case SDCS_ECC|SDCS_ECC_HOLD:		/*		 * Drive not ready... so start..		 */		sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD|SDCS_RETRY;sdintr_stst:		timeout(delay_start, (caddr_t)ii, hz);		return;	/****************************************/	/*					*/	/*	RETRY with ECC & more RETRYS	*/	/*					*/	/****************************************/	case SDCS_ECC|SDCS_ECC_HOLD|SDCS_RETRY:		sdc->sdc_state = SDCS_ECCOFF;sdintr_exec:		if (sdc->sdc_countcc++ > MAXRETRYCNT)			goto sdintr_error;		sdexec(bp);		return;	/****************************************/	/*					*/	/*	reset ECC & RETRY TIMES		*/	/*					*/	/****************************************/	case SDCS_ECCOFF:		if (tstatus == TGST_CC) {			sdc->sdc_state = SDCS_ECCOFF|SDCS_RSENSE;			goto sdintr_rsense;		} else if (tstatus != TGST_GOOD) {			printf("sd%d: bad target status 0x%x\n",				unit, sc->sc_tstatus);			goto sdintr_error;		}		sdc->sdc_state = SDCS_NORMAL;		goto sdintr_msel_reset;sdintr_msel_set:		/*		 * set more ERROR RECOVERY PARAMETERS		 */		if ((erp_page = sdi->max_ERP_page) == NULL)			goto check_target_status;		bzero((caddr_t)sc->sc_param, 4);		len = *(erp_page + 1) + 2;		bcopy(erp_page, &sc->sc_param[4], len);		im->im_tab.b_active = 2;		scop_mselect(intr, sc, slave, SCSI_INTEN,				(SDM_PF<<24) + len +4, (caddr_t)0);		return;sdintr_msel_reset:		if (sdc->sdc_firmware & SDCFW_DEFMODE)			goto sdintr_exec;		/*		 * set normal ERROR RECOVERY PARAMETERS		 */		erp_page = sdi->ERP_page;		bzero((caddr_t)sc->sc_param, 4);		len = *(erp_page + 1) + 2;		bcopy(erp_page, &sc->sc_param[4], len);		im->im_tab.b_active = 2;		scop_mselect(intr, sc, slave, SCSI_INTEN,				(SDM_PF<<24) + len +4, (caddr_t)0);		return;sdintr_error:		bp->b_flags |= B_ERROR;		if (sdc->sdc_state & SDCS_ECC) {			sdc->sdc_state = SDCS_NORMAL;			goto sdintr_msel_reset;		}		break;	/*	 * UNKNOWN STATUS	 */	default:		printf("sd%d: unknown status (0x%x)\n", unit, sdc->sdc_state);		goto sdintr_error;	}sdintr_done:	if (bp->b_flags & B_ERROR) {        printf("%s%d%c: hard error sn%d ", "sd",            minor(bp->b_dev) >> 3, 'a'+(minor(bp->b_dev)&07), bp->b_blkno);		printf("\n");	}	sdd->sdd_lastblk = dkblock(bp) + btodb(bp->b_bcount - bp->b_resid);	sdc->sdc_countcc = 0;	sdc->sdc_retrycnt = 0;	sdd->sdd_flags &= ~SDDF_VBADSECT;	if (im->im_tab.b_active) {		im->im_tab.b_active = 0;		im->im_tab.b_errcnt = 0;		im->im_tab.b_actf = 0;		dp->b_active = 0;		dp->b_errcnt = 0;		dp->b_actf = bp->b_actf;		if (bp == &csdbuf[unit]) {			register struct scsi *ksc = &kernscsi[unit];			/* copy result */			bcopy((caddr_t)sc, (caddr_t)ksc, sizeof(struct scsi));		}		iodone(bp);		/*		 * If this unit has more work to do,		 *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -