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

📄 scsi_obsolete.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		return;	}	if (SCpnt->flags & WAS_SENSE) {		SCpnt->use_sg = SCpnt->old_use_sg;		SCpnt->cmd_len = SCpnt->old_cmd_len;		SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;		SCpnt->underflow = SCpnt->old_underflow;	}	switch (host_byte(result)) {	case DID_OK:		if (status_byte(result) && (SCpnt->flags & WAS_SENSE))			/* Failed to obtain sense information */		{			SCpnt->flags &= ~WAS_SENSE;#if 0				/* This cannot possibly be correct. */			SCpnt->internal_timeout &= ~SENSE_TIMEOUT;#endif			if (!(SCpnt->flags & WAS_RESET)) {				printk("scsi%d : channel %d target %d lun %d request sense"				       " failed, performing reset.\n",				       SCpnt->host->host_no, SCpnt->channel, SCpnt->target,				       SCpnt->lun);				scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS);				status = REDO;				break;			} else {				exit = (DRIVER_HARD | SUGGEST_ABORT);				status = CMD_FINISHED;			}		} else			switch (msg_byte(result)) {			case COMMAND_COMPLETE:				switch (status_byte(result)) {				case GOOD:					if (SCpnt->flags & WAS_SENSE) {#ifdef DEBUG						printk("In scsi_done, GOOD status, COMMAND COMPLETE, "						       "parsing sense information.\n");#endif						SCpnt->flags &= ~WAS_SENSE;#if 0				/* This cannot possibly be correct. */						SCpnt->internal_timeout &= ~SENSE_TIMEOUT;#endif						switch (checked = check_sense(SCpnt)) {						case SUGGEST_SENSE:						case 0:#ifdef DEBUG							printk("NO SENSE.  status = REDO\n");#endif							update_timeout(SCpnt, oldto);							status = REDO;							break;						case SUGGEST_IS_OK:							break;						case SUGGEST_REMAP:#ifdef DEBUG							printk("SENSE SUGGEST REMAP - status = CMD_FINISHED\n");#endif							status = CMD_FINISHED;							exit = DRIVER_SENSE | SUGGEST_ABORT;							break;						case SUGGEST_RETRY:#ifdef DEBUG							printk("SENSE SUGGEST RETRY - status = MAYREDO\n");#endif							status = MAYREDO;							exit = DRIVER_SENSE | SUGGEST_RETRY;							break;						case SUGGEST_ABORT:#ifdef DEBUG							printk("SENSE SUGGEST ABORT - status = CMD_FINISHED");#endif							status = CMD_FINISHED;							exit = DRIVER_SENSE | SUGGEST_ABORT;							break;						default:							printk("Internal error %s %d \n", __FILE__,							       __LINE__);						}					}					/* end WAS_SENSE */					else {#ifdef DEBUG						printk("COMMAND COMPLETE message returned, "						       "status = CMD_FINISHED. \n");#endif						exit = DRIVER_OK;						status = CMD_FINISHED;					}					break;				case CHECK_CONDITION:				case COMMAND_TERMINATED:					switch (check_sense(SCpnt)) {					case 0:						update_timeout(SCpnt, oldto);						status = REDO;						break;					case SUGGEST_REMAP:						status = CMD_FINISHED;						exit = DRIVER_SENSE | SUGGEST_ABORT;						break;					case SUGGEST_RETRY:						status = MAYREDO;						exit = DRIVER_SENSE | SUGGEST_RETRY;						break;					case SUGGEST_ABORT:						status = CMD_FINISHED;						exit = DRIVER_SENSE | SUGGEST_ABORT;						break;					case SUGGEST_SENSE:						scsi_request_sense(SCpnt);						status = PENDING;						break;					}					break;				case CONDITION_GOOD:				case INTERMEDIATE_GOOD:				case INTERMEDIATE_C_GOOD:					break;				case BUSY:				case QUEUE_FULL:					update_timeout(SCpnt, oldto);					status = REDO;					break;				case RESERVATION_CONFLICT:					printk("scsi%d, channel %d : RESERVATION CONFLICT performing"					       " reset.\n", SCpnt->host->host_no, SCpnt->channel);					scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS);					status = REDO;					break;				default:					printk("Internal error %s %d \n"					 "status byte = %d \n", __FILE__,					  __LINE__, status_byte(result));				}				break;			default:				panic("scsi: unsupported message byte %d received\n",				      msg_byte(result));			}		break;	case DID_TIME_OUT:#ifdef DEBUG		printk("Host returned DID_TIME_OUT - ");#endif		if (SCpnt->flags & WAS_TIMEDOUT) {#ifdef DEBUG			printk("Aborting\n");#endif			/*			   Allow TEST_UNIT_READY and INQUIRY commands to timeout early			   without causing resets.  All other commands should be retried.			 */			if (SCpnt->cmnd[0] != TEST_UNIT_READY &&			    SCpnt->cmnd[0] != INQUIRY)				status = MAYREDO;			exit = (DRIVER_TIMEOUT | SUGGEST_ABORT);		} else {#ifdef DEBUG			printk("Retrying.\n");#endif			SCpnt->flags |= WAS_TIMEDOUT;			SCpnt->internal_timeout &= ~IN_ABORT;			status = REDO;		}		break;	case DID_BUS_BUSY:	case DID_PARITY:		status = REDO;		break;	case DID_NO_CONNECT:#ifdef DEBUG		printk("Couldn't connect.\n");#endif		exit = (DRIVER_HARD | SUGGEST_ABORT);		break;	case DID_ERROR:		status = MAYREDO;		exit = (DRIVER_HARD | SUGGEST_ABORT);		break;	case DID_BAD_TARGET:	case DID_ABORT:		exit = (DRIVER_INVALID | SUGGEST_ABORT);		break;	case DID_RESET:		if (SCpnt->flags & IS_RESETTING) {			SCpnt->flags &= ~IS_RESETTING;			status = REDO;			break;		}		if (msg_byte(result) == GOOD &&		    status_byte(result) == CHECK_CONDITION) {			switch (check_sense(SCpnt)) {			case 0:				update_timeout(SCpnt, oldto);				status = REDO;				break;			case SUGGEST_REMAP:			case SUGGEST_RETRY:				status = MAYREDO;				exit = DRIVER_SENSE | SUGGEST_RETRY;				break;			case SUGGEST_ABORT:				status = CMD_FINISHED;				exit = DRIVER_SENSE | SUGGEST_ABORT;				break;			case SUGGEST_SENSE:				scsi_request_sense(SCpnt);				status = PENDING;				break;			}		} else {			status = REDO;			exit = SUGGEST_RETRY;		}		break;	default:		exit = (DRIVER_ERROR | SUGGEST_DIE);	}	switch (status) {	case CMD_FINISHED:	case PENDING:		break;	case MAYREDO:#ifdef DEBUG		printk("In MAYREDO, allowing %d retries, have %d\n",		       SCpnt->allowed, SCpnt->retries);#endif		if ((++SCpnt->retries) < SCpnt->allowed) {			if ((SCpnt->retries >= (SCpnt->allowed >> 1))			    && !(SCpnt->host->resetting && time_before(jiffies, SCpnt->host->last_reset + MIN_RESET_PERIOD))			    && !(SCpnt->flags & WAS_RESET)) {				printk("scsi%d channel %d : resetting for second half of retries.\n",				   SCpnt->host->host_no, SCpnt->channel);				scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS);				/* fall through to REDO */			}		} else {			status = CMD_FINISHED;			break;		}		/* fall through to REDO */	case REDO:		if (SCpnt->flags & WAS_SENSE)			scsi_request_sense(SCpnt);		else {			memcpy((void *) SCpnt->cmnd,			       (void *) SCpnt->data_cmnd,			       sizeof(SCpnt->data_cmnd));			memset((void *) SCpnt->sense_buffer, 0,			       sizeof(SCpnt->sense_buffer));			SCpnt->request_buffer = SCpnt->buffer;			SCpnt->request_bufflen = SCpnt->bufflen;			SCpnt->use_sg = SCpnt->old_use_sg;			SCpnt->cmd_len = SCpnt->old_cmd_len;			SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;			SCpnt->underflow = SCpnt->old_underflow;			SCpnt->result = 0;                        /*                         * Ugly, ugly.  The newer interfaces all                         * assume that the lock isn't held.  Mustn't                         * disappoint, or we deadlock the system.                           */                        spin_unlock_irq(&io_request_lock);			scsi_dispatch_cmd(SCpnt);                        spin_lock_irq(&io_request_lock);		}		break;	default:		INTERNAL_ERROR;	}	if (status == CMD_FINISHED) {		Scsi_Request *SRpnt;#ifdef DEBUG		printk("Calling done function - at address %p\n", SCpnt->done);#endif		host->host_busy--;	/* Indicate that we are free */                device->device_busy--;	/* Decrement device usage counter. */		SCpnt->result = result | ((exit & 0xff) << 24);		SCpnt->use_sg = SCpnt->old_use_sg;		SCpnt->cmd_len = SCpnt->old_cmd_len;		SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;		SCpnt->underflow = SCpnt->old_underflow;                /*                 * The upper layers assume the lock isn't held.  We mustn't                 * disappoint them.  When the new error handling code is in                 * use, the upper code is run from a bottom half handler, so                 * it isn't an issue.                 */                spin_unlock_irq(&io_request_lock);		SRpnt = SCpnt->sc_request;		if( SRpnt != NULL ) {			SRpnt->sr_result = SRpnt->sr_command->result;			if( SRpnt->sr_result != 0 ) {				memcpy(SRpnt->sr_sense_buffer,				       SRpnt->sr_command->sense_buffer,				       sizeof(SRpnt->sr_sense_buffer));			}		}		SCpnt->done(SCpnt);                spin_lock_irq(&io_request_lock);	}#undef CMD_FINISHED#undef REDO#undef MAYREDO#undef PENDING}/* * The scsi_abort function interfaces with the abort() function of the host * we are aborting, and causes the current command to not complete.  The * caller should deal with any error messages or status returned on the * next call. * * This will not be called reentrantly for a given host. *//* * Since we're nice guys and specified that abort() and reset() * can be non-reentrant.  The internal_timeout flags are used for * this. */static int scsi_abort(Scsi_Cmnd * SCpnt, int why){	int oldto;	struct Scsi_Host *host = SCpnt->host;	while (1) {		/*		 * Protect against races here.  If the command is done, or we are		 * on a different command forget it.		 */		if (SCpnt->serial_number != SCpnt->serial_number_at_timeout) {			return 0;		}		if (SCpnt->internal_timeout & IN_ABORT) {			spin_unlock_irq(&io_request_lock);			while (SCpnt->internal_timeout & IN_ABORT)				barrier();			spin_lock_irq(&io_request_lock);		} else {			SCpnt->internal_timeout |= IN_ABORT;			oldto = update_timeout(SCpnt, ABORT_TIMEOUT);			if ((SCpnt->flags & IS_RESETTING) && SCpnt->device->soft_reset) {				/* OK, this command must have died when we did the				 *  reset.  The device itself must have lied.				 */				printk("Stale command on %d %d:%d appears to have died when"				       " the bus was reset\n",				       SCpnt->channel, SCpnt->target, SCpnt->lun);			}			if (!host->host_busy) {				SCpnt->internal_timeout &= ~IN_ABORT;				update_timeout(SCpnt, oldto);				return 0;

⌨️ 快捷键说明

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