|
@@ -78,7 +78,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM);
|
|
|
|
|
|
static int sr_probe(struct device *);
|
|
|
static int sr_remove(struct device *);
|
|
|
-static int sr_init_command(struct scsi_cmnd *);
|
|
|
|
|
|
static struct scsi_driver sr_template = {
|
|
|
.owner = THIS_MODULE,
|
|
@@ -87,7 +86,6 @@ static struct scsi_driver sr_template = {
|
|
|
.probe = sr_probe,
|
|
|
.remove = sr_remove,
|
|
|
},
|
|
|
- .init_command = sr_init_command,
|
|
|
};
|
|
|
|
|
|
static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG];
|
|
@@ -296,19 +294,39 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
|
|
|
scsi_io_completion(SCpnt, good_bytes);
|
|
|
}
|
|
|
|
|
|
-static int sr_init_command(struct scsi_cmnd * SCpnt)
|
|
|
+static int sr_prep_fn(struct request_queue *q, struct request *rq)
|
|
|
{
|
|
|
int block=0, this_count, s_size, timeout = SR_TIMEOUT;
|
|
|
- struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk);
|
|
|
+ struct scsi_cd *cd;
|
|
|
+ struct scsi_cmnd *SCpnt;
|
|
|
+ struct scsi_device *sdp = q->queuedata;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
|
|
|
+ ret = scsi_setup_blk_pc_cmnd(sdp, rq);
|
|
|
+ goto out;
|
|
|
+ } else if (rq->cmd_type != REQ_TYPE_FS) {
|
|
|
+ ret = BLKPREP_KILL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ ret = scsi_setup_fs_cmnd(sdp, rq);
|
|
|
+ if (ret != BLKPREP_OK)
|
|
|
+ goto out;
|
|
|
+ SCpnt = rq->special;
|
|
|
+ cd = scsi_cd(rq->rq_disk);
|
|
|
+
|
|
|
+ /* from here on until we're complete, any goto out
|
|
|
+ * is used for a killable error condition */
|
|
|
+ ret = BLKPREP_KILL;
|
|
|
|
|
|
SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n",
|
|
|
cd->disk->disk_name, block));
|
|
|
|
|
|
if (!cd->device || !scsi_device_online(cd->device)) {
|
|
|
SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n",
|
|
|
- SCpnt->request->nr_sectors));
|
|
|
+ rq->nr_sectors));
|
|
|
SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
|
|
|
- return 0;
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
if (cd->device->changed) {
|
|
@@ -316,7 +334,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
|
|
|
* quietly refuse to do anything to a changed disc until the
|
|
|
* changed bit has been reset
|
|
|
*/
|
|
|
- return 0;
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -333,21 +351,21 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
|
|
|
|
|
|
if (s_size != 512 && s_size != 1024 && s_size != 2048) {
|
|
|
scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size);
|
|
|
- return 0;
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
- if (rq_data_dir(SCpnt->request) == WRITE) {
|
|
|
+ if (rq_data_dir(rq) == WRITE) {
|
|
|
if (!cd->device->writeable)
|
|
|
- return 0;
|
|
|
+ goto out;
|
|
|
SCpnt->cmnd[0] = WRITE_10;
|
|
|
SCpnt->sc_data_direction = DMA_TO_DEVICE;
|
|
|
cd->cdi.media_written = 1;
|
|
|
- } else if (rq_data_dir(SCpnt->request) == READ) {
|
|
|
+ } else if (rq_data_dir(rq) == READ) {
|
|
|
SCpnt->cmnd[0] = READ_10;
|
|
|
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
|
|
|
} else {
|
|
|
- blk_dump_rq_flags(SCpnt->request, "Unknown sr command");
|
|
|
- return 0;
|
|
|
+ blk_dump_rq_flags(rq, "Unknown sr command");
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
{
|
|
@@ -368,10 +386,10 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
|
|
|
/*
|
|
|
* request doesn't start on hw block boundary, add scatter pads
|
|
|
*/
|
|
|
- if (((unsigned int)SCpnt->request->sector % (s_size >> 9)) ||
|
|
|
+ if (((unsigned int)rq->sector % (s_size >> 9)) ||
|
|
|
(SCpnt->request_bufflen % s_size)) {
|
|
|
scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n");
|
|
|
- return 0;
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9);
|
|
@@ -379,12 +397,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
|
|
|
|
|
|
SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n",
|
|
|
cd->cdi.name,
|
|
|
- (rq_data_dir(SCpnt->request) == WRITE) ?
|
|
|
+ (rq_data_dir(rq) == WRITE) ?
|
|
|
"writing" : "reading",
|
|
|
- this_count, SCpnt->request->nr_sectors));
|
|
|
+ this_count, rq->nr_sectors));
|
|
|
|
|
|
SCpnt->cmnd[1] = 0;
|
|
|
- block = (unsigned int)SCpnt->request->sector / (s_size >> 9);
|
|
|
+ block = (unsigned int)rq->sector / (s_size >> 9);
|
|
|
|
|
|
if (this_count > 0xffff) {
|
|
|
this_count = 0xffff;
|
|
@@ -419,7 +437,9 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
|
|
|
* This indicates that the command is ready from our end to be
|
|
|
* queued.
|
|
|
*/
|
|
|
- return 1;
|
|
|
+ ret = BLKPREP_OK;
|
|
|
+ out:
|
|
|
+ return scsi_prep_return(q, rq, ret);
|
|
|
}
|
|
|
|
|
|
static int sr_block_open(struct inode *inode, struct file *file)
|
|
@@ -590,6 +610,7 @@ static int sr_probe(struct device *dev)
|
|
|
|
|
|
/* FIXME: need to handle a get_capabilities failure properly ?? */
|
|
|
get_capabilities(cd);
|
|
|
+ blk_queue_prep_rq(sdev->request_queue, sr_prep_fn);
|
|
|
sr_vendor_init(cd);
|
|
|
|
|
|
disk->driverfs_dev = &sdev->sdev_gendev;
|