.shutdown = sd_shutdown,
},
.rescan = sd_rescan,
- .init_command = sd_init_command,
};
/*
*
* 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;
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;
+ 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,
"sd_init_command: block=%llu, "
rq->nr_sectors));
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
"Retry with 0x%p\n", SCpnt));
- return 0;
+ goto out;
}
if (sdp->changed) {
* the changed bit has been reset
*/
/* 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",
(unsigned long long)block));
if ((block & 1) || (rq->nr_sectors & 1)) {
scmd_printk(KERN_ERR, SCpnt,
"Bad block number requested\n");
- return 0;
+ goto out;
} else {
block = block >> 1;
this_count = this_count >> 1;
if ((block & 3) || (rq->nr_sectors & 3)) {
scmd_printk(KERN_ERR, SCpnt,
"Bad block number requested\n");
- return 0;
+ goto out;
} else {
block = block >> 2;
this_count = this_count >> 2;
if ((block & 7) || (rq->nr_sectors & 7)) {
scmd_printk(KERN_ERR, SCpnt,
"Bad block number requested\n");
- return 0;
+ goto out;
} else {
block = block >> 3;
this_count = this_count >> 3;
}
if (rq_data_dir(rq) == WRITE) {
if (!sdp->writeable) {
- return 0;
+ goto out;
}
SCpnt->cmnd[0] = WRITE_6;
SCpnt->sc_data_direction = DMA_TO_DEVICE;
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
} else {
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,
*/
scmd_printk(KERN_ERR, SCpnt,
"FUA write on READ/WRITE(6) drive\n");
- return 0;
+ goto out;
}
SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f);
* 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);
}
/**
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);
gd->driverfs_dev = &sdp->sdev_gendev;