diff options
Diffstat (limited to 'drivers/scsi/scsi_ioctl.c')
-rw-r--r-- | drivers/scsi/scsi_ioctl.c | 46 |
1 files changed, 16 insertions, 30 deletions
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index f5bf5c07be91..5f399c9c68ee 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c | |||
@@ -88,25 +88,21 @@ static int ioctl_probe(struct Scsi_Host *host, void __user *buffer) | |||
88 | static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, | 88 | static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, |
89 | int timeout, int retries) | 89 | int timeout, int retries) |
90 | { | 90 | { |
91 | struct scsi_request *sreq; | ||
92 | int result; | 91 | int result; |
93 | struct scsi_sense_hdr sshdr; | 92 | struct scsi_sense_hdr sshdr; |
93 | char sense[SCSI_SENSE_BUFFERSIZE]; | ||
94 | 94 | ||
95 | SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd)); | 95 | SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd)); |
96 | 96 | ||
97 | sreq = scsi_allocate_request(sdev, GFP_KERNEL); | ||
98 | if (!sreq) { | ||
99 | printk(KERN_WARNING "SCSI internal ioctl failed, no memory\n"); | ||
100 | return -ENOMEM; | ||
101 | } | ||
102 | 97 | ||
103 | sreq->sr_data_direction = DMA_NONE; | 98 | memset(sense, 0, sizeof(*sense)); |
104 | scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries); | 99 | result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, |
100 | sense, timeout, retries); | ||
105 | 101 | ||
106 | SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", sreq->sr_result)); | 102 | SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", result)); |
107 | 103 | ||
108 | if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) && | 104 | if ((driver_byte(result) & DRIVER_SENSE) && |
109 | (scsi_request_normalize_sense(sreq, &sshdr))) { | 105 | (scsi_normalize_sense(sense, sizeof(*sense), &sshdr))) { |
110 | switch (sshdr.sense_key) { | 106 | switch (sshdr.sense_key) { |
111 | case ILLEGAL_REQUEST: | 107 | case ILLEGAL_REQUEST: |
112 | if (cmd[0] == ALLOW_MEDIUM_REMOVAL) | 108 | if (cmd[0] == ALLOW_MEDIUM_REMOVAL) |
@@ -125,7 +121,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, | |||
125 | case UNIT_ATTENTION: | 121 | case UNIT_ATTENTION: |
126 | if (sdev->removable) { | 122 | if (sdev->removable) { |
127 | sdev->changed = 1; | 123 | sdev->changed = 1; |
128 | sreq->sr_result = 0; /* This is no longer considered an error */ | 124 | result = 0; /* This is no longer considered an error */ |
129 | break; | 125 | break; |
130 | } | 126 | } |
131 | default: /* Fall through for non-removable media */ | 127 | default: /* Fall through for non-removable media */ |
@@ -135,15 +131,13 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, | |||
135 | sdev->channel, | 131 | sdev->channel, |
136 | sdev->id, | 132 | sdev->id, |
137 | sdev->lun, | 133 | sdev->lun, |
138 | sreq->sr_result); | 134 | result); |
139 | scsi_print_req_sense(" ", sreq); | 135 | __scsi_print_sense(" ", sense, sizeof(*sense)); |
140 | break; | 136 | break; |
141 | } | 137 | } |
142 | } | 138 | } |
143 | 139 | ||
144 | result = sreq->sr_result; | ||
145 | SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n")); | 140 | SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n")); |
146 | scsi_release_request(sreq); | ||
147 | return result; | 141 | return result; |
148 | } | 142 | } |
149 | 143 | ||
@@ -208,8 +202,8 @@ int scsi_ioctl_send_command(struct scsi_device *sdev, | |||
208 | { | 202 | { |
209 | char *buf; | 203 | char *buf; |
210 | unsigned char cmd[MAX_COMMAND_SIZE]; | 204 | unsigned char cmd[MAX_COMMAND_SIZE]; |
205 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; | ||
211 | char __user *cmd_in; | 206 | char __user *cmd_in; |
212 | struct scsi_request *sreq; | ||
213 | unsigned char opcode; | 207 | unsigned char opcode; |
214 | unsigned int inlen, outlen, cmdlen; | 208 | unsigned int inlen, outlen, cmdlen; |
215 | unsigned int needed, buf_needed; | 209 | unsigned int needed, buf_needed; |
@@ -321,31 +315,23 @@ int scsi_ioctl_send_command(struct scsi_device *sdev, | |||
321 | break; | 315 | break; |
322 | } | 316 | } |
323 | 317 | ||
324 | sreq = scsi_allocate_request(sdev, GFP_KERNEL); | 318 | result = scsi_execute_req(sdev, cmd, data_direction, buf, needed, |
325 | if (!sreq) { | 319 | sense, timeout, retries); |
326 | result = -EINTR; | 320 | |
327 | goto error; | ||
328 | } | ||
329 | |||
330 | sreq->sr_data_direction = data_direction; | ||
331 | scsi_wait_req(sreq, cmd, buf, needed, timeout, retries); | ||
332 | |||
333 | /* | 321 | /* |
334 | * If there was an error condition, pass the info back to the user. | 322 | * If there was an error condition, pass the info back to the user. |
335 | */ | 323 | */ |
336 | result = sreq->sr_result; | ||
337 | if (result) { | 324 | if (result) { |
338 | int sb_len = sizeof(sreq->sr_sense_buffer); | 325 | int sb_len = sizeof(*sense); |
339 | 326 | ||
340 | sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len; | 327 | sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len; |
341 | if (copy_to_user(cmd_in, sreq->sr_sense_buffer, sb_len)) | 328 | if (copy_to_user(cmd_in, sense, sb_len)) |
342 | result = -EFAULT; | 329 | result = -EFAULT; |
343 | } else { | 330 | } else { |
344 | if (copy_to_user(cmd_in, buf, outlen)) | 331 | if (copy_to_user(cmd_in, buf, outlen)) |
345 | result = -EFAULT; | 332 | result = -EFAULT; |
346 | } | 333 | } |
347 | 334 | ||
348 | scsi_release_request(sreq); | ||
349 | error: | 335 | error: |
350 | kfree(buf); | 336 | kfree(buf); |
351 | return result; | 337 | return result; |