diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 2c6116fd4578..38a41415004b 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -240,7 +240,6 @@ static struct scsi_driver sd_template = { | |||
240 | .shutdown = sd_shutdown, | 240 | .shutdown = sd_shutdown, |
241 | }, | 241 | }, |
242 | .rescan = sd_rescan, | 242 | .rescan = sd_rescan, |
243 | .init_command = sd_init_command, | ||
244 | }; | 243 | }; |
245 | 244 | ||
246 | /* | 245 | /* |
@@ -331,14 +330,31 @@ static void scsi_disk_put(struct scsi_disk *sdkp) | |||
331 | * | 330 | * |
332 | * Returns 1 if successful and 0 if error (or cannot be done now). | 331 | * Returns 1 if successful and 0 if error (or cannot be done now). |
333 | **/ | 332 | **/ |
334 | static int sd_init_command(struct scsi_cmnd * SCpnt) | 333 | static int sd_prep_fn(struct request_queue *q, struct request *rq) |
335 | { | 334 | { |
336 | struct scsi_device *sdp = SCpnt->device; | 335 | struct scsi_cmnd *SCpnt; |
337 | struct request *rq = SCpnt->request; | 336 | struct scsi_device *sdp = q->queuedata; |
338 | struct gendisk *disk = rq->rq_disk; | 337 | struct gendisk *disk = rq->rq_disk; |
339 | sector_t block = rq->sector; | 338 | sector_t block = rq->sector; |
340 | unsigned int this_count = SCpnt->request_bufflen >> 9; | 339 | unsigned int this_count = rq->nr_sectors; |
341 | unsigned int timeout = sdp->timeout; | 340 | unsigned int timeout = sdp->timeout; |
341 | int ret; | ||
342 | |||
343 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { | ||
344 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | ||
345 | goto out; | ||
346 | } else if (rq->cmd_type != REQ_TYPE_FS) { | ||
347 | ret = BLKPREP_KILL; | ||
348 | goto out; | ||
349 | } | ||
350 | ret = scsi_setup_fs_cmnd(sdp, rq); | ||
351 | if (ret != BLKPREP_OK) | ||
352 | goto out; | ||
353 | SCpnt = rq->special; | ||
354 | |||
355 | /* from here on until we're complete, any goto out | ||
356 | * is used for a killable error condition */ | ||
357 | ret = BLKPREP_KILL; | ||
342 | 358 | ||
343 | SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, | 359 | SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, |
344 | "sd_init_command: block=%llu, " | 360 | "sd_init_command: block=%llu, " |
@@ -353,7 +369,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
353 | rq->nr_sectors)); | 369 | rq->nr_sectors)); |
354 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, | 370 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, |
355 | "Retry with 0x%p\n", SCpnt)); | 371 | "Retry with 0x%p\n", SCpnt)); |
356 | return 0; | 372 | goto out; |
357 | } | 373 | } |
358 | 374 | ||
359 | if (sdp->changed) { | 375 | if (sdp->changed) { |
@@ -362,8 +378,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
362 | * the changed bit has been reset | 378 | * the changed bit has been reset |
363 | */ | 379 | */ |
364 | /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ | 380 | /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ |
365 | return 0; | 381 | goto out; |
366 | } | 382 | } |
383 | |||
367 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", | 384 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", |
368 | (unsigned long long)block)); | 385 | (unsigned long long)block)); |
369 | 386 | ||
@@ -382,7 +399,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
382 | if ((block & 1) || (rq->nr_sectors & 1)) { | 399 | if ((block & 1) || (rq->nr_sectors & 1)) { |
383 | scmd_printk(KERN_ERR, SCpnt, | 400 | scmd_printk(KERN_ERR, SCpnt, |
384 | "Bad block number requested\n"); | 401 | "Bad block number requested\n"); |
385 | return 0; | 402 | goto out; |
386 | } else { | 403 | } else { |
387 | block = block >> 1; | 404 | block = block >> 1; |
388 | this_count = this_count >> 1; | 405 | this_count = this_count >> 1; |
@@ -392,7 +409,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
392 | if ((block & 3) || (rq->nr_sectors & 3)) { | 409 | if ((block & 3) || (rq->nr_sectors & 3)) { |
393 | scmd_printk(KERN_ERR, SCpnt, | 410 | scmd_printk(KERN_ERR, SCpnt, |
394 | "Bad block number requested\n"); | 411 | "Bad block number requested\n"); |
395 | return 0; | 412 | goto out; |
396 | } else { | 413 | } else { |
397 | block = block >> 2; | 414 | block = block >> 2; |
398 | this_count = this_count >> 2; | 415 | this_count = this_count >> 2; |
@@ -402,7 +419,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
402 | if ((block & 7) || (rq->nr_sectors & 7)) { | 419 | if ((block & 7) || (rq->nr_sectors & 7)) { |
403 | scmd_printk(KERN_ERR, SCpnt, | 420 | scmd_printk(KERN_ERR, SCpnt, |
404 | "Bad block number requested\n"); | 421 | "Bad block number requested\n"); |
405 | return 0; | 422 | goto out; |
406 | } else { | 423 | } else { |
407 | block = block >> 3; | 424 | block = block >> 3; |
408 | this_count = this_count >> 3; | 425 | this_count = this_count >> 3; |
@@ -410,7 +427,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
410 | } | 427 | } |
411 | if (rq_data_dir(rq) == WRITE) { | 428 | if (rq_data_dir(rq) == WRITE) { |
412 | if (!sdp->writeable) { | 429 | if (!sdp->writeable) { |
413 | return 0; | 430 | goto out; |
414 | } | 431 | } |
415 | SCpnt->cmnd[0] = WRITE_6; | 432 | SCpnt->cmnd[0] = WRITE_6; |
416 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | 433 | SCpnt->sc_data_direction = DMA_TO_DEVICE; |
@@ -419,7 +436,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
419 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | 436 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; |
420 | } else { | 437 | } else { |
421 | scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); | 438 | scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); |
422 | return 0; | 439 | goto out; |
423 | } | 440 | } |
424 | 441 | ||
425 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, | 442 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, |
@@ -470,7 +487,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
470 | */ | 487 | */ |
471 | scmd_printk(KERN_ERR, SCpnt, | 488 | scmd_printk(KERN_ERR, SCpnt, |
472 | "FUA write on READ/WRITE(6) drive\n"); | 489 | "FUA write on READ/WRITE(6) drive\n"); |
473 | return 0; | 490 | goto out; |
474 | } | 491 | } |
475 | 492 | ||
476 | SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); | 493 | SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); |
@@ -501,7 +518,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
501 | * This indicates that the command is ready from our end to be | 518 | * This indicates that the command is ready from our end to be |
502 | * queued. | 519 | * queued. |
503 | */ | 520 | */ |
504 | return 1; | 521 | ret = BLKPREP_OK; |
522 | out: | ||
523 | return scsi_prep_return(q, rq, ret); | ||
505 | } | 524 | } |
506 | 525 | ||
507 | /** | 526 | /** |
@@ -1669,6 +1688,7 @@ static int sd_probe(struct device *dev) | |||
1669 | 1688 | ||
1670 | sd_revalidate_disk(gd); | 1689 | sd_revalidate_disk(gd); |
1671 | 1690 | ||
1691 | blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); | ||
1672 | blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush); | 1692 | blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush); |
1673 | 1693 | ||
1674 | gd->driverfs_dev = &sdp->sdev_gendev; | 1694 | gd->driverfs_dev = &sdp->sdev_gendev; |