diff options
author | Matthew Wilcox <matthew@wil.cx> | 2007-09-25 12:42:04 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-10-12 14:52:46 -0400 |
commit | 6f5391c283d7fdcf24bf40786ea79061919d1e1d (patch) | |
tree | 32ee9abddf9879445792019e1c03bcd28ce6bd4f /drivers | |
parent | 687d2bc4877081a44c41b5b312e012cc69edda53 (diff) |
[SCSI] Get rid of scsi_cmnd->done
The ULD ->done callback moves into the scsi_driver. By moving the call
to scsi_io_completion() from scsi_blk_pc_done() to scsi_finish_command(),
we can eliminate the latter entirely. By returning 'good_bytes' from
the ->done callback (rather than invoking scsi_io_completion()), we can
stop exporting scsi_io_completion().
Also move the prototypes from sd.h to sd.c as they're all internal anyway.
Rename sd_rw_intr to sd_done and rw_intr to sr_done.
Inspired-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/scsi.c | 20 | ||||
-rw-r--r-- | drivers/scsi/scsi_error.c | 1 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 14 | ||||
-rw-r--r-- | drivers/scsi/scsi_priv.h | 1 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 28 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 21 |
6 files changed, 42 insertions, 43 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 07a7c2a70a3f..192948822455 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <scsi/scsi_cmnd.h> | 59 | #include <scsi/scsi_cmnd.h> |
60 | #include <scsi/scsi_dbg.h> | 60 | #include <scsi/scsi_dbg.h> |
61 | #include <scsi/scsi_device.h> | 61 | #include <scsi/scsi_device.h> |
62 | #include <scsi/scsi_driver.h> | ||
62 | #include <scsi/scsi_eh.h> | 63 | #include <scsi/scsi_eh.h> |
63 | #include <scsi/scsi_host.h> | 64 | #include <scsi/scsi_host.h> |
64 | #include <scsi/scsi_tcq.h> | 65 | #include <scsi/scsi_tcq.h> |
@@ -367,9 +368,8 @@ void scsi_log_send(struct scsi_cmnd *cmd) | |||
367 | scsi_print_command(cmd); | 368 | scsi_print_command(cmd); |
368 | if (level > 3) { | 369 | if (level > 3) { |
369 | printk(KERN_INFO "buffer = 0x%p, bufflen = %d," | 370 | printk(KERN_INFO "buffer = 0x%p, bufflen = %d," |
370 | " done = 0x%p, queuecommand 0x%p\n", | 371 | " queuecommand 0x%p\n", |
371 | scsi_sglist(cmd), scsi_bufflen(cmd), | 372 | scsi_sglist(cmd), scsi_bufflen(cmd), |
372 | cmd->done, | ||
373 | cmd->device->host->hostt->queuecommand); | 373 | cmd->device->host->hostt->queuecommand); |
374 | 374 | ||
375 | } | 375 | } |
@@ -654,6 +654,12 @@ void __scsi_done(struct scsi_cmnd *cmd) | |||
654 | blk_complete_request(rq); | 654 | blk_complete_request(rq); |
655 | } | 655 | } |
656 | 656 | ||
657 | /* Move this to a header if it becomes more generally useful */ | ||
658 | static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) | ||
659 | { | ||
660 | return *(struct scsi_driver **)cmd->request->rq_disk->private_data; | ||
661 | } | ||
662 | |||
657 | /* | 663 | /* |
658 | * Function: scsi_finish_command | 664 | * Function: scsi_finish_command |
659 | * | 665 | * |
@@ -665,6 +671,8 @@ void scsi_finish_command(struct scsi_cmnd *cmd) | |||
665 | { | 671 | { |
666 | struct scsi_device *sdev = cmd->device; | 672 | struct scsi_device *sdev = cmd->device; |
667 | struct Scsi_Host *shost = sdev->host; | 673 | struct Scsi_Host *shost = sdev->host; |
674 | struct scsi_driver *drv; | ||
675 | unsigned int good_bytes; | ||
668 | 676 | ||
669 | scsi_device_unbusy(sdev); | 677 | scsi_device_unbusy(sdev); |
670 | 678 | ||
@@ -690,7 +698,13 @@ void scsi_finish_command(struct scsi_cmnd *cmd) | |||
690 | "Notifying upper driver of completion " | 698 | "Notifying upper driver of completion " |
691 | "(result %x)\n", cmd->result)); | 699 | "(result %x)\n", cmd->result)); |
692 | 700 | ||
693 | cmd->done(cmd); | 701 | good_bytes = cmd->request_bufflen; |
702 | if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { | ||
703 | drv = scsi_cmd_to_driver(cmd); | ||
704 | if (drv->done) | ||
705 | good_bytes = drv->done(cmd); | ||
706 | } | ||
707 | scsi_io_completion(cmd, good_bytes); | ||
694 | } | 708 | } |
695 | EXPORT_SYMBOL(scsi_finish_command); | 709 | EXPORT_SYMBOL(scsi_finish_command); |
696 | 710 | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 44e6721ddea6..f49feb9351d0 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1671,7 +1671,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1671 | memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); | 1671 | memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); |
1672 | 1672 | ||
1673 | scmd->scsi_done = scsi_reset_provider_done_command; | 1673 | scmd->scsi_done = scsi_reset_provider_done_command; |
1674 | scmd->done = NULL; | ||
1675 | scmd->request_buffer = NULL; | 1674 | scmd->request_buffer = NULL; |
1676 | scmd->request_bufflen = 0; | 1675 | scmd->request_bufflen = 0; |
1677 | 1676 | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 86fd3abe731a..fac34293bef7 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -982,7 +982,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
982 | } | 982 | } |
983 | scsi_end_request(cmd, 0, this_count, !result); | 983 | scsi_end_request(cmd, 0, this_count, !result); |
984 | } | 984 | } |
985 | EXPORT_SYMBOL(scsi_io_completion); | ||
986 | 985 | ||
987 | /* | 986 | /* |
988 | * Function: scsi_init_io() | 987 | * Function: scsi_init_io() |
@@ -1063,18 +1062,6 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, | |||
1063 | return cmd; | 1062 | return cmd; |
1064 | } | 1063 | } |
1065 | 1064 | ||
1066 | static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | ||
1067 | { | ||
1068 | BUG_ON(!blk_pc_request(cmd->request)); | ||
1069 | /* | ||
1070 | * This will complete the whole command with uptodate=1 so | ||
1071 | * as far as the block layer is concerned the command completed | ||
1072 | * successfully. Since this is a REQ_BLOCK_PC command the | ||
1073 | * caller should check the request's errors value | ||
1074 | */ | ||
1075 | scsi_io_completion(cmd, cmd->request_bufflen); | ||
1076 | } | ||
1077 | |||
1078 | int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) | 1065 | int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) |
1079 | { | 1066 | { |
1080 | struct scsi_cmnd *cmd; | 1067 | struct scsi_cmnd *cmd; |
@@ -1124,7 +1111,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) | |||
1124 | cmd->transfersize = req->data_len; | 1111 | cmd->transfersize = req->data_len; |
1125 | cmd->allowed = req->retries; | 1112 | cmd->allowed = req->retries; |
1126 | cmd->timeout_per_command = req->timeout; | 1113 | cmd->timeout_per_command = req->timeout; |
1127 | cmd->done = scsi_blk_pc_done; | ||
1128 | return BLKPREP_OK; | 1114 | return BLKPREP_OK; |
1129 | } | 1115 | } |
1130 | EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); | 1116 | EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index ee8efe849bf4..eff005951895 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -68,6 +68,7 @@ extern int scsi_maybe_unblock_host(struct scsi_device *sdev); | |||
68 | extern void scsi_device_unbusy(struct scsi_device *sdev); | 68 | extern void scsi_device_unbusy(struct scsi_device *sdev); |
69 | extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); | 69 | extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); |
70 | extern void scsi_next_command(struct scsi_cmnd *cmd); | 70 | extern void scsi_next_command(struct scsi_cmnd *cmd); |
71 | extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); | ||
71 | extern void scsi_run_host_queues(struct Scsi_Host *shost); | 72 | extern void scsi_run_host_queues(struct Scsi_Host *shost); |
72 | extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); | 73 | extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); |
73 | extern void scsi_free_queue(struct request_queue *q); | 74 | extern void scsi_free_queue(struct request_queue *q); |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 38a41415004b..0a3a528212c2 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -86,6 +86,19 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); | |||
86 | MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); | 86 | MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); |
87 | MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); | 87 | MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); |
88 | 88 | ||
89 | static int sd_revalidate_disk(struct gendisk *); | ||
90 | static int sd_probe(struct device *); | ||
91 | static int sd_remove(struct device *); | ||
92 | static void sd_shutdown(struct device *); | ||
93 | static int sd_suspend(struct device *, pm_message_t state); | ||
94 | static int sd_resume(struct device *); | ||
95 | static void sd_rescan(struct device *); | ||
96 | static int sd_done(struct scsi_cmnd *); | ||
97 | static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); | ||
98 | static void scsi_disk_release(struct class_device *cdev); | ||
99 | static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); | ||
100 | static void sd_print_result(struct scsi_disk *, int); | ||
101 | |||
89 | static DEFINE_IDR(sd_index_idr); | 102 | static DEFINE_IDR(sd_index_idr); |
90 | static DEFINE_SPINLOCK(sd_index_lock); | 103 | static DEFINE_SPINLOCK(sd_index_lock); |
91 | 104 | ||
@@ -240,6 +253,7 @@ static struct scsi_driver sd_template = { | |||
240 | .shutdown = sd_shutdown, | 253 | .shutdown = sd_shutdown, |
241 | }, | 254 | }, |
242 | .rescan = sd_rescan, | 255 | .rescan = sd_rescan, |
256 | .done = sd_done, | ||
243 | }; | 257 | }; |
244 | 258 | ||
245 | /* | 259 | /* |
@@ -509,12 +523,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
509 | SCpnt->timeout_per_command = timeout; | 523 | SCpnt->timeout_per_command = timeout; |
510 | 524 | ||
511 | /* | 525 | /* |
512 | * This is the completion routine we use. This is matched in terms | ||
513 | * of capability to this function. | ||
514 | */ | ||
515 | SCpnt->done = sd_rw_intr; | ||
516 | |||
517 | /* | ||
518 | * This indicates that the command is ready from our end to be | 526 | * This indicates that the command is ready from our end to be |
519 | * queued. | 527 | * queued. |
520 | */ | 528 | */ |
@@ -908,13 +916,13 @@ static struct block_device_operations sd_fops = { | |||
908 | }; | 916 | }; |
909 | 917 | ||
910 | /** | 918 | /** |
911 | * sd_rw_intr - bottom half handler: called when the lower level | 919 | * sd_done - bottom half handler: called when the lower level |
912 | * driver has completed (successfully or otherwise) a scsi command. | 920 | * driver has completed (successfully or otherwise) a scsi command. |
913 | * @SCpnt: mid-level's per command structure. | 921 | * @SCpnt: mid-level's per command structure. |
914 | * | 922 | * |
915 | * Note: potentially run from within an ISR. Must not block. | 923 | * Note: potentially run from within an ISR. Must not block. |
916 | **/ | 924 | **/ |
917 | static void sd_rw_intr(struct scsi_cmnd * SCpnt) | 925 | static int sd_done(struct scsi_cmnd *SCpnt) |
918 | { | 926 | { |
919 | int result = SCpnt->result; | 927 | int result = SCpnt->result; |
920 | unsigned int xfer_size = SCpnt->request_bufflen; | 928 | unsigned int xfer_size = SCpnt->request_bufflen; |
@@ -935,7 +943,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
935 | SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); | 943 | SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); |
936 | if (sense_valid) { | 944 | if (sense_valid) { |
937 | SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, | 945 | SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, |
938 | "sd_rw_intr: sb[respc,sk,asc," | 946 | "sd_done: sb[respc,sk,asc," |
939 | "ascq]=%x,%x,%x,%x\n", | 947 | "ascq]=%x,%x,%x,%x\n", |
940 | sshdr.response_code, | 948 | sshdr.response_code, |
941 | sshdr.sense_key, sshdr.asc, | 949 | sshdr.sense_key, sshdr.asc, |
@@ -1007,7 +1015,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
1007 | break; | 1015 | break; |
1008 | } | 1016 | } |
1009 | out: | 1017 | out: |
1010 | scsi_io_completion(SCpnt, good_bytes); | 1018 | return good_bytes; |
1011 | } | 1019 | } |
1012 | 1020 | ||
1013 | static int media_not_present(struct scsi_disk *sdkp, | 1021 | static int media_not_present(struct scsi_disk *sdkp, |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index a0c4e13d4dab..c61999031141 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -78,6 +78,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM); | |||
78 | 78 | ||
79 | static int sr_probe(struct device *); | 79 | static int sr_probe(struct device *); |
80 | static int sr_remove(struct device *); | 80 | static int sr_remove(struct device *); |
81 | static int sr_done(struct scsi_cmnd *); | ||
81 | 82 | ||
82 | static struct scsi_driver sr_template = { | 83 | static struct scsi_driver sr_template = { |
83 | .owner = THIS_MODULE, | 84 | .owner = THIS_MODULE, |
@@ -86,6 +87,7 @@ static struct scsi_driver sr_template = { | |||
86 | .probe = sr_probe, | 87 | .probe = sr_probe, |
87 | .remove = sr_remove, | 88 | .remove = sr_remove, |
88 | }, | 89 | }, |
90 | .done = sr_done, | ||
89 | }; | 91 | }; |
90 | 92 | ||
91 | static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; | 93 | static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; |
@@ -208,12 +210,12 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) | |||
208 | } | 210 | } |
209 | 211 | ||
210 | /* | 212 | /* |
211 | * rw_intr is the interrupt routine for the device driver. | 213 | * sr_done is the interrupt routine for the device driver. |
212 | * | 214 | * |
213 | * 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 |
214 | * of several actions based on success or failure. | 216 | * of several actions based on success or failure. |
215 | */ | 217 | */ |
216 | static void rw_intr(struct scsi_cmnd * SCpnt) | 218 | static int sr_done(struct scsi_cmnd *SCpnt) |
217 | { | 219 | { |
218 | int result = SCpnt->result; | 220 | int result = SCpnt->result; |
219 | int this_count = SCpnt->request_bufflen; | 221 | int this_count = SCpnt->request_bufflen; |
@@ -286,12 +288,7 @@ static void rw_intr(struct scsi_cmnd * SCpnt) | |||
286 | } | 288 | } |
287 | } | 289 | } |
288 | 290 | ||
289 | /* | 291 | return good_bytes; |
290 | * This calls the generic completion function, now that we know | ||
291 | * how many actual sectors finished, and how many sectors we need | ||
292 | * to say have failed. | ||
293 | */ | ||
294 | scsi_io_completion(SCpnt, good_bytes); | ||
295 | } | 292 | } |
296 | 293 | ||
297 | static int sr_prep_fn(struct request_queue *q, struct request *rq) | 294 | static int sr_prep_fn(struct request_queue *q, struct request *rq) |
@@ -428,12 +425,6 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) | |||
428 | SCpnt->timeout_per_command = timeout; | 425 | SCpnt->timeout_per_command = timeout; |
429 | 426 | ||
430 | /* | 427 | /* |
431 | * This is the completion routine we use. This is matched in terms | ||
432 | * of capability to this function. | ||
433 | */ | ||
434 | SCpnt->done = rw_intr; | ||
435 | |||
436 | /* | ||
437 | * 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 |
438 | * queued. | 429 | * queued. |
439 | */ | 430 | */ |