aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_ioctl.c')
-rw-r--r--drivers/scsi/scsi_ioctl.c64
1 files changed, 23 insertions, 41 deletions
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 7a6b530115ac..b7fddac81347 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -30,20 +30,20 @@
30 30
31#define MAX_BUF PAGE_SIZE 31#define MAX_BUF PAGE_SIZE
32 32
33/* 33/**
34 * If we are told to probe a host, we will return 0 if the host is not 34 * ioctl_probe -- return host identification
35 * present, 1 if the host is present, and will return an identifying 35 * @host: host to identify
36 * string at *arg, if arg is non null, filling to the length stored at 36 * @buffer: userspace buffer for identification
37 * (int *) arg 37 *
38 * Return an identifying string at @buffer, if @buffer is non-NULL, filling
39 * to the length stored at * (int *) @buffer.
38 */ 40 */
39
40static int ioctl_probe(struct Scsi_Host *host, void __user *buffer) 41static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
41{ 42{
42 unsigned int len, slen; 43 unsigned int len, slen;
43 const char *string; 44 const char *string;
44 int temp = host->hostt->present;
45 45
46 if (temp && buffer) { 46 if (buffer) {
47 if (get_user(len, (unsigned int __user *) buffer)) 47 if (get_user(len, (unsigned int __user *) buffer))
48 return -EFAULT; 48 return -EFAULT;
49 49
@@ -59,7 +59,7 @@ static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
59 return -EFAULT; 59 return -EFAULT;
60 } 60 }
61 } 61 }
62 return temp; 62 return 1;
63} 63}
64 64
65/* 65/*
@@ -88,25 +88,18 @@ static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
88static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, 88static 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;
94 93
95 SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd)); 94 SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));
96 95
97 sreq = scsi_allocate_request(sdev, GFP_KERNEL); 96 result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
98 if (!sreq) { 97 &sshdr, timeout, retries);
99 printk(KERN_WARNING "SCSI internal ioctl failed, no memory\n");
100 return -ENOMEM;
101 }
102
103 sreq->sr_data_direction = DMA_NONE;
104 scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);
105 98
106 SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", sreq->sr_result)); 99 SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", result));
107 100
108 if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) && 101 if ((driver_byte(result) & DRIVER_SENSE) &&
109 (scsi_request_normalize_sense(sreq, &sshdr))) { 102 (scsi_sense_valid(&sshdr))) {
110 switch (sshdr.sense_key) { 103 switch (sshdr.sense_key) {
111 case ILLEGAL_REQUEST: 104 case ILLEGAL_REQUEST:
112 if (cmd[0] == ALLOW_MEDIUM_REMOVAL) 105 if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
@@ -125,7 +118,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
125 case UNIT_ATTENTION: 118 case UNIT_ATTENTION:
126 if (sdev->removable) { 119 if (sdev->removable) {
127 sdev->changed = 1; 120 sdev->changed = 1;
128 sreq->sr_result = 0; /* This is no longer considered an error */ 121 result = 0; /* This is no longer considered an error */
129 break; 122 break;
130 } 123 }
131 default: /* Fall through for non-removable media */ 124 default: /* Fall through for non-removable media */
@@ -135,15 +128,13 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
135 sdev->channel, 128 sdev->channel,
136 sdev->id, 129 sdev->id,
137 sdev->lun, 130 sdev->lun,
138 sreq->sr_result); 131 result);
139 scsi_print_req_sense(" ", sreq); 132 scsi_print_sense_hdr(" ", &sshdr);
140 break; 133 break;
141 } 134 }
142 } 135 }
143 136
144 result = sreq->sr_result;
145 SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n")); 137 SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
146 scsi_release_request(sreq);
147 return result; 138 return result;
148} 139}
149 140
@@ -208,8 +199,8 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
208{ 199{
209 char *buf; 200 char *buf;
210 unsigned char cmd[MAX_COMMAND_SIZE]; 201 unsigned char cmd[MAX_COMMAND_SIZE];
202 unsigned char sense[SCSI_SENSE_BUFFERSIZE];
211 char __user *cmd_in; 203 char __user *cmd_in;
212 struct scsi_request *sreq;
213 unsigned char opcode; 204 unsigned char opcode;
214 unsigned int inlen, outlen, cmdlen; 205 unsigned int inlen, outlen, cmdlen;
215 unsigned int needed, buf_needed; 206 unsigned int needed, buf_needed;
@@ -321,31 +312,23 @@ int scsi_ioctl_send_command(struct scsi_device *sdev,
321 break; 312 break;
322 } 313 }
323 314
324 sreq = scsi_allocate_request(sdev, GFP_KERNEL); 315 result = scsi_execute(sdev, cmd, data_direction, buf, needed,
325 if (!sreq) { 316 sense, timeout, retries, 0);
326 result = -EINTR;
327 goto error;
328 }
329
330 sreq->sr_data_direction = data_direction;
331 scsi_wait_req(sreq, cmd, buf, needed, timeout, retries);
332 317
333 /* 318 /*
334 * If there was an error condition, pass the info back to the user. 319 * If there was an error condition, pass the info back to the user.
335 */ 320 */
336 result = sreq->sr_result;
337 if (result) { 321 if (result) {
338 int sb_len = sizeof(sreq->sr_sense_buffer); 322 int sb_len = sizeof(*sense);
339 323
340 sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len; 324 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)) 325 if (copy_to_user(cmd_in, sense, sb_len))
342 result = -EFAULT; 326 result = -EFAULT;
343 } else { 327 } else {
344 if (copy_to_user(cmd_in, buf, outlen)) 328 if (copy_to_user(cmd_in, buf, outlen))
345 result = -EFAULT; 329 result = -EFAULT;
346 } 330 }
347 331
348 scsi_release_request(sreq);
349error: 332error:
350 kfree(buf); 333 kfree(buf);
351 return result; 334 return result;
@@ -475,8 +458,7 @@ int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
475 * error processing, as long as the device was opened 458 * error processing, as long as the device was opened
476 * non-blocking */ 459 * non-blocking */
477 if (filp && filp->f_flags & O_NONBLOCK) { 460 if (filp && filp->f_flags & O_NONBLOCK) {
478 if (test_bit(SHOST_RECOVERY, 461 if (sdev->host->shost_state == SHOST_RECOVERY)
479 &sdev->host->shost_state))
480 return -ENODEV; 462 return -ENODEV;
481 } else if (!scsi_block_when_processing_errors(sdev)) 463 } else if (!scsi_block_when_processing_errors(sdev))
482 return -ENODEV; 464 return -ENODEV;