aboutsummaryrefslogtreecommitdiffstats
path: root/block/scsi_ioctl.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2006-03-22 11:52:04 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-04-13 11:13:15 -0400
commit21b2f0c803adaf00fce1b606c50b49ae8b106773 (patch)
tree1acc834df309041ed0c5681f4bd222fd3e113900 /block/scsi_ioctl.c
parent765fcab23d0a79ed7aab8da79766f5873d936f1b (diff)
[SCSI] unify SCSI_IOCTL_SEND_COMMAND implementations
We currently have two implementations of this obsolete ioctl, one in the block layer and one in the scsi code. Both of them have drawbacks. This patch kills the scsi layer version after updating the block version with the missing bits: - argument checking - use scatterlist I/O - set number of retries based on the submitted command This is the last user of non-S/G I/O except for the gdth driver, so getting this in ASAP and through the scsi tree would be nie to kill the non-S/G I/O path. Jens, what do you think about adding a check for non-S/G I/O in the midlayer? Thanks to Or Gerlitz for testing this patch. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'block/scsi_ioctl.c')
-rw-r--r--block/scsi_ioctl.c101
1 files changed, 72 insertions, 29 deletions
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 24f7af9d0abc..b33eda26e205 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -350,16 +350,51 @@ out:
350 return ret; 350 return ret;
351} 351}
352 352
353/**
354 * sg_scsi_ioctl -- handle deprecated SCSI_IOCTL_SEND_COMMAND ioctl
355 * @file: file this ioctl operates on (optional)
356 * @q: request queue to send scsi commands down
357 * @disk: gendisk to operate on (option)
358 * @sic: userspace structure describing the command to perform
359 *
360 * Send down the scsi command described by @sic to the device below
361 * the request queue @q. If @file is non-NULL it's used to perform
362 * fine-grained permission checks that allow users to send down
363 * non-destructive SCSI commands. If the caller has a struct gendisk
364 * available it should be passed in as @disk to allow the low level
365 * driver to use the information contained in it. A non-NULL @disk
366 * is only allowed if the caller knows that the low level driver doesn't
367 * need it (e.g. in the scsi subsystem).
368 *
369 * Notes:
370 * - This interface is deprecated - users should use the SG_IO
371 * interface instead, as this is a more flexible approach to
372 * performing SCSI commands on a device.
373 * - The SCSI command length is determined by examining the 1st byte
374 * of the given command. There is no way to override this.
375 * - Data transfers are limited to PAGE_SIZE
376 * - The length (x + y) must be at least OMAX_SB_LEN bytes long to
377 * accommodate the sense buffer when an error occurs.
378 * The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that
379 * old code will not be surprised.
380 * - If a Unix error occurs (e.g. ENOMEM) then the user will receive
381 * a negative return and the Unix error code in 'errno'.
382 * If the SCSI command succeeds then 0 is returned.
383 * Positive numbers returned are the compacted SCSI error codes (4
384 * bytes in one int) where the lowest byte is the SCSI status.
385 */
353#define OMAX_SB_LEN 16 /* For backward compatibility */ 386#define OMAX_SB_LEN 16 /* For backward compatibility */
354 387int sg_scsi_ioctl(struct file *file, struct request_queue *q,
355static int sg_scsi_ioctl(struct file *file, request_queue_t *q, 388 struct gendisk *disk, struct scsi_ioctl_command __user *sic)
356 struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic)
357{ 389{
358 struct request *rq; 390 struct request *rq;
359 int err; 391 int err;
360 unsigned int in_len, out_len, bytes, opcode, cmdlen; 392 unsigned int in_len, out_len, bytes, opcode, cmdlen;
361 char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE]; 393 char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
362 394
395 if (!sic)
396 return -EINVAL;
397
363 /* 398 /*
364 * get in an out lengths, verify they don't exceed a page worth of data 399 * get in an out lengths, verify they don't exceed a page worth of data
365 */ 400 */
@@ -393,45 +428,53 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
393 if (copy_from_user(rq->cmd, sic->data, cmdlen)) 428 if (copy_from_user(rq->cmd, sic->data, cmdlen))
394 goto error; 429 goto error;
395 430
396 if (copy_from_user(buffer, sic->data + cmdlen, in_len)) 431 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
397 goto error; 432 goto error;
398 433
399 err = verify_command(file, rq->cmd); 434 err = verify_command(file, rq->cmd);
400 if (err) 435 if (err)
401 goto error; 436 goto error;
402 437
438 /* default. possible overriden later */
439 rq->retries = 5;
440
403 switch (opcode) { 441 switch (opcode) {
404 case SEND_DIAGNOSTIC: 442 case SEND_DIAGNOSTIC:
405 case FORMAT_UNIT: 443 case FORMAT_UNIT:
406 rq->timeout = FORMAT_UNIT_TIMEOUT; 444 rq->timeout = FORMAT_UNIT_TIMEOUT;
407 break; 445 rq->retries = 1;
408 case START_STOP: 446 break;
409 rq->timeout = START_STOP_TIMEOUT; 447 case START_STOP:
410 break; 448 rq->timeout = START_STOP_TIMEOUT;
411 case MOVE_MEDIUM: 449 break;
412 rq->timeout = MOVE_MEDIUM_TIMEOUT; 450 case MOVE_MEDIUM:
413 break; 451 rq->timeout = MOVE_MEDIUM_TIMEOUT;
414 case READ_ELEMENT_STATUS: 452 break;
415 rq->timeout = READ_ELEMENT_STATUS_TIMEOUT; 453 case READ_ELEMENT_STATUS:
416 break; 454 rq->timeout = READ_ELEMENT_STATUS_TIMEOUT;
417 case READ_DEFECT_DATA: 455 break;
418 rq->timeout = READ_DEFECT_DATA_TIMEOUT; 456 case READ_DEFECT_DATA:
419 break; 457 rq->timeout = READ_DEFECT_DATA_TIMEOUT;
420 default: 458 rq->retries = 1;
421 rq->timeout = BLK_DEFAULT_TIMEOUT; 459 break;
422 break; 460 default:
461 rq->timeout = BLK_DEFAULT_TIMEOUT;
462 break;
463 }
464
465 if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, __GFP_WAIT)) {
466 err = DRIVER_ERROR << 24;
467 goto out;
423 } 468 }
424 469
425 memset(sense, 0, sizeof(sense)); 470 memset(sense, 0, sizeof(sense));
426 rq->sense = sense; 471 rq->sense = sense;
427 rq->sense_len = 0; 472 rq->sense_len = 0;
428
429 rq->data = buffer;
430 rq->data_len = bytes;
431 rq->flags |= REQ_BLOCK_PC; 473 rq->flags |= REQ_BLOCK_PC;
432 rq->retries = 0;
433 474
434 blk_execute_rq(q, bd_disk, rq, 0); 475 blk_execute_rq(q, disk, rq, 0);
476
477out:
435 err = rq->errors & 0xff; /* only 8 bit SCSI status */ 478 err = rq->errors & 0xff; /* only 8 bit SCSI status */
436 if (err) { 479 if (err) {
437 if (rq->sense_len && rq->sense) { 480 if (rq->sense_len && rq->sense) {
@@ -450,7 +493,7 @@ error:
450 blk_put_request(rq); 493 blk_put_request(rq);
451 return err; 494 return err;
452} 495}
453 496EXPORT_SYMBOL_GPL(sg_scsi_ioctl);
454 497
455/* Send basic block requests */ 498/* Send basic block requests */
456static int __blk_send_generic(request_queue_t *q, struct gendisk *bd_disk, int cmd, int data) 499static int __blk_send_generic(request_queue_t *q, struct gendisk *bd_disk, int cmd, int data)