aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-15 11:19:33 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-15 11:19:33 -0400
commitdf3d80f5a5c74168be42788364d13cf6c83c7b9c (patch)
tree892a964c2fd28d028f2fb7471e8543d3f4006a58 /drivers/scsi/sr.c
parent3d06f7a5f74a813cee817c4b30b5e6f0398da0be (diff)
parentc8e91b0a8fc8493e3bf3efcb3c8f866e9453cf1c (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (207 commits) [SCSI] gdth: fix CONFIG_ISA build failure [SCSI] esp_scsi: remove __dev{init,exit} [SCSI] gdth: !use_sg cleanup and use of scsi accessors [SCSI] gdth: Move members from SCp to gdth_cmndinfo, stage 2 [SCSI] gdth: Setup proper per-command private data [SCSI] gdth: Remove gdth_ctr_tab[] [SCSI] gdth: switch to modern scsi host registration [SCSI] gdth: gdth_interrupt() gdth_get_status() & gdth_wait() fixes [SCSI] gdth: clean up host private data [SCSI] gdth: Remove virt hosts [SCSI] gdth: Reorder scsi_host_template intitializers [SCSI] gdth: kill gdth_{read,write}[bwl] wrappers [SCSI] gdth: Remove 2.4.x support, in-kernel changelog [SCSI] gdth: split out pci probing [SCSI] gdth: split out eisa probing [SCSI] gdth: split out isa probing gdth: Make one abuse of scsi_cmnd less obvious [SCSI] NCR5380: Use scsi_eh API for REQUEST_SENSE invocation [SCSI] usb storage: use scsi_eh API in REQUEST_SENSE execution [SCSI] scsi_error: Refactoring scsi_error to facilitate in synchronous REQUEST_SENSE ...
Diffstat (limited to 'drivers/scsi/sr.c')
-rw-r--r--drivers/scsi/sr.c80
1 files changed, 46 insertions, 34 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 902eb11ffe8a..c61999031141 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -78,7 +78,7 @@ 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 *); 81static int sr_done(struct scsi_cmnd *);
82 82
83static struct scsi_driver sr_template = { 83static struct scsi_driver sr_template = {
84 .owner = THIS_MODULE, 84 .owner = THIS_MODULE,
@@ -87,7 +87,7 @@ static struct scsi_driver sr_template = {
87 .probe = sr_probe, 87 .probe = sr_probe,
88 .remove = sr_remove, 88 .remove = sr_remove,
89 }, 89 },
90 .init_command = sr_init_command, 90 .done = sr_done,
91}; 91};
92 92
93static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; 93static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG];
@@ -210,12 +210,12 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot)
210} 210}
211 211
212/* 212/*
213 * rw_intr is the interrupt routine for the device driver. 213 * sr_done is the interrupt routine for the device driver.
214 * 214 *
215 * It will be notified on the end of a SCSI read / write, and will take on 215 * It will be notified on the end of a SCSI read / write, and will take one
216 * of several actions based on success or failure. 216 * of several actions based on success or failure.
217 */ 217 */
218static void rw_intr(struct scsi_cmnd * SCpnt) 218static int sr_done(struct scsi_cmnd *SCpnt)
219{ 219{
220 int result = SCpnt->result; 220 int result = SCpnt->result;
221 int this_count = SCpnt->request_bufflen; 221 int this_count = SCpnt->request_bufflen;
@@ -288,27 +288,42 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
288 } 288 }
289 } 289 }
290 290
291 /* 291 return good_bytes;
292 * This calls the generic completion function, now that we know
293 * how many actual sectors finished, and how many sectors we need
294 * to say have failed.
295 */
296 scsi_io_completion(SCpnt, good_bytes);
297} 292}
298 293
299static int sr_init_command(struct scsi_cmnd * SCpnt) 294static int sr_prep_fn(struct request_queue *q, struct request *rq)
300{ 295{
301 int block=0, this_count, s_size, timeout = SR_TIMEOUT; 296 int block=0, this_count, s_size, timeout = SR_TIMEOUT;
302 struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk); 297 struct scsi_cd *cd;
298 struct scsi_cmnd *SCpnt;
299 struct scsi_device *sdp = q->queuedata;
300 int ret;
301
302 if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
303 ret = scsi_setup_blk_pc_cmnd(sdp, rq);
304 goto out;
305 } else if (rq->cmd_type != REQ_TYPE_FS) {
306 ret = BLKPREP_KILL;
307 goto out;
308 }
309 ret = scsi_setup_fs_cmnd(sdp, rq);
310 if (ret != BLKPREP_OK)
311 goto out;
312 SCpnt = rq->special;
313 cd = scsi_cd(rq->rq_disk);
314
315 /* from here on until we're complete, any goto out
316 * is used for a killable error condition */
317 ret = BLKPREP_KILL;
303 318
304 SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n", 319 SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n",
305 cd->disk->disk_name, block)); 320 cd->disk->disk_name, block));
306 321
307 if (!cd->device || !scsi_device_online(cd->device)) { 322 if (!cd->device || !scsi_device_online(cd->device)) {
308 SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", 323 SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n",
309 SCpnt->request->nr_sectors)); 324 rq->nr_sectors));
310 SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); 325 SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
311 return 0; 326 goto out;
312 } 327 }
313 328
314 if (cd->device->changed) { 329 if (cd->device->changed) {
@@ -316,7 +331,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
316 * quietly refuse to do anything to a changed disc until the 331 * quietly refuse to do anything to a changed disc until the
317 * changed bit has been reset 332 * changed bit has been reset
318 */ 333 */
319 return 0; 334 goto out;
320 } 335 }
321 336
322 /* 337 /*
@@ -333,21 +348,21 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
333 348
334 if (s_size != 512 && s_size != 1024 && s_size != 2048) { 349 if (s_size != 512 && s_size != 1024 && s_size != 2048) {
335 scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size); 350 scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size);
336 return 0; 351 goto out;
337 } 352 }
338 353
339 if (rq_data_dir(SCpnt->request) == WRITE) { 354 if (rq_data_dir(rq) == WRITE) {
340 if (!cd->device->writeable) 355 if (!cd->device->writeable)
341 return 0; 356 goto out;
342 SCpnt->cmnd[0] = WRITE_10; 357 SCpnt->cmnd[0] = WRITE_10;
343 SCpnt->sc_data_direction = DMA_TO_DEVICE; 358 SCpnt->sc_data_direction = DMA_TO_DEVICE;
344 cd->cdi.media_written = 1; 359 cd->cdi.media_written = 1;
345 } else if (rq_data_dir(SCpnt->request) == READ) { 360 } else if (rq_data_dir(rq) == READ) {
346 SCpnt->cmnd[0] = READ_10; 361 SCpnt->cmnd[0] = READ_10;
347 SCpnt->sc_data_direction = DMA_FROM_DEVICE; 362 SCpnt->sc_data_direction = DMA_FROM_DEVICE;
348 } else { 363 } else {
349 blk_dump_rq_flags(SCpnt->request, "Unknown sr command"); 364 blk_dump_rq_flags(rq, "Unknown sr command");
350 return 0; 365 goto out;
351 } 366 }
352 367
353 { 368 {
@@ -368,10 +383,10 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
368 /* 383 /*
369 * request doesn't start on hw block boundary, add scatter pads 384 * request doesn't start on hw block boundary, add scatter pads
370 */ 385 */
371 if (((unsigned int)SCpnt->request->sector % (s_size >> 9)) || 386 if (((unsigned int)rq->sector % (s_size >> 9)) ||
372 (SCpnt->request_bufflen % s_size)) { 387 (SCpnt->request_bufflen % s_size)) {
373 scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); 388 scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n");
374 return 0; 389 goto out;
375 } 390 }
376 391
377 this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); 392 this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9);
@@ -379,12 +394,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
379 394
380 SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", 395 SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n",
381 cd->cdi.name, 396 cd->cdi.name,
382 (rq_data_dir(SCpnt->request) == WRITE) ? 397 (rq_data_dir(rq) == WRITE) ?
383 "writing" : "reading", 398 "writing" : "reading",
384 this_count, SCpnt->request->nr_sectors)); 399 this_count, rq->nr_sectors));
385 400
386 SCpnt->cmnd[1] = 0; 401 SCpnt->cmnd[1] = 0;
387 block = (unsigned int)SCpnt->request->sector / (s_size >> 9); 402 block = (unsigned int)rq->sector / (s_size >> 9);
388 403
389 if (this_count > 0xffff) { 404 if (this_count > 0xffff) {
390 this_count = 0xffff; 405 this_count = 0xffff;
@@ -410,16 +425,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
410 SCpnt->timeout_per_command = timeout; 425 SCpnt->timeout_per_command = timeout;
411 426
412 /* 427 /*
413 * This is the completion routine we use. This is matched in terms
414 * of capability to this function.
415 */
416 SCpnt->done = rw_intr;
417
418 /*
419 * This indicates that the command is ready from our end to be 428 * This indicates that the command is ready from our end to be
420 * queued. 429 * queued.
421 */ 430 */
422 return 1; 431 ret = BLKPREP_OK;
432 out:
433 return scsi_prep_return(q, rq, ret);
423} 434}
424 435
425static int sr_block_open(struct inode *inode, struct file *file) 436static int sr_block_open(struct inode *inode, struct file *file)
@@ -590,6 +601,7 @@ static int sr_probe(struct device *dev)
590 601
591 /* FIXME: need to handle a get_capabilities failure properly ?? */ 602 /* FIXME: need to handle a get_capabilities failure properly ?? */
592 get_capabilities(cd); 603 get_capabilities(cd);
604 blk_queue_prep_rq(sdev->request_queue, sr_prep_fn);
593 sr_vendor_init(cd); 605 sr_vendor_init(cd);
594 606
595 disk->driverfs_dev = &sdev->sdev_gendev; 607 disk->driverfs_dev = &sdev->sdev_gendev;