diff options
author | James Bottomley <jejb@titanic.(none)> | 2005-06-15 19:48:29 -0400 |
---|---|---|
committer | James Bottomley <jejb@titanic.(none)> | 2005-08-28 11:46:40 -0400 |
commit | 392160335c798bbe94ab3aae6ea0c85d32b81bbc (patch) | |
tree | ce664010089283f464d88cd89c11a60d35923851 /drivers/scsi/scsi_lib.c | |
parent | 8e6401187ef7fb1edc2740832b48bf47ed2c90f2 (diff) |
[SCSI] use scatter lists for all block pc requests and simplify hw handlers
Original From: Mike Christie <michaelc@cs.wisc.edu>
Add scsi_execute_req() as a replacement for scsi_wait_req()
Fixed up various pieces (added REQ_SPECIAL and caught req use after
free)
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 60f07b6a5ffc..b8212c563fed 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -246,7 +246,7 @@ void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer, | |||
246 | unsigned bufflen, int timeout, int retries) | 246 | unsigned bufflen, int timeout, int retries) |
247 | { | 247 | { |
248 | DECLARE_COMPLETION(wait); | 248 | DECLARE_COMPLETION(wait); |
249 | int write = sreq->sr_data_direction == DMA_TO_DEVICE; | 249 | int write = (sreq->sr_data_direction == DMA_TO_DEVICE); |
250 | struct request *req; | 250 | struct request *req; |
251 | 251 | ||
252 | req = blk_get_request(sreq->sr_device->request_queue, write, | 252 | req = blk_get_request(sreq->sr_device->request_queue, write, |
@@ -281,6 +281,55 @@ void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer, | |||
281 | 281 | ||
282 | EXPORT_SYMBOL(scsi_wait_req); | 282 | EXPORT_SYMBOL(scsi_wait_req); |
283 | 283 | ||
284 | /** | ||
285 | * scsi_execute_req - insert request and wait for the result | ||
286 | * @sdev: scsi device | ||
287 | * @cmd: scsi command | ||
288 | * @data_direction: data direction | ||
289 | * @buffer: data buffer | ||
290 | * @bufflen: len of buffer | ||
291 | * @sense: optional sense buffer | ||
292 | * @timeout: request timeout in seconds | ||
293 | * @retries: number of times to retry request | ||
294 | * | ||
295 | * scsi_execute_req returns the req->errors value which is the | ||
296 | * the scsi_cmnd result field. | ||
297 | **/ | ||
298 | int scsi_execute_req(struct scsi_device *sdev, unsigned char *cmd, | ||
299 | int data_direction, void *buffer, unsigned bufflen, | ||
300 | unsigned char *sense, int timeout, int retries) | ||
301 | { | ||
302 | struct request *req; | ||
303 | int write = (data_direction == DMA_TO_DEVICE); | ||
304 | int ret = DRIVER_ERROR << 24; | ||
305 | |||
306 | req = blk_get_request(sdev->request_queue, write, __GFP_WAIT); | ||
307 | |||
308 | if (bufflen && blk_rq_map_kern(sdev->request_queue, req, | ||
309 | buffer, bufflen, __GFP_WAIT)) | ||
310 | goto out; | ||
311 | |||
312 | req->cmd_len = COMMAND_SIZE(cmd[0]); | ||
313 | memcpy(req->cmd, cmd, req->cmd_len); | ||
314 | req->sense = sense; | ||
315 | req->sense_len = 0; | ||
316 | req->timeout = timeout; | ||
317 | req->flags |= REQ_BLOCK_PC | REQ_SPECIAL; | ||
318 | |||
319 | /* | ||
320 | * head injection *required* here otherwise quiesce won't work | ||
321 | */ | ||
322 | blk_execute_rq(req->q, NULL, req, 1); | ||
323 | |||
324 | ret = req->errors; | ||
325 | out: | ||
326 | blk_put_request(req); | ||
327 | |||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | EXPORT_SYMBOL(scsi_execute_req); | ||
332 | |||
284 | /* | 333 | /* |
285 | * Function: scsi_init_cmd_errh() | 334 | * Function: scsi_init_cmd_errh() |
286 | * | 335 | * |