|
@@ -240,7 +240,6 @@ static struct scsi_driver sd_template = {
|
|
.shutdown = sd_shutdown,
|
|
.shutdown = sd_shutdown,
|
|
},
|
|
},
|
|
.rescan = sd_rescan,
|
|
.rescan = sd_rescan,
|
|
- .init_command = sd_init_command,
|
|
|
|
};
|
|
};
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -331,14 +330,31 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
|
|
*
|
|
*
|
|
* Returns 1 if successful and 0 if error (or cannot be done now).
|
|
* Returns 1 if successful and 0 if error (or cannot be done now).
|
|
**/
|
|
**/
|
|
-static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|
|
|
|
|
+static int sd_prep_fn(struct request_queue *q, struct request *rq)
|
|
{
|
|
{
|
|
- struct scsi_device *sdp = SCpnt->device;
|
|
|
|
- struct request *rq = SCpnt->request;
|
|
|
|
|
|
+ struct scsi_cmnd *SCpnt;
|
|
|
|
+ struct scsi_device *sdp = q->queuedata;
|
|
struct gendisk *disk = rq->rq_disk;
|
|
struct gendisk *disk = rq->rq_disk;
|
|
sector_t block = rq->sector;
|
|
sector_t block = rq->sector;
|
|
- unsigned int this_count = SCpnt->request_bufflen >> 9;
|
|
|
|
|
|
+ unsigned int this_count = rq->nr_sectors;
|
|
unsigned int timeout = sdp->timeout;
|
|
unsigned int timeout = sdp->timeout;
|
|
|
|
+ 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;
|
|
|
|
+
|
|
|
|
+ /* from here on until we're complete, any goto out
|
|
|
|
+ * is used for a killable error condition */
|
|
|
|
+ ret = BLKPREP_KILL;
|
|
|
|
|
|
SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt,
|
|
SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt,
|
|
"sd_init_command: block=%llu, "
|
|
"sd_init_command: block=%llu, "
|
|
@@ -353,7 +369,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|
rq->nr_sectors));
|
|
rq->nr_sectors));
|
|
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
|
|
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
|
|
"Retry with 0x%p\n", SCpnt));
|
|
"Retry with 0x%p\n", SCpnt));
|
|
- return 0;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
|
|
|
|
if (sdp->changed) {
|
|
if (sdp->changed) {
|
|
@@ -362,8 +378,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|
* the changed bit has been reset
|
|
* the changed bit has been reset
|
|
*/
|
|
*/
|
|
/* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
|
|
/* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
|
|
- return 0;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
|
|
+
|
|
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n",
|
|
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n",
|
|
(unsigned long long)block));
|
|
(unsigned long long)block));
|
|
|
|
|
|
@@ -382,7 +399,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|
if ((block & 1) || (rq->nr_sectors & 1)) {
|
|
if ((block & 1) || (rq->nr_sectors & 1)) {
|
|
scmd_printk(KERN_ERR, SCpnt,
|
|
scmd_printk(KERN_ERR, SCpnt,
|
|
"Bad block number requested\n");
|
|
"Bad block number requested\n");
|
|
- return 0;
|
|
|
|
|
|
+ goto out;
|
|
} else {
|
|
} else {
|
|
block = block >> 1;
|
|
block = block >> 1;
|
|
this_count = this_count >> 1;
|
|
this_count = this_count >> 1;
|
|
@@ -392,7 +409,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|
if ((block & 3) || (rq->nr_sectors & 3)) {
|
|
if ((block & 3) || (rq->nr_sectors & 3)) {
|
|
scmd_printk(KERN_ERR, SCpnt,
|
|
scmd_printk(KERN_ERR, SCpnt,
|
|
"Bad block number requested\n");
|
|
"Bad block number requested\n");
|
|
- return 0;
|
|
|
|
|
|
+ goto out;
|
|
} else {
|
|
} else {
|
|
block = block >> 2;
|
|
block = block >> 2;
|
|
this_count = this_count >> 2;
|
|
this_count = this_count >> 2;
|
|
@@ -402,7 +419,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|
if ((block & 7) || (rq->nr_sectors & 7)) {
|
|
if ((block & 7) || (rq->nr_sectors & 7)) {
|
|
scmd_printk(KERN_ERR, SCpnt,
|
|
scmd_printk(KERN_ERR, SCpnt,
|
|
"Bad block number requested\n");
|
|
"Bad block number requested\n");
|
|
- return 0;
|
|
|
|
|
|
+ goto out;
|
|
} else {
|
|
} else {
|
|
block = block >> 3;
|
|
block = block >> 3;
|
|
this_count = this_count >> 3;
|
|
this_count = this_count >> 3;
|
|
@@ -410,7 +427,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|
}
|
|
}
|
|
if (rq_data_dir(rq) == WRITE) {
|
|
if (rq_data_dir(rq) == WRITE) {
|
|
if (!sdp->writeable) {
|
|
if (!sdp->writeable) {
|
|
- return 0;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
SCpnt->cmnd[0] = WRITE_6;
|
|
SCpnt->cmnd[0] = WRITE_6;
|
|
SCpnt->sc_data_direction = DMA_TO_DEVICE;
|
|
SCpnt->sc_data_direction = DMA_TO_DEVICE;
|
|
@@ -419,7 +436,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
|
|
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
|
|
} else {
|
|
} else {
|
|
scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags);
|
|
scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags);
|
|
- return 0;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
|
|
|
|
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
|
|
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
|
|
@@ -470,7 +487,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|
*/
|
|
*/
|
|
scmd_printk(KERN_ERR, SCpnt,
|
|
scmd_printk(KERN_ERR, SCpnt,
|
|
"FUA write on READ/WRITE(6) drive\n");
|
|
"FUA write on READ/WRITE(6) drive\n");
|
|
- return 0;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
|
|
|
|
SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f);
|
|
SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f);
|
|
@@ -501,7 +518,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|
* This indicates that the command is ready from our end to be
|
|
* This indicates that the command is ready from our end to be
|
|
* queued.
|
|
* queued.
|
|
*/
|
|
*/
|
|
- return 1;
|
|
|
|
|
|
+ ret = BLKPREP_OK;
|
|
|
|
+ out:
|
|
|
|
+ return scsi_prep_return(q, rq, ret);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1669,6 +1688,7 @@ static int sd_probe(struct device *dev)
|
|
|
|
|
|
sd_revalidate_disk(gd);
|
|
sd_revalidate_disk(gd);
|
|
|
|
|
|
|
|
+ blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
|
|
blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush);
|
|
blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush);
|
|
|
|
|
|
gd->driverfs_dev = &sdp->sdev_gendev;
|
|
gd->driverfs_dev = &sdp->sdev_gendev;
|