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

📄 sf.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
}/* * This routine called to see whether unit is (still) there. Must not * be called when un->un_sbufp is in use, and must not be called with * an unattached disk. Soft state of disk is restored to what it was * upon entry- up to caller to set the correct state. * */static intsf_unit_ready(dev)dev_t dev;{	struct scsi_device *devp = sfunits[SFUNIT(dev)];	struct scsi_floppy *un = UPTR;	auto struct dk_cmd cblk, *com = &cblk;	u_char state;	un->un_last_state = un->un_state;	un->un_state = SF_STATE_OPENING;	com->dkc_cmd = SCMD_REZERO_UNIT;	com->dkc_flags = DK_SILENT;	com->dkc_blkno = 0;	com->dkc_secnt = 0;	com->dkc_bufaddr = 0;	com->dkc_buflen = 0;	if (sfioctl_cmd(dev,com)) {		state = un->un_state;		un->un_last_state = un->un_state;		un->un_state = state;		return (0);	}	state = un->un_state;	un->un_last_state = un->un_state;	un->un_state = state;	return (1);}static intsf_get_density(dev)dev_t dev;{	struct scsi_device *devp = sfunits[SFUNIT(dev)];	struct scsi_floppy *un = UPTR;	struct ccs_modesel_head *hp = (struct ccs_modesel_head *) un->un_mode;	auto struct dk_cmd cblk, *com = &cblk;	caddr_t dblk;	register int i, dens, rval = -1;	u_char state;	un->un_last_state = un->un_state;	un->un_state = SF_STATE_OPENING;	dblk = kmem_alloc((unsigned)SECSIZE);	if (dblk == 0) {		printf("%s%d: unable to alloc space\n",DNAME,DUNIT);		return (rval);	}	for (dens = 0; media_types[dens] != 0; dens++) {		if (sf_get_mode(dev,com) == 0) {			break;		}		if (dens == 0)			media_types[dens] = hp->medium;		hp->medium = media_types[dens];		DPRINTF_IOCTL("%s%d: trying to set density %x\n",DNAME,DUNIT,			hp->medium);		if (sf_set_shortmode(dev,com)) {			DPRINTF_IOCTL("%s%d: mode select fails; key %x\n",				DNAME,DUNIT,un->un_status);			continue;		}		com->dkc_cmd = SCMD_READ;		com->dkc_flags = DK_SILENT;		com->dkc_blkno = 0;		com->dkc_secnt = 1;		com->dkc_bufaddr = dblk;		com->dkc_buflen = SECSIZE | (1<<31);		if (sfioctl_cmd(dev,com) == 0) {			rval = 0;			DPRINTF_IOCTL("%s%d: test read succeeds; dens=%x\n",				DNAME,DUNIT,media_types[dens]&0xff);			break;					}		DPRINTF_IOCTL("%s%d: test read fails; key %x\n",DNAME,DUNIT,			un->un_status);	}	(void) kmem_free (dblk, (unsigned) SECSIZE);	state = un->un_state;	un->un_last_state = un->un_state;	un->un_state = state;	return (rval);}static intsf_get_mode(dev,com)dev_t dev;struct dk_cmd *com;{	struct scsi_device *devp = sfunits[SFUNIT(dev)];	struct scsi_floppy *un = UPTR;	com->dkc_cmd = SCMD_MODE_SENSE;	com->dkc_flags = DK_SILENT;	com->dkc_blkno = 0x5;	com->dkc_secnt = 0;	com->dkc_bufaddr = un->un_mode;	com->dkc_buflen = MSIZE | (1<<31);/* to avoid an as_fault */	bzero(un->un_mode,MSIZE);	if (sfioctl_cmd(dev,com)) {		return (0);	}	if (DEBUGGING_ALL) {		register i;		char *p = un->un_mode;		printf("mode sense data:\n");		for (i = 0; i < MSIZE; i++) {			printf(" 0x%x",p[i]&0xff);			if (((i+1)&0xf) == 0)				printf("\n");		}		printf("\n");	}	return (1);}static intsf_set_shortmode(dev,com)dev_t dev;struct dk_cmd *com;{	struct scsi_device *devp = sfunits[SFUNIT(dev)];	struct scsi_floppy *un = UPTR;	struct ccs_modesel_head *hp = (struct ccs_modesel_head *) un->un_mode;	hp->block_desc_length = 0;	com->dkc_cmd = SCMD_MODE_SELECT;	com->dkc_flags = DK_SILENT;	com->dkc_blkno = 0;	com->dkc_secnt = 0;	com->dkc_bufaddr = un->un_mode;	com->dkc_buflen =  4 | (1<<31);	if (sfioctl_cmd(dev,com)) {		return (0);	}	return (1);}static intsf_set_density(dev)dev_t dev;{	return (0);}/************************************************************************ ************************************************************************ *																		* *																		* *				Interrupt Service Routines								* *																		* *																		* ************************************************************************ ************************************************************************/staticsfrestart(arg)caddr_t arg;{		struct scsi_device *devp = (struct scsi_device *) arg;		struct buf *bp;		register s = splr(sfpri);		printf("sfrestart\n");		if ((bp = UPTR->un_utab.b_forw) == 0) {				printf("%s%d: busy restart aborted\n",DNAME,DUNIT);		} else {				struct scsi_pkt *pkt;				if (UPTR->un_state == SF_STATE_SENSING) {						pkt = UPTR->un_rqs;				} else {						pkt = BP_PKT(bp);				}				if (pkt_transport(pkt) == 0) {						printf("%s%d: restart transport failed\n",DNAME,DUNIT);						UPTR->un_state = UPTR->un_last_state;						bp->b_resid = bp->b_bcount;						bp->b_flags |= B_ERROR;						sfdone(devp);				}		}		(void) splx(s);}/* * Command completion processing * */static voidsfintr(pkt)struct scsi_pkt *pkt;{		register struct scsi_device *devp;		register struct scsi_floppy *un;		register struct buf *bp;		register action;		if (pkt->pkt_flags & FLAG_NOINTR) {				printf("sfintr:internal error - got a non-interrupting cmd\n");				return;		}		DPRINTF("sfintr:\n");		bp = (struct buf *) pkt->pkt_private;		ASSERT(bp != NULL);		devp = sfunits[SFUNIT(bp->b_dev)];		un = UPTR;		if(bp != un->un_utab.b_forw) {				printf("sfintr: buf not on queue?");				panic("sfintr1");		}		if (pkt->pkt_reason != CMD_CMPLT) {				action = sf_handle_incomplete(devp);		/*		 * At this point we know that the command was successfully		 * completed. Now what?		 */		} else if (un->un_state == SF_STATE_SENSING) {				/*				 * okay. We were running a REQUEST SENSE. Find				 * out what to do next.				 */				ASSERT(pkt == un->un_rqs);				un->un_state = un->un_last_state;				un->un_last_state = un->un_state;				pkt = BP_PKT(bp);				action = sf_handle_sense(devp);		/*		 * Okay, we weren't running a REQUEST SENSE. Call a routine		 * to see if the status bits we're okay. As a side effect,		 * clear state for this device, set non-error b_resid values, etc.		 * If a request sense is to be run, that will happen.		 */		} else {				action = sf_check_error(devp);		}		switch(action) {		case COMMAND_DONE_ERROR:				un->un_err_severe = DK_FATAL;				un->un_err_resid = bp->b_resid = bp->b_bcount;				bp->b_flags |= B_ERROR;				/* FALL THRU */		case COMMAND_DONE:				sfdone(devp);				break;		case QUE_SENSE:				un->un_last_state = un->un_last_state;				un->un_state = SF_STATE_SENSING;				un->un_rqs->pkt_private = (opaque_t) bp;				bzero((caddr_t)devp->sd_sense,SENSE_LENGTH);				if (pkt_transport(un->un_rqs) == 0) {						panic("sfintr: transport of request sense fails");						/*NOTREACHED*/				}				break;		case QUE_COMMAND:				if (pkt_transport(BP_PKT(bp)) == 0) {						printf("sfintr: requeue of command fails\n");						un->un_err_resid = bp->b_resid = bp->b_bcount;								bp->b_flags |= B_ERROR;						sfdone(devp);				}				break;		case JUST_RETURN:				break;		}}static intsf_handle_incomplete(devp)struct scsi_device *devp;{		static char *notresp = "%s%d: disk not responding to selection\n";		register rval = COMMAND_DONE_ERROR;		struct scsi_floppy *un = UPTR;		struct buf *bp = un->un_utab.b_forw;		struct scsi_pkt *pkt = (un->un_state == SF_STATE_SENSING)?				un->un_rqs : BP_PKT(bp);		if (pkt == un->un_rqs) {				un->un_state = un->un_last_state;				un->un_last_state = SF_STATE_SENSING;				if (un->un_retry_ct++ < SF_RETRY_COUNT)						rval = QUE_SENSE;		} else if (bp == un->un_sbufp && (un->un_soptions & DK_ISOLATE)) {				rval = COMMAND_DONE_ERROR;		} else if (un->un_retry_ct++ < SF_RETRY_COUNT) {				rval = QUE_COMMAND;		}		if (pkt->pkt_state == STATE_GOT_BUS && rval == COMMAND_DONE_ERROR) {				/*				 * Looks like someone turned off this shoebox.				 */				printf(notresp,DNAME,DUNIT);				un->un_last_state = un->un_state;				un->un_state = SF_STATE_DETACHING;		} else if (bp != un->un_sbufp || (un->un_soptions & DK_SILENT) == 0) {				printf("%s%d: command transport failed: reason '%s': %s\n",						DNAME,DUNIT,scsi_rname(pkt->pkt_reason),						(rval == COMMAND_DONE_ERROR)?"giving up":"retrying");		}		return rval;}static intsf_handle_sense(devp)register struct scsi_device *devp;{		register struct scsi_floppy *un = UPTR;		register struct buf *bp = un->un_utab.b_forw;		struct scsi_pkt *pkt = BP_PKT(bp), *rqpkt = un->un_rqs;		register rval = COMMAND_DONE_ERROR;		int severity, amt, i;		char *p;		static char *hex =" 0x%x";		if (SCBP(rqpkt)->sts_busy) {				printf ("%s%d: busy unit on request sense\n",DNAME,DUNIT);				if (un->un_retry_ct++ < SF_RETRY_COUNT) {						timeout (sfrestart, (caddr_t)devp, SFTIMEOUT);						rval = JUST_RETURN;				}				return(rval);		}		if (SCBP(rqpkt)->sts_chk) {				printf ("%s%d: Check Condition on REQUEST SENSE\n",DNAME,DUNIT);				return (rval);		}		amt = SENSE_LENGTH - rqpkt->pkt_resid;		if ((rqpkt->pkt_state&STATE_XFERRED_DATA) == 0 || amt == 0) {				printf("%s%d: Request Sense couldn't get sense data\n",DNAME,						DUNIT);				return (rval);		}		/*		 * Now, check to see whether we got enough sense data to make any		 * sense out if it (heh-heh).		 */		if (amt < sizeof (struct scsi_extended_sense)) {				if (amt < sizeof (struct scsi_sense)) {						printf("%s%d: couldn't get enough sense information\n",								DNAME,DUNIT);						return (rval);				}				if (devp->sd_sense->es_class != CLASS_EXTENDED_SENSE) {						p = (char *) devp->sd_sense;						printf("%s%d: undecoded sense information:");						for (i = 0; i < amt; i++) {								printf(hex,*(p++)&0xff);						}						printf("; assuming a fatal error\n");						return (rval);				}		}		un->un_status = devp->sd_sense->es_key;		un->un_err_code = devp->sd_sense->es_code;		if (devp->sd_sense->es_valid) {				un->un_err_blkno =		(devp->sd_sense->es_info_1 << 24) |										(devp->sd_sense->es_info_2 << 16) |										(devp->sd_sense->es_info_3 << 8)  |										(devp->sd_sense->es_info_4);		} else {				un->un_err_blkno = bp->b_blkno;		}		if (DEBUGGING_ALL || sf_error_reporting == SDERR_ALL) {				p = (char *) devp->sd_sense;				printf("%s%d:sdata:",DNAME,DUNIT);				for (i = 0; i < amt; i++) {						printf(hex,*(p++)&0xff);				}				printf("\n      cmd:");				p = pkt->pkt_cdbp;				for (i = 0; i < CDB_SIZE; i++)						printf(hex,*(p++)&0xff);				printf("\n");		}		switch (un->un_status) {		case KEY_NO_SENSE:				un->un_err_severe = DK_NOERROR;				severity = SDERR_RETRYABLE;				rval = SDERR_INFORMATIONAL;				break;		case KEY_RECOVERABLE_ERROR:				bp->b_resid = pkt->pkt_resid;				un->un_err_severe = DK_CORRECTED;				un->un_retry_ct = 0;				severity = SDERR_RECOVERED;				rval = COMMAND_DONE;				break;		case KEY_NOT_READY:		case KEY_MEDIUM_ERROR:		case KEY_HARDWARE_ERROR:		case KEY_ILLEGAL_REQUEST:		case KEY_VOLUME_OVERFLOW:		case KEY_WRITE_PROTECT:		case KEY_BLANK_CHECK:				un->un_err_severe = DK_FATAL;				severity = SDERR_FATAL;				rval = COMMAND_DONE_ERROR;				break;		case KEY_ABORTED_COMMAND:				severity = SDERR_RETRYABLE;				rval = QUE_COMMAND;				break;		case KEY_UNIT_ATTENTION:		{				bp->b_resid = pkt->pkt_resid;				un->un_err_severe = DK_NOERROR;				un->un_retry_ct = 0;				severity = SDERR_INFORMATIONAL;				rval = QUE_COMMAND;				break;		}		default:				/*				 * Undecoded sense key.  Try retries and hope				 * that will fix the problem.  Otherwise, we're				 * dead.				 */				printf("%s%d: Sense Key '%s'\n",DNAME,DUNIT,						sense_keys[un->un_status]);				if (un->un_retry_ct++ < SF_RETRY_COUNT) {						un->un_err_severe = DK_RECOVERED;						severity = SDERR_RETRYABLE;						rval = QUE_COMMAND;				} else {						un->un_err_severe = DK_FATAL;						severity = SDERR_FATAL;						rval = COMMAND_DONE_ERROR;				}		}		if (rval == QUE_COMMAND && bp == un->un_sbufp &&						(un->un_soptions & DK_DIAGNOSE) == 0) {				un->un_err_severe = DK_FATAL;				rval = COMMAND_DONE_ERROR;		}		if (bp == un->un_sbufp) {				if ((un->un_soptions & DK_SILENT) == 0) {						sferrmsg(devp,severity);				}		} else if (DEBUGGING_ALL || severity >= sf_error_reporting) {				sferrmsg(devp,severity);		}		return (rval);}static intsf_check_error(devp)register struct scsi_device *devp;{		register struct scsi_floppy *un = UPTR;		struct buf *bp = un->un_utab.b_forw;		register struct scsi_pkt *pkt = BP_PKT(bp);		register action;		if (SCBP(pkt)->sts_busy) {				printf("%s%d: unit busy\n",DNAME,DUNIT);				if (un->un_retry_ct++ < SF_RETRY_COUNT) {						timeout(sfrestart,(caddr_t)devp,SFTIMEOUT);						action = JUST_RETURN;				} else {						printf("%s%d: device busy too long\n",DNAME,DUNIT);						action = COMMAND_DONE_ERROR;				}		} else if (SCBP(pkt)->sts_chk) {				DPRINTF("%s%d: check condition\n",DNAME,DUNIT);				action = QUE_SENSE;		} else {				/*				 * pkt_resid will reflect, at this point, a residual				 * of how many bytes left to be transferred there were				 *				 */				bp->b_resid = pkt->pkt_resid;				action = COMMAND_DONE;				un->un_err_severe = DK_NOERROR;				un->un_retry_ct = 0;		}		return (action);}/************************************************************************ ************************************************************************ *																		* *																		* *				Error Printing												* *																		* *																		* ************************************************************************ ************************************************************************/static char *sf_cmds[] = {		"\000test unit ready",				/* 0x00 */		"\001rezero",						/* 0x01 */		"\003request sense",				/* 0x03 */		"\004format",						/* 0x04 */		"\007reassign",						/* 0x07 */		"\010read",						/* 0x08 */		"\012write",						/* 0x0a */		"\013seek",						/* 0x0b */		"\022inquiry",						/* 0x12 */		"\025mode select",				/* 0x15 */		"\026reserve",						/* 0x16 */		"\027release",						/* 0x17 */		"\030copy",						/* 0x18 */		"\032mode sense",				/* 0x1a */		"\033start/stop",				/* 0x1b */		"\036door lock",				/* 0x1e */		"\067read defect data",				/* 0x37 */		NULL};static voidsferrmsg(devp, level)register struct scsi_device *devp;int level;{		static char *error_classes[] = {				"All          ", "Unknown      ", "Informational",				"Recovered    ", "Retryable    ", "Fatal        "		};		char *class;		struct scsi_pkt *pkt;		class = error_classes[level];		pkt = BP_PKT(UPTR->un_utab.b_forw);		printf("%s%d:\tError for command '%s'\n",DNAME,DUNIT,				scsi_cmd_decode(CDBP(pkt)->scc_cmd,sf_cmds));		printf("    \tError Level: %s Block: %d\n",class,UPTR->un_err_blkno);		printf("    \tSense Key:   %s\n",sense_keys[devp->sd_sense->es_key]);		if (devp->sd_sense->es_code) {				printf("    \tVendor Unique Error Code: %x",						devp->sd_sense->es_code);		}		printf("\n");}#endif		NSF > 0

⌨️ 快捷键说明

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