aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLi Zhong <zhong@linux.vnet.ibm.com>2012-09-29 00:23:37 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-10-09 07:04:42 -0400
commit329a402cb052b233bc92aa34c4caf2f7dfb2d76e (patch)
treec58a423318703fc41a61641aef2720d48640f25d
parent865b58c05b841964f48f574c2027311bd04db8a1 (diff)
[SCSI] Shorten the path length of scsi_cmd_to_driver()
This patch tries to shorten the path length of scsi_cmd_to_driver(). As only REQ_TYPE_BLOCK_PC commands can be submitted without a driver, so we could avoid the related NULL checking, as long as we make sure we don't use it for REQ_TYPE_BLOCK_PC type commands. Plus, this fixes a bug where you get different behaviors from REQ_TYPE_BLOCK_PC commands when a driver is and isn't attached. Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/scsi_error.c8
-rw-r--r--include/scsi/scsi_cmnd.h12
2 files changed, 7 insertions, 13 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index de2337f255a..c1b05a83d40 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -789,7 +789,6 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
789 int cmnd_size, int timeout, unsigned sense_bytes) 789 int cmnd_size, int timeout, unsigned sense_bytes)
790{ 790{
791 struct scsi_device *sdev = scmd->device; 791 struct scsi_device *sdev = scmd->device;
792 struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
793 struct Scsi_Host *shost = sdev->host; 792 struct Scsi_Host *shost = sdev->host;
794 DECLARE_COMPLETION_ONSTACK(done); 793 DECLARE_COMPLETION_ONSTACK(done);
795 unsigned long timeleft; 794 unsigned long timeleft;
@@ -845,8 +844,11 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
845 844
846 scsi_eh_restore_cmnd(scmd, &ses); 845 scsi_eh_restore_cmnd(scmd, &ses);
847 846
848 if (sdrv && sdrv->eh_action) 847 if (scmd->request->cmd_type != REQ_TYPE_BLOCK_PC) {
849 rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn); 848 struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
849 if (sdrv->eh_action)
850 rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn);
851 }
850 852
851 return rtn; 853 return rtn;
852} 854}
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index ac06cc59589..de5f5d8f1f8 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -132,18 +132,10 @@ struct scsi_cmnd {
132 unsigned char tag; /* SCSI-II queued command tag */ 132 unsigned char tag; /* SCSI-II queued command tag */
133}; 133};
134 134
135/* make sure not to use it with REQ_TYPE_BLOCK_PC commands */
135static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) 136static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
136{ 137{
137 struct scsi_driver **sdp; 138 return *(struct scsi_driver **)cmd->request->rq_disk->private_data;
138
139 if (!cmd->request->rq_disk)
140 return NULL;
141
142 sdp = (struct scsi_driver **)cmd->request->rq_disk->private_data;
143 if (!sdp)
144 return NULL;
145
146 return *sdp;
147} 139}
148 140
149extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); 141extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);