return ret;
}
-/**
- * sg_scsi_ioctl -- handle deprecated SCSI_IOCTL_SEND_COMMAND ioctl
- * @file: file this ioctl operates on (optional)
- * @q: request queue to send scsi commands down
- * @disk: gendisk to operate on (option)
- * @sic: userspace structure describing the command to perform
- *
- * Send down the scsi command described by @sic to the device below
- * the request queue @q. If @file is non-NULL it's used to perform
- * fine-grained permission checks that allow users to send down
- * non-destructive SCSI commands. If the caller has a struct gendisk
- * available it should be passed in as @disk to allow the low level
- * driver to use the information contained in it. A non-NULL @disk
- * is only allowed if the caller knows that the low level driver doesn't
- * need it (e.g. in the scsi subsystem).
- *
- * Notes:
- * - This interface is deprecated - users should use the SG_IO
- * interface instead, as this is a more flexible approach to
- * performing SCSI commands on a device.
- * - The SCSI command length is determined by examining the 1st byte
- * of the given command. There is no way to override this.
- * - Data transfers are limited to PAGE_SIZE
- * - The length (x + y) must be at least OMAX_SB_LEN bytes long to
- * accommodate the sense buffer when an error occurs.
- * The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that
- * old code will not be surprised.
- * - If a Unix error occurs (e.g. ENOMEM) then the user will receive
- * a negative return and the Unix error code in 'errno'.
- * If the SCSI command succeeds then 0 is returned.
- * Positive numbers returned are the compacted SCSI error codes (4
- * bytes in one int) where the lowest byte is the SCSI status.
- */
#define OMAX_SB_LEN 16 /* For backward compatibility */
-int sg_scsi_ioctl(struct file *file, struct request_queue *q,
- struct gendisk *disk, struct scsi_ioctl_command __user *sic)
+
+static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
+ struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic)
{
struct request *rq;
int err;
unsigned int in_len, out_len, bytes, opcode, cmdlen;
char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
- if (!sic)
- return -EINVAL;
-
/*
* get in an out lengths, verify they don't exceed a page worth of data
*/
if (copy_from_user(rq->cmd, sic->data, cmdlen))
goto error;
- if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
+ if (copy_from_user(buffer, sic->data + cmdlen, in_len))
goto error;
err = verify_command(file, rq->cmd);
if (err)
goto error;
- /* default. possible overriden later */
- rq->retries = 5;
-
switch (opcode) {
- case SEND_DIAGNOSTIC:
- case FORMAT_UNIT:
- rq->timeout = FORMAT_UNIT_TIMEOUT;
- rq->retries = 1;
- break;
- case START_STOP:
- rq->timeout = START_STOP_TIMEOUT;
- break;
- case MOVE_MEDIUM:
- rq->timeout = MOVE_MEDIUM_TIMEOUT;
- break;
- case READ_ELEMENT_STATUS:
- rq->timeout = READ_ELEMENT_STATUS_TIMEOUT;
- break;
- case READ_DEFECT_DATA:
- rq->timeout = READ_DEFECT_DATA_TIMEOUT;
- rq->retries = 1;
- break;
- default:
- rq->timeout = BLK_DEFAULT_TIMEOUT;
- break;
- }
-
- if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, __GFP_WAIT)) {
- err = DRIVER_ERROR << 24;
- goto out;
+ case SEND_DIAGNOSTIC:
+ case FORMAT_UNIT:
+ rq->timeout = FORMAT_UNIT_TIMEOUT;
+ break;
+ case START_STOP:
+ rq->timeout = START_STOP_TIMEOUT;
+ break;
+ case MOVE_MEDIUM:
+ rq->timeout = MOVE_MEDIUM_TIMEOUT;
+ break;
+ case READ_ELEMENT_STATUS:
+ rq->timeout = READ_ELEMENT_STATUS_TIMEOUT;
+ break;
+ case READ_DEFECT_DATA:
+ rq->timeout = READ_DEFECT_DATA_TIMEOUT;
+ break;
+ default:
+ rq->timeout = BLK_DEFAULT_TIMEOUT;
+ break;
}
memset(sense, 0, sizeof(sense));
rq->sense = sense;
rq->sense_len = 0;
- rq->flags |= REQ_BLOCK_PC;
- blk_execute_rq(q, disk, rq, 0);
+ rq->data = buffer;
+ rq->data_len = bytes;
+ rq->flags |= REQ_BLOCK_PC;
+ rq->retries = 0;
-out:
+ blk_execute_rq(q, bd_disk, rq, 0);
err = rq->errors & 0xff; /* only 8 bit SCSI status */
if (err) {
if (rq->sense_len && rq->sense) {
blk_put_request(rq);
return err;
}
-EXPORT_SYMBOL_GPL(sg_scsi_ioctl);
+
/* Send basic block requests */
static int __blk_send_generic(request_queue_t *q, struct gendisk *bd_disk, int cmd, int data)