diff options
author | James Bottomley <James.Bottomley@steeleye.com> | 2005-12-09 17:45:22 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-12-14 00:29:27 -0500 |
commit | c9526497cf03ee775c3a6f8ba62335735f98de7a (patch) | |
tree | 46619a6e57ca84b51fed852722114c2fd25a9289 | |
parent | 322e079f1b606e46b79bb8b8e6cf6110b5f2aa3f (diff) |
[SCSI] Consolidate REQ_BLOCK_PC handling path (fix ipod panic)
This follows on from Jens' patch and consolidates all of the ULD
separate handlers for REQ_BLOCK_PC into a single call which has his
fix for our direction bug.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/scsi_lib.c | 33 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 16 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 20 | ||||
-rw-r--r-- | drivers/scsi/st.c | 19 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 1 |
5 files changed, 27 insertions, 62 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 097888721ec4..9be5769d44aa 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1078,6 +1078,26 @@ static void scsi_generic_done(struct scsi_cmnd *cmd) | |||
1078 | scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0); | 1078 | scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0); |
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries) | ||
1082 | { | ||
1083 | struct request *req = cmd->request; | ||
1084 | |||
1085 | BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); | ||
1086 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); | ||
1087 | cmd->cmd_len = req->cmd_len; | ||
1088 | if (!req->data_len) | ||
1089 | cmd->sc_data_direction = DMA_NONE; | ||
1090 | else if (rq_data_dir(req) == WRITE) | ||
1091 | cmd->sc_data_direction = DMA_TO_DEVICE; | ||
1092 | else | ||
1093 | cmd->sc_data_direction = DMA_FROM_DEVICE; | ||
1094 | |||
1095 | cmd->transfersize = req->data_len; | ||
1096 | cmd->allowed = retries; | ||
1097 | cmd->timeout_per_command = req->timeout; | ||
1098 | } | ||
1099 | EXPORT_SYMBOL_GPL(scsi_setup_blk_pc_cmnd); | ||
1100 | |||
1081 | static int scsi_prep_fn(struct request_queue *q, struct request *req) | 1101 | static int scsi_prep_fn(struct request_queue *q, struct request *req) |
1082 | { | 1102 | { |
1083 | struct scsi_device *sdev = q->queuedata; | 1103 | struct scsi_device *sdev = q->queuedata; |
@@ -1213,18 +1233,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1213 | goto kill; | 1233 | goto kill; |
1214 | } | 1234 | } |
1215 | } else { | 1235 | } else { |
1216 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); | 1236 | scsi_setup_blk_pc_cmnd(cmd, 3); |
1217 | cmd->cmd_len = req->cmd_len; | ||
1218 | if (!req->data_len) | ||
1219 | cmd->sc_data_direction = DMA_NONE; | ||
1220 | else if (rq_data_dir(req) == WRITE) | ||
1221 | cmd->sc_data_direction = DMA_TO_DEVICE; | ||
1222 | else | ||
1223 | cmd->sc_data_direction = DMA_FROM_DEVICE; | ||
1224 | |||
1225 | cmd->transfersize = req->data_len; | ||
1226 | cmd->allowed = 3; | ||
1227 | cmd->timeout_per_command = req->timeout; | ||
1228 | cmd->done = scsi_generic_done; | 1237 | cmd->done = scsi_generic_done; |
1229 | } | 1238 | } |
1230 | } | 1239 | } |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8613a1317712..03fcbab30033 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -245,24 +245,10 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
245 | * SG_IO from block layer already setup, just copy cdb basically | 245 | * SG_IO from block layer already setup, just copy cdb basically |
246 | */ | 246 | */ |
247 | if (blk_pc_request(rq)) { | 247 | if (blk_pc_request(rq)) { |
248 | if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) | 248 | scsi_setup_blk_pc_cmnd(SCpnt, SD_PASSTHROUGH_RETRIES); |
249 | return 0; | ||
250 | |||
251 | memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); | ||
252 | SCpnt->cmd_len = rq->cmd_len; | ||
253 | if (rq_data_dir(rq) == WRITE) | ||
254 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | ||
255 | else if (rq->data_len) | ||
256 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | ||
257 | else | ||
258 | SCpnt->sc_data_direction = DMA_NONE; | ||
259 | |||
260 | this_count = rq->data_len; | ||
261 | if (rq->timeout) | 249 | if (rq->timeout) |
262 | timeout = rq->timeout; | 250 | timeout = rq->timeout; |
263 | 251 | ||
264 | SCpnt->transfersize = rq->data_len; | ||
265 | SCpnt->allowed = SD_PASSTHROUGH_RETRIES; | ||
266 | goto queue; | 252 | goto queue; |
267 | } | 253 | } |
268 | 254 | ||
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d68cea753bb2..fb4012b5c188 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -320,25 +320,11 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
320 | * these are already setup, just copy cdb basically | 320 | * these are already setup, just copy cdb basically |
321 | */ | 321 | */ |
322 | if (SCpnt->request->flags & REQ_BLOCK_PC) { | 322 | if (SCpnt->request->flags & REQ_BLOCK_PC) { |
323 | struct request *rq = SCpnt->request; | 323 | scsi_setup_blk_pc_cmnd(SCpnt, MAX_RETRIES); |
324 | 324 | ||
325 | if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) | 325 | if (SCpnt->timeout_per_command) |
326 | return 0; | 326 | timeout = SCpnt->timeout_per_command; |
327 | |||
328 | memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); | ||
329 | SCpnt->cmd_len = rq->cmd_len; | ||
330 | if (!rq->data_len) | ||
331 | SCpnt->sc_data_direction = DMA_NONE; | ||
332 | else if (rq_data_dir(rq) == WRITE) | ||
333 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | ||
334 | else | ||
335 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | ||
336 | |||
337 | this_count = rq->data_len; | ||
338 | if (rq->timeout) | ||
339 | timeout = rq->timeout; | ||
340 | 327 | ||
341 | SCpnt->transfersize = rq->data_len; | ||
342 | goto queue; | 328 | goto queue; |
343 | } | 329 | } |
344 | 330 | ||
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 7ac6ea141fff..dd592f6a2529 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -4194,27 +4194,10 @@ static void st_intr(struct scsi_cmnd *SCpnt) | |||
4194 | */ | 4194 | */ |
4195 | static int st_init_command(struct scsi_cmnd *SCpnt) | 4195 | static int st_init_command(struct scsi_cmnd *SCpnt) |
4196 | { | 4196 | { |
4197 | struct request *rq; | ||
4198 | |||
4199 | if (!(SCpnt->request->flags & REQ_BLOCK_PC)) | 4197 | if (!(SCpnt->request->flags & REQ_BLOCK_PC)) |
4200 | return 0; | 4198 | return 0; |
4201 | 4199 | ||
4202 | rq = SCpnt->request; | 4200 | scsi_setup_blk_pc_cmnd(SCpnt, 0); |
4203 | if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) | ||
4204 | return 0; | ||
4205 | |||
4206 | memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); | ||
4207 | SCpnt->cmd_len = rq->cmd_len; | ||
4208 | |||
4209 | if (rq_data_dir(rq) == WRITE) | ||
4210 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | ||
4211 | else if (rq->data_len) | ||
4212 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | ||
4213 | else | ||
4214 | SCpnt->sc_data_direction = DMA_NONE; | ||
4215 | |||
4216 | SCpnt->timeout_per_command = rq->timeout; | ||
4217 | SCpnt->transfersize = rq->data_len; | ||
4218 | SCpnt->done = st_intr; | 4201 | SCpnt->done = st_intr; |
4219 | return 1; | 4202 | return 1; |
4220 | } | 4203 | } |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 7529f4388bb4..20da282d4abb 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -151,5 +151,6 @@ extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); | |||
151 | extern void scsi_put_command(struct scsi_cmnd *); | 151 | extern void scsi_put_command(struct scsi_cmnd *); |
152 | extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int); | 152 | extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int); |
153 | extern void scsi_finish_command(struct scsi_cmnd *cmd); | 153 | extern void scsi_finish_command(struct scsi_cmnd *cmd); |
154 | extern void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries); | ||
154 | 155 | ||
155 | #endif /* _SCSI_SCSI_CMND_H */ | 156 | #endif /* _SCSI_SCSI_CMND_H */ |