Commit 1cf72699 authored by James Bottomley's avatar James Bottomley
Browse files

[SCSI] convert the remaining mid-layer pieces to scsi_execute_req



After this, we just have some drivers, all the ULDs and the SPI
transport class using scsi_wait_req().

Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 7a93aef7
Loading
Loading
Loading
Loading
+16 −30
Original line number Diff line number Diff line
@@ -88,25 +88,21 @@ static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
				  int timeout, int retries)
{
	struct scsi_request *sreq;
	int result;
	struct scsi_sense_hdr sshdr;
	char sense[SCSI_SENSE_BUFFERSIZE];

	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));

	sreq = scsi_allocate_request(sdev, GFP_KERNEL);
	if (!sreq) {
		printk(KERN_WARNING "SCSI internal ioctl failed, no memory\n");
		return -ENOMEM;
	}

	sreq->sr_data_direction = DMA_NONE;
        scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);
	memset(sense, 0, sizeof(*sense));
	result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
				  sense, timeout, retries);

	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", sreq->sr_result));
	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", result));

	if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
	    (scsi_request_normalize_sense(sreq, &sshdr))) {
	if ((driver_byte(result) & DRIVER_SENSE) &&
	    (scsi_normalize_sense(sense, sizeof(*sense), &sshdr))) {
		switch (sshdr.sense_key) {
		case ILLEGAL_REQUEST:
			if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
@@ -125,7 +121,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
		case UNIT_ATTENTION:
			if (sdev->removable) {
				sdev->changed = 1;
				sreq->sr_result = 0;	/* This is no longer considered an error */
				result = 0;	/* This is no longer considered an error */
				break;
			}
		default:	/* Fall through for non-removable media */
@@ -135,15 +131,13 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
			       sdev->channel,
			       sdev->id,
			       sdev->lun,
			       sreq->sr_result);
			scsi_print_req_sense("   ", sreq);
			       result);
			__scsi_print_sense("   ", sense, sizeof(*sense));
			break;
		}
	}

	result = sreq->sr_result;
	SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
	scsi_release_request(sreq);
	return result;
}

@@ -208,8 +202,8 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
{
	char *buf;
	unsigned char cmd[MAX_COMMAND_SIZE];
	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
	char __user *cmd_in;
	struct scsi_request *sreq;
	unsigned char opcode;
	unsigned int inlen, outlen, cmdlen;
	unsigned int needed, buf_needed;
@@ -321,31 +315,23 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
		break;
	}

	sreq = scsi_allocate_request(sdev, GFP_KERNEL);
        if (!sreq) {
                result = -EINTR;
                goto error;
        }

	sreq->sr_data_direction = data_direction;
        scsi_wait_req(sreq, cmd, buf, needed, timeout, retries);
	result = scsi_execute_req(sdev, cmd, data_direction, buf, needed,
				  sense, timeout, retries);
				  
	/* 
	 * If there was an error condition, pass the info back to the user. 
	 */
	result = sreq->sr_result;
	if (result) {
		int sb_len = sizeof(sreq->sr_sense_buffer);
		int sb_len = sizeof(*sense);

		sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len;
		if (copy_to_user(cmd_in, sreq->sr_sense_buffer, sb_len))
		if (copy_to_user(cmd_in, sense, sb_len))
			result = -EFAULT;
	} else {
		if (copy_to_user(cmd_in, buf, outlen))
			result = -EFAULT;
	}	

	scsi_release_request(sreq);
error:
	kfree(buf);
	return result;
+33 −61
Original line number Diff line number Diff line
@@ -1615,7 +1615,7 @@ void scsi_exit_queue(void)
/**
 *	__scsi_mode_sense - issue a mode sense, falling back from 10 to 
 *		six bytes if necessary.
 *	@sreq:	SCSI request to fill in with the MODE_SENSE
 *	@sdev:	SCSI device to be queried
 *	@dbd:	set if mode sense will allow block descriptors to be returned
 *	@modepage: mode page being requested
 *	@buffer: request buffer (may not be smaller than eight bytes)
@@ -1623,26 +1623,38 @@ void scsi_exit_queue(void)
 *	@timeout: command timeout
 *	@retries: number of retries before failing
 *	@data: returns a structure abstracting the mode header data
 *	@sense: place to put sense data (or NULL if no sense to be collected).
 *		must be SCSI_SENSE_BUFFERSIZE big.
 *
 *	Returns zero if unsuccessful, or the header offset (either 4
 *	or 8 depending on whether a six or ten byte command was
 *	issued) if successful.
 **/
int
__scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage,
scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
		  unsigned char *buffer, int len, int timeout, int retries,
		  struct scsi_mode_data *data) {
		  struct scsi_mode_data *data, char *sense) {
	unsigned char cmd[12];
	int use_10_for_ms;
	int header_length;
	int result;
	char *sense_buffer = NULL;

	memset(data, 0, sizeof(*data));
	memset(&cmd[0], 0, 12);
	cmd[1] = dbd & 0x18;	/* allows DBD and LLBA bits */
	cmd[2] = modepage;

	if (!sense) {
		sense_buffer = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
		if (!sense_buffer) {
			dev_printk(KERN_ERR, &sdev->sdev_gendev, "failed to allocate sense buffer\n");
			return 0;
		}
		sense = sense_buffer;
	}
 retry:
	use_10_for_ms = sreq->sr_device->use_10_for_ms;
	use_10_for_ms = sdev->use_10_for_ms;

	if (use_10_for_ms) {
		if (len < 8)
@@ -1660,36 +1672,35 @@ __scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage,
		header_length = 4;
	}

	sreq->sr_cmd_len = 0;
	memset(sreq->sr_sense_buffer, 0, sizeof(sreq->sr_sense_buffer));
	sreq->sr_data_direction = DMA_FROM_DEVICE;
	memset(sense, 0, SCSI_SENSE_BUFFERSIZE);

	memset(buffer, 0, len);

	scsi_wait_req(sreq, cmd, buffer, len, timeout, retries);
	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
				  sense, timeout, retries);

	/* This code looks awful: what it's doing is making sure an
	 * ILLEGAL REQUEST sense return identifies the actual command
	 * byte as the problem.  MODE_SENSE commands can return
	 * ILLEGAL REQUEST if the code page isn't supported */

	if (use_10_for_ms && !scsi_status_is_good(sreq->sr_result) &&
	    (driver_byte(sreq->sr_result) & DRIVER_SENSE)) {
	if (use_10_for_ms && !scsi_status_is_good(result) &&
	    (driver_byte(result) & DRIVER_SENSE)) {
		struct scsi_sense_hdr sshdr;

		if (scsi_request_normalize_sense(sreq, &sshdr)) {
		if (scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) {
			if ((sshdr.sense_key == ILLEGAL_REQUEST) &&
			    (sshdr.asc == 0x20) && (sshdr.ascq == 0)) {
				/* 
				 * Invalid command operation code
				 */
				sreq->sr_device->use_10_for_ms = 0;
				sdev->use_10_for_ms = 0;
				goto retry;
			}
		}
	}

	if(scsi_status_is_good(sreq->sr_result)) {
	if(scsi_status_is_good(result)) {
		data->header_length = header_length;
		if(use_10_for_ms) {
			data->length = buffer[0]*256 + buffer[1] + 2;
@@ -1706,73 +1717,34 @@ __scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage,
		}
	}

	return sreq->sr_result;
}
EXPORT_SYMBOL(__scsi_mode_sense);

/**
 *	scsi_mode_sense - issue a mode sense, falling back from 10 to 
 *		six bytes if necessary.
 *	@sdev:	scsi device to send command to.
 *	@dbd:	set if mode sense will disable block descriptors in the return
 *	@modepage: mode page being requested
 *	@buffer: request buffer (may not be smaller than eight bytes)
 *	@len:	length of request buffer.
 *	@timeout: command timeout
 *	@retries: number of retries before failing
 *
 *	Returns zero if unsuccessful, or the header offset (either 4
 *	or 8 depending on whether a six or ten byte command was
 *	issued) if successful.
 **/
int
scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
		unsigned char *buffer, int len, int timeout, int retries,
		struct scsi_mode_data *data)
{
	struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL);
	int ret;

	if (!sreq)
		return -1;

	ret = __scsi_mode_sense(sreq, dbd, modepage, buffer, len,
				timeout, retries, data);

	scsi_release_request(sreq);

	return ret;
	kfree(sense_buffer);
	return result;
}
EXPORT_SYMBOL(scsi_mode_sense);

int
scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries)
{
	struct scsi_request *sreq;
	char cmd[] = {
		TEST_UNIT_READY, 0, 0, 0, 0, 0,
	};
	char sense[SCSI_SENSE_BUFFERSIZE];
	int result;
	
	sreq = scsi_allocate_request(sdev, GFP_KERNEL);
	if (!sreq)
		return -ENOMEM;
	result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sense,
				  timeout, retries);

	sreq->sr_data_direction = DMA_NONE;
	scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);

	if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) && sdev->removable) {
	if ((driver_byte(result) & DRIVER_SENSE) && sdev->removable) {
		struct scsi_sense_hdr sshdr;

		if ((scsi_request_normalize_sense(sreq, &sshdr)) &&
		if ((scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE,
					  &sshdr)) &&
		    ((sshdr.sense_key == UNIT_ATTENTION) ||
		     (sshdr.sense_key == NOT_READY))) {
			sdev->changed = 1;
			sreq->sr_result = 0;
			result = 0;
		}
	}
	result = sreq->sr_result;
	scsi_release_request(sreq);
	return result;
}
EXPORT_SYMBOL(scsi_test_unit_ready);
+3 −2
Original line number Diff line number Diff line
@@ -1299,8 +1299,9 @@ static inline int
sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage,
		 unsigned char *buffer, int len, struct scsi_mode_data *data)
{
	return __scsi_mode_sense(SRpnt, dbd, modepage, buffer, len,
				 SD_TIMEOUT, SD_MAX_RETRIES, data);
	return scsi_mode_sense(SRpnt->sr_device, dbd, modepage, buffer, len,
			       SD_TIMEOUT, SD_MAX_RETRIES, data,
			       SRpnt->sr_sense_buffer);
}

/*
+1 −1
Original line number Diff line number Diff line
@@ -817,7 +817,7 @@ static void get_capabilities(struct scsi_cd *cd)

	/* ask for mode page 0x2a */
	rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
			     SR_TIMEOUT, 3, &data);
			     SR_TIMEOUT, 3, &data, NULL);

	if (!scsi_status_is_good(rc)) {
		/* failed, drive doesn't have capabilities mode page */
+11 −2
Original line number Diff line number Diff line
@@ -8,9 +8,17 @@

struct request_queue;
struct scsi_cmnd;
struct scsi_mode_data;
struct scsi_lun;

struct scsi_mode_data {
	__u32	length;
	__u16	block_descriptor_length;
	__u8	medium_type;
	__u8	device_specific;
	__u8	header_length;
	__u8	longlba:1;
};

/*
 * sdev state: If you alter this, you also need to alter scsi_sysfs.c
 * (for the ascii descriptions) and the state model enforcer:
@@ -228,7 +236,8 @@ extern int scsi_set_medium_removal(struct scsi_device *, char);

extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
			   unsigned char *buffer, int len, int timeout,
			   int retries, struct scsi_mode_data *data);
			   int retries, struct scsi_mode_data *data,
			   char *sense);
extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout,
				int retries);
extern int scsi_device_set_state(struct scsi_device *sdev,
Loading