forked from mirrors/linux
		
	scsi: move scsi_dispatch_cmd to scsi_lib.c
scsi_lib.c is where the rest of the I/O submission path lives, so move scsi_dispatch_cmd there and mark it static. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Hannes Reinecke <hare@suse.de>
This commit is contained in:
		
							parent
							
								
									3c356bde19
								
							
						
					
					
						commit
						82042a2cdb
					
				
					 3 changed files with 81 additions and 82 deletions
				
			
		| 
						 | 
					@ -602,87 +602,6 @@ void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(scsi_cmd_get_serial);
 | 
					EXPORT_SYMBOL(scsi_cmd_get_serial);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * scsi_dispatch_command - Dispatch a command to the low-level driver.
 | 
					 | 
				
			||||||
 * @cmd: command block we are dispatching.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Return: nonzero return request was rejected and device's queue needs to be
 | 
					 | 
				
			||||||
 * plugged.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct Scsi_Host *host = cmd->device->host;
 | 
					 | 
				
			||||||
	int rtn = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	atomic_inc(&cmd->device->iorequest_cnt);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* check if the device is still usable */
 | 
					 | 
				
			||||||
	if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
 | 
					 | 
				
			||||||
		/* in SDEV_DEL we error all commands. DID_NO_CONNECT
 | 
					 | 
				
			||||||
		 * returns an immediate error upwards, and signals
 | 
					 | 
				
			||||||
		 * that the device is no longer present */
 | 
					 | 
				
			||||||
		cmd->result = DID_NO_CONNECT << 16;
 | 
					 | 
				
			||||||
		goto done;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Check to see if the scsi lld made this device blocked. */
 | 
					 | 
				
			||||||
	if (unlikely(scsi_device_blocked(cmd->device))) {
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * in blocked state, the command is just put back on
 | 
					 | 
				
			||||||
		 * the device queue.  The suspend state has already
 | 
					 | 
				
			||||||
		 * blocked the queue so future requests should not
 | 
					 | 
				
			||||||
		 * occur until the device transitions out of the
 | 
					 | 
				
			||||||
		 * suspend state.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
 | 
					 | 
				
			||||||
			"queuecommand : device blocked\n"));
 | 
					 | 
				
			||||||
		return SCSI_MLQUEUE_DEVICE_BUSY;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Store the LUN value in cmnd, if needed. */
 | 
					 | 
				
			||||||
	if (cmd->device->lun_in_cdb)
 | 
					 | 
				
			||||||
		cmd->cmnd[1] = (cmd->cmnd[1] & 0x1f) |
 | 
					 | 
				
			||||||
			       (cmd->device->lun << 5 & 0xe0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	scsi_log_send(cmd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Before we queue this command, check if the command
 | 
					 | 
				
			||||||
	 * length exceeds what the host adapter can handle.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (cmd->cmd_len > cmd->device->host->max_cmd_len) {
 | 
					 | 
				
			||||||
		SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
 | 
					 | 
				
			||||||
			       "queuecommand : command too long. "
 | 
					 | 
				
			||||||
			       "cdb_size=%d host->max_cmd_len=%d\n",
 | 
					 | 
				
			||||||
			       cmd->cmd_len, cmd->device->host->max_cmd_len));
 | 
					 | 
				
			||||||
		cmd->result = (DID_ABORT << 16);
 | 
					 | 
				
			||||||
		goto done;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (unlikely(host->shost_state == SHOST_DEL)) {
 | 
					 | 
				
			||||||
		cmd->result = (DID_NO_CONNECT << 16);
 | 
					 | 
				
			||||||
		goto done;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	trace_scsi_dispatch_cmd_start(cmd);
 | 
					 | 
				
			||||||
	rtn = host->hostt->queuecommand(host, cmd);
 | 
					 | 
				
			||||||
	if (rtn) {
 | 
					 | 
				
			||||||
		trace_scsi_dispatch_cmd_error(cmd, rtn);
 | 
					 | 
				
			||||||
		if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
 | 
					 | 
				
			||||||
		    rtn != SCSI_MLQUEUE_TARGET_BUSY)
 | 
					 | 
				
			||||||
			rtn = SCSI_MLQUEUE_HOST_BUSY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
 | 
					 | 
				
			||||||
			"queuecommand : request rejected\n"));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return rtn;
 | 
					 | 
				
			||||||
 done:
 | 
					 | 
				
			||||||
	cmd->scsi_done(cmd);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * scsi_finish_command - cleanup and pass command back to upper layer
 | 
					 * scsi_finish_command - cleanup and pass command back to upper layer
 | 
				
			||||||
 * @cmd: the command
 | 
					 * @cmd: the command
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1640,6 +1640,87 @@ static void scsi_softirq_done(struct request *rq)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * scsi_dispatch_command - Dispatch a command to the low-level driver.
 | 
				
			||||||
 | 
					 * @cmd: command block we are dispatching.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return: nonzero return request was rejected and device's queue needs to be
 | 
				
			||||||
 | 
					 * plugged.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct Scsi_Host *host = cmd->device->host;
 | 
				
			||||||
 | 
						int rtn = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						atomic_inc(&cmd->device->iorequest_cnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* check if the device is still usable */
 | 
				
			||||||
 | 
						if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
 | 
				
			||||||
 | 
							/* in SDEV_DEL we error all commands. DID_NO_CONNECT
 | 
				
			||||||
 | 
							 * returns an immediate error upwards, and signals
 | 
				
			||||||
 | 
							 * that the device is no longer present */
 | 
				
			||||||
 | 
							cmd->result = DID_NO_CONNECT << 16;
 | 
				
			||||||
 | 
							goto done;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Check to see if the scsi lld made this device blocked. */
 | 
				
			||||||
 | 
						if (unlikely(scsi_device_blocked(cmd->device))) {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * in blocked state, the command is just put back on
 | 
				
			||||||
 | 
							 * the device queue.  The suspend state has already
 | 
				
			||||||
 | 
							 * blocked the queue so future requests should not
 | 
				
			||||||
 | 
							 * occur until the device transitions out of the
 | 
				
			||||||
 | 
							 * suspend state.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
 | 
				
			||||||
 | 
								"queuecommand : device blocked\n"));
 | 
				
			||||||
 | 
							return SCSI_MLQUEUE_DEVICE_BUSY;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Store the LUN value in cmnd, if needed. */
 | 
				
			||||||
 | 
						if (cmd->device->lun_in_cdb)
 | 
				
			||||||
 | 
							cmd->cmnd[1] = (cmd->cmnd[1] & 0x1f) |
 | 
				
			||||||
 | 
								       (cmd->device->lun << 5 & 0xe0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scsi_log_send(cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Before we queue this command, check if the command
 | 
				
			||||||
 | 
						 * length exceeds what the host adapter can handle.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (cmd->cmd_len > cmd->device->host->max_cmd_len) {
 | 
				
			||||||
 | 
							SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
 | 
				
			||||||
 | 
								       "queuecommand : command too long. "
 | 
				
			||||||
 | 
								       "cdb_size=%d host->max_cmd_len=%d\n",
 | 
				
			||||||
 | 
								       cmd->cmd_len, cmd->device->host->max_cmd_len));
 | 
				
			||||||
 | 
							cmd->result = (DID_ABORT << 16);
 | 
				
			||||||
 | 
							goto done;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (unlikely(host->shost_state == SHOST_DEL)) {
 | 
				
			||||||
 | 
							cmd->result = (DID_NO_CONNECT << 16);
 | 
				
			||||||
 | 
							goto done;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						trace_scsi_dispatch_cmd_start(cmd);
 | 
				
			||||||
 | 
						rtn = host->hostt->queuecommand(host, cmd);
 | 
				
			||||||
 | 
						if (rtn) {
 | 
				
			||||||
 | 
							trace_scsi_dispatch_cmd_error(cmd, rtn);
 | 
				
			||||||
 | 
							if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
 | 
				
			||||||
 | 
							    rtn != SCSI_MLQUEUE_TARGET_BUSY)
 | 
				
			||||||
 | 
								rtn = SCSI_MLQUEUE_HOST_BUSY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
 | 
				
			||||||
 | 
								"queuecommand : request rejected\n"));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rtn;
 | 
				
			||||||
 | 
					 done:
 | 
				
			||||||
 | 
						cmd->scsi_done(cmd);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * scsi_done - Invoke completion on finished SCSI command.
 | 
					 * scsi_done - Invoke completion on finished SCSI command.
 | 
				
			||||||
 * @cmd: The SCSI Command for which a low-level device driver (LLDD) gives
 | 
					 * @cmd: The SCSI Command for which a low-level device driver (LLDD) gives
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,6 @@ extern int scsi_init_hosts(void);
 | 
				
			||||||
extern void scsi_exit_hosts(void);
 | 
					extern void scsi_exit_hosts(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* scsi.c */
 | 
					/* scsi.c */
 | 
				
			||||||
extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
 | 
					 | 
				
			||||||
extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
 | 
					extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
 | 
				
			||||||
extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
 | 
					extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
 | 
				
			||||||
#ifdef CONFIG_SCSI_LOGGING
 | 
					#ifdef CONFIG_SCSI_LOGGING
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue