aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sr.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2007-08-04 11:06:25 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:49:30 -0400
commit7f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65 (patch)
treef2cceb87e2b6c9a66c66a8c8ceeb20bad09bb6fa /drivers/scsi/sr.c
parentd3849d512fb0ca1e369e3efcaec910a949f55f62 (diff)
[SCSI] move ULD attachment into the prep function
One of the intents of the block prep function was to allow ULDs to use it for preprocessing. The original SCSI model was to have a single prep function and add a pointer indirect filter to build the necessary commands. This patch reverses that, does away with the init_command field of the scsi_driver structure and makes ULDs attach directly to the prep function instead. The value is really that it allows us to begin to separate the ULDs from the SCSI mid layer (as long as they don't use any core functions---which is hard at the moment---a ULD doesn't even need SCSI to bind). Acked-by: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r--drivers/scsi/sr.c59
1 files changed, 40 insertions, 19 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 902eb11ffe8a..a0c4e13d4dab 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -78,7 +78,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM);
78 78
79static int sr_probe(struct device *); 79static int sr_probe(struct device *);
80static int sr_remove(struct device *); 80static int sr_remove(struct device *);
81static int sr_init_command(struct scsi_cmnd *);
82 81
83static struct scsi_driver sr_template = { 82static struct scsi_driver sr_template = {
84 .owner = THIS_MODULE, 83 .owner = THIS_MODULE,
@@ -87,7 +86,6 @@ static struct scsi_driver sr_template = {
87 .probe = sr_probe, 86 .probe = sr_probe,
88 .remove = sr_remove, 87 .remove = sr_remove,
89 }, 88 },
90 .init_command = sr_init_command,
91}; 89};
92 90
93static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; 91static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG];
@@ -296,19 +294,39 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
296 scsi_io_completion(SCpnt, good_bytes); 294 scsi_io_completion(SCpnt, good_bytes);
297} 295}
298 296
299static int sr_init_command(struct scsi_cmnd * SCpnt) 297static int sr_prep_fn(struct request_queue *q, struct request *rq)
300{ 298{
301 int block=0, this_count, s_size, timeout = SR_TIMEOUT; 299 int block=0, this_count, s_size, timeout = SR_TIMEOUT;
302 struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk); 300 struct scsi_cd *cd;
301 struct scsi_cmnd *SCpnt;
302 struct scsi_device *sdp = q->queuedata;
303 int ret;
304
305 if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
306 ret = scsi_setup_blk_pc_cmnd(sdp, rq);
307 goto out;
308 } else if (rq->cmd_type != REQ_TYPE_FS) {
309 ret = BLKPREP_KILL;
310 goto out;
311 }
312 ret = scsi_setup_fs_cmnd(sdp, rq);
313 if (ret != BLKPREP_OK)
314 goto out;
315 SCpnt = rq->special;
316 cd = scsi_cd(rq->rq_disk);
317
318 /* from here on until we're complete, any goto out
319 * is used for a killable error condition */
320 ret = BLKPREP_KILL;
303 321
304 SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n", 322 SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n",
305 cd->disk->disk_name, block)); 323 cd->disk->disk_name, block));
306 324
307 if (!cd->device || !scsi_device_online(cd->device)) { 325 if (!cd->device || !scsi_device_online(cd->device)) {
308 SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", 326 SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n",
309 SCpnt->request->nr_sectors)); 327 rq->nr_sectors));
310 SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); 328 SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
311 return 0; 329 goto out;
312 } 330 }
313 331
314 if (cd->device->changed) { 332 if (cd->device->changed) {
@@ -316,7 +334,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
316 * quietly refuse to do anything to a changed disc until the 334 * quietly refuse to do anything to a changed disc until the
317 * changed bit has been reset 335 * changed bit has been reset
318 */ 336 */
319 return 0; 337 goto out;
320 } 338 }
321 339
322 /* 340 /*
@@ -333,21 +351,21 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
333 351
334 if (s_size != 512 && s_size != 1024 && s_size != 2048) { 352 if (s_size != 512 && s_size != 1024 && s_size != 2048) {
335 scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size); 353 scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size);
336 return 0; 354 goto out;
337 } 355 }
338 356
339 if (rq_data_dir(SCpnt->request) == WRITE) { 357 if (rq_data_dir(rq) == WRITE) {
340 if (!cd->device->writeable) 358 if (!cd->device->writeable)
341 return 0; 359 goto out;
342 SCpnt->cmnd[0] = WRITE_10; 360 SCpnt->cmnd[0] = WRITE_10;
343 SCpnt->sc_data_direction = DMA_TO_DEVICE; 361 SCpnt->sc_data_direction = DMA_TO_DEVICE;
344 cd->cdi.media_written = 1; 362 cd->cdi.media_written = 1;
345 } else if (rq_data_dir(SCpnt->request) == READ) { 363 } else if (rq_data_dir(rq) == READ) {
346 SCpnt->cmnd[0] = READ_10; 364 SCpnt->cmnd[0] = READ_10;
347 SCpnt->sc_data_direction = DMA_FROM_DEVICE; 365 SCpnt->sc_data_direction = DMA_FROM_DEVICE;
348 } else { 366 } else {
349 blk_dump_rq_flags(SCpnt->request, "Unknown sr command"); 367 blk_dump_rq_flags(rq, "Unknown sr command");
350 return 0; 368 goto out;
351 } 369 }
352 370
353 { 371 {
@@ -368,10 +386,10 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
368 /* 386 /*
369 * request doesn't start on hw block boundary, add scatter pads 387 * request doesn't start on hw block boundary, add scatter pads
370 */ 388 */
371 if (((unsigned int)SCpnt->request->sector % (s_size >> 9)) || 389 if (((unsigned int)rq->sector % (s_size >> 9)) ||
372 (SCpnt->request_bufflen % s_size)) { 390 (SCpnt->request_bufflen % s_size)) {
373 scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); 391 scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n");
374 return 0; 392 goto out;
375 } 393 }
376 394
377 this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); 395 this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9);
@@ -379,12 +397,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
379 397
380 SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", 398 SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n",
381 cd->cdi.name, 399 cd->cdi.name,
382 (rq_data_dir(SCpnt->request) == WRITE) ? 400 (rq_data_dir(rq) == WRITE) ?
383 "writing" : "reading", 401 "writing" : "reading",
384 this_count, SCpnt->request->nr_sectors)); 402 this_count, rq->nr_sectors));
385 403
386 SCpnt->cmnd[1] = 0; 404 SCpnt->cmnd[1] = 0;
387 block = (unsigned int)SCpnt->request->sector / (s_size >> 9); 405 block = (unsigned int)rq->sector / (s_size >> 9);
388 406
389 if (this_count > 0xffff) { 407 if (this_count > 0xffff) {
390 this_count = 0xffff; 408 this_count = 0xffff;
@@ -419,7 +437,9 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
419 * This indicates that the command is ready from our end to be 437 * This indicates that the command is ready from our end to be
420 * queued. 438 * queued.
421 */ 439 */
422 return 1; 440 ret = BLKPREP_OK;
441 out:
442 return scsi_prep_return(q, rq, ret);
423} 443}
424 444
425static int sr_block_open(struct inode *inode, struct file *file) 445static int sr_block_open(struct inode *inode, struct file *file)
@@ -590,6 +610,7 @@ static int sr_probe(struct device *dev)
590 610
591 /* FIXME: need to handle a get_capabilities failure properly ?? */ 611 /* FIXME: need to handle a get_capabilities failure properly ?? */
592 get_capabilities(cd); 612 get_capabilities(cd);
613 blk_queue_prep_rq(sdev->request_queue, sr_prep_fn);
593 sr_vendor_init(cd); 614 sr_vendor_init(cd);
594 615
595 disk->driverfs_dev = &sdev->sdev_gendev; 616 disk->driverfs_dev = &sdev->sdev_gendev;