diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-08 05:37:58 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-08 05:37:58 -0400 |
| commit | 5a2cec83a9bb1b4295aa8ab728fcb8ca1811a33c (patch) | |
| tree | 2f83dc6949763e77cf6422e696dc6146684dcf4e /drivers/scsi/scsi_ioctl.c | |
| parent | f2c853bca542f5ac0b036377637192a74f2091c2 (diff) | |
| parent | caf39e87cc1182f7dae84eefc43ca14d54c78ef9 (diff) | |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'drivers/scsi/scsi_ioctl.c')
| -rw-r--r-- | drivers/scsi/scsi_ioctl.c | 64 |
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 | |||
| 40 | static int ioctl_probe(struct Scsi_Host *host, void __user *buffer) | 41 | static 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) | |||
| 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; |
| 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); | ||
| 349 | error: | 332 | error: |
| 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; |
