Commit cf0bd3e9 authored by Patrick Mansfield's avatar Patrick Mansfield Committed by James Bottomley

[PATCH] add scsi_cmd_ioctl (SG_IO) support for st

Add SG_IO support for st, so we can send scsi commands directly to an st
device.

Though st (still?) needs to move to move away from cdev for udev to
function with it.
parent 807adbc5
......@@ -179,6 +179,7 @@ static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
static int st_probe(struct device *);
static int st_remove(struct device *);
static int st_init_command(struct scsi_cmnd *);
static void do_create_driverfs_files(void);
static void do_remove_driverfs_files(void);
......@@ -191,6 +192,7 @@ static struct scsi_driver st_template = {
.probe = st_probe,
.remove = st_remove,
},
.init_command = st_init_command,
};
static int st_compression(Scsi_Tape *, int);
......@@ -3390,7 +3392,11 @@ static int st_ioctl(struct inode *inode, struct file *file,
goto out;
}
up(&STp->lock);
return scsi_ioctl(STp->device, cmd_in, (void *) arg);
i = scsi_cmd_ioctl(STp->disk, cmd_in, arg);
if (i != -ENOTTY)
return i;
else
return scsi_ioctl(STp->device, cmd_in, (void *) arg);
out:
up(&STp->lock);
......@@ -3797,6 +3803,7 @@ static int st_probe(struct device *dev)
tpnt->disk = disk;
sprintf(disk->disk_name, "st%d", i);
disk->private_data = &tpnt->driver;
disk->queue = SDp->request_queue;
tpnt->driver = &st_template;
scsi_tapes[i] = tpnt;
dev_num = i;
......@@ -4006,6 +4013,41 @@ static int st_remove(struct device *dev)
return 0;
}
static void st_intr(struct scsi_cmnd *SCpnt)
{
scsi_io_completion(SCpnt, (SCpnt->result ? 0: SCpnt->bufflen >> 9), 1);
}
/*
* st_init_command: only called via the scsi_cmd_ioctl (block SG_IO)
* interface for REQ_BLOCK_PC commands.
*/
static int st_init_command(struct scsi_cmnd *SCpnt)
{
struct request *rq;
if (!(SCpnt->request->flags & REQ_BLOCK_PC))
return 0;
rq = SCpnt->request;
if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
return 0;
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
if (rq_data_dir(rq) == WRITE)
SCpnt->sc_data_direction = DMA_TO_DEVICE;
else if (rq->data_len)
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
else
SCpnt->sc_data_direction = DMA_NONE;
SCpnt->timeout_per_command = rq->timeout;
SCpnt->transfersize = rq->data_len;
SCpnt->done = st_intr;
return 1;
}
static int __init init_st(void)
{
validate_options();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment