diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/scsi.c | 37 | ||||
-rw-r--r-- | drivers/scsi/scsi_error.c | 6 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 12 | ||||
-rw-r--r-- | drivers/scsi/scsi_tgt_lib.c | 3 |
4 files changed, 31 insertions, 27 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index fb86479ffd4a..2b12983d2b2d 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -284,27 +284,19 @@ EXPORT_SYMBOL_GPL(__scsi_get_command); | |||
284 | */ | 284 | */ |
285 | struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask) | 285 | struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask) |
286 | { | 286 | { |
287 | struct scsi_cmnd *cmd; | 287 | struct scsi_cmnd *cmd = __scsi_get_command(dev->host, gfp_mask); |
288 | unsigned long flags; | ||
288 | 289 | ||
289 | /* Bail if we can't get a reference to the device */ | 290 | if (unlikely(cmd == NULL)) |
290 | if (!get_device(&dev->sdev_gendev)) | ||
291 | return NULL; | 291 | return NULL; |
292 | 292 | ||
293 | cmd = __scsi_get_command(dev->host, gfp_mask); | 293 | cmd->device = dev; |
294 | 294 | INIT_LIST_HEAD(&cmd->list); | |
295 | if (likely(cmd != NULL)) { | 295 | INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); |
296 | unsigned long flags; | 296 | spin_lock_irqsave(&dev->list_lock, flags); |
297 | 297 | list_add_tail(&cmd->list, &dev->cmd_list); | |
298 | cmd->device = dev; | 298 | spin_unlock_irqrestore(&dev->list_lock, flags); |
299 | INIT_LIST_HEAD(&cmd->list); | 299 | cmd->jiffies_at_alloc = jiffies; |
300 | INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); | ||
301 | spin_lock_irqsave(&dev->list_lock, flags); | ||
302 | list_add_tail(&cmd->list, &dev->cmd_list); | ||
303 | spin_unlock_irqrestore(&dev->list_lock, flags); | ||
304 | cmd->jiffies_at_alloc = jiffies; | ||
305 | } else | ||
306 | put_device(&dev->sdev_gendev); | ||
307 | |||
308 | return cmd; | 300 | return cmd; |
309 | } | 301 | } |
310 | EXPORT_SYMBOL(scsi_get_command); | 302 | EXPORT_SYMBOL(scsi_get_command); |
@@ -313,10 +305,8 @@ EXPORT_SYMBOL(scsi_get_command); | |||
313 | * __scsi_put_command - Free a struct scsi_cmnd | 305 | * __scsi_put_command - Free a struct scsi_cmnd |
314 | * @shost: dev->host | 306 | * @shost: dev->host |
315 | * @cmd: Command to free | 307 | * @cmd: Command to free |
316 | * @dev: parent scsi device | ||
317 | */ | 308 | */ |
318 | void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd, | 309 | void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) |
319 | struct device *dev) | ||
320 | { | 310 | { |
321 | unsigned long flags; | 311 | unsigned long flags; |
322 | 312 | ||
@@ -331,8 +321,6 @@ void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd, | |||
331 | 321 | ||
332 | if (likely(cmd != NULL)) | 322 | if (likely(cmd != NULL)) |
333 | scsi_pool_free_command(shost->cmd_pool, cmd); | 323 | scsi_pool_free_command(shost->cmd_pool, cmd); |
334 | |||
335 | put_device(dev); | ||
336 | } | 324 | } |
337 | EXPORT_SYMBOL(__scsi_put_command); | 325 | EXPORT_SYMBOL(__scsi_put_command); |
338 | 326 | ||
@@ -346,7 +334,6 @@ EXPORT_SYMBOL(__scsi_put_command); | |||
346 | */ | 334 | */ |
347 | void scsi_put_command(struct scsi_cmnd *cmd) | 335 | void scsi_put_command(struct scsi_cmnd *cmd) |
348 | { | 336 | { |
349 | struct scsi_device *sdev = cmd->device; | ||
350 | unsigned long flags; | 337 | unsigned long flags; |
351 | 338 | ||
352 | /* serious error if the command hasn't come from a device list */ | 339 | /* serious error if the command hasn't come from a device list */ |
@@ -357,7 +344,7 @@ void scsi_put_command(struct scsi_cmnd *cmd) | |||
357 | 344 | ||
358 | cancel_delayed_work(&cmd->abort_work); | 345 | cancel_delayed_work(&cmd->abort_work); |
359 | 346 | ||
360 | __scsi_put_command(cmd->device->host, cmd, &sdev->sdev_gendev); | 347 | __scsi_put_command(cmd->device->host, cmd); |
361 | } | 348 | } |
362 | EXPORT_SYMBOL(scsi_put_command); | 349 | EXPORT_SYMBOL(scsi_put_command); |
363 | 350 | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 78b004da2885..771c16bfdbac 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -2288,6 +2288,11 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
2288 | if (scsi_autopm_get_host(shost) < 0) | 2288 | if (scsi_autopm_get_host(shost) < 0) |
2289 | return FAILED; | 2289 | return FAILED; |
2290 | 2290 | ||
2291 | if (!get_device(&dev->sdev_gendev)) { | ||
2292 | rtn = FAILED; | ||
2293 | goto out_put_autopm_host; | ||
2294 | } | ||
2295 | |||
2291 | scmd = scsi_get_command(dev, GFP_KERNEL); | 2296 | scmd = scsi_get_command(dev, GFP_KERNEL); |
2292 | blk_rq_init(NULL, &req); | 2297 | blk_rq_init(NULL, &req); |
2293 | scmd->request = &req; | 2298 | scmd->request = &req; |
@@ -2345,6 +2350,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
2345 | scsi_run_host_queues(shost); | 2350 | scsi_run_host_queues(shost); |
2346 | 2351 | ||
2347 | scsi_next_command(scmd); | 2352 | scsi_next_command(scmd); |
2353 | out_put_autopm_host: | ||
2348 | scsi_autopm_put_host(shost); | 2354 | scsi_autopm_put_host(shost); |
2349 | return rtn; | 2355 | return rtn; |
2350 | } | 2356 | } |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 492071ca45d1..007e979fa437 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -95,6 +95,7 @@ static void scsi_unprep_request(struct request *req) | |||
95 | req->special = NULL; | 95 | req->special = NULL; |
96 | 96 | ||
97 | scsi_put_command(cmd); | 97 | scsi_put_command(cmd); |
98 | put_device(&cmd->device->sdev_gendev); | ||
98 | } | 99 | } |
99 | 100 | ||
100 | /** | 101 | /** |
@@ -529,6 +530,7 @@ void scsi_next_command(struct scsi_cmnd *cmd) | |||
529 | get_device(&sdev->sdev_gendev); | 530 | get_device(&sdev->sdev_gendev); |
530 | 531 | ||
531 | scsi_put_command(cmd); | 532 | scsi_put_command(cmd); |
533 | put_device(&sdev->sdev_gendev); | ||
532 | scsi_run_queue(q); | 534 | scsi_run_queue(q); |
533 | 535 | ||
534 | /* ok to remove device now */ | 536 | /* ok to remove device now */ |
@@ -1123,6 +1125,7 @@ err_exit: | |||
1123 | scsi_release_buffers(cmd); | 1125 | scsi_release_buffers(cmd); |
1124 | cmd->request->special = NULL; | 1126 | cmd->request->special = NULL; |
1125 | scsi_put_command(cmd); | 1127 | scsi_put_command(cmd); |
1128 | put_device(&cmd->device->sdev_gendev); | ||
1126 | return error; | 1129 | return error; |
1127 | } | 1130 | } |
1128 | EXPORT_SYMBOL(scsi_init_io); | 1131 | EXPORT_SYMBOL(scsi_init_io); |
@@ -1133,9 +1136,15 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, | |||
1133 | struct scsi_cmnd *cmd; | 1136 | struct scsi_cmnd *cmd; |
1134 | 1137 | ||
1135 | if (!req->special) { | 1138 | if (!req->special) { |
1139 | /* Bail if we can't get a reference to the device */ | ||
1140 | if (!get_device(&sdev->sdev_gendev)) | ||
1141 | return NULL; | ||
1142 | |||
1136 | cmd = scsi_get_command(sdev, GFP_ATOMIC); | 1143 | cmd = scsi_get_command(sdev, GFP_ATOMIC); |
1137 | if (unlikely(!cmd)) | 1144 | if (unlikely(!cmd)) { |
1145 | put_device(&sdev->sdev_gendev); | ||
1138 | return NULL; | 1146 | return NULL; |
1147 | } | ||
1139 | req->special = cmd; | 1148 | req->special = cmd; |
1140 | } else { | 1149 | } else { |
1141 | cmd = req->special; | 1150 | cmd = req->special; |
@@ -1298,6 +1307,7 @@ int scsi_prep_return(struct request_queue *q, struct request *req, int ret) | |||
1298 | struct scsi_cmnd *cmd = req->special; | 1307 | struct scsi_cmnd *cmd = req->special; |
1299 | scsi_release_buffers(cmd); | 1308 | scsi_release_buffers(cmd); |
1300 | scsi_put_command(cmd); | 1309 | scsi_put_command(cmd); |
1310 | put_device(&cmd->device->sdev_gendev); | ||
1301 | req->special = NULL; | 1311 | req->special = NULL; |
1302 | } | 1312 | } |
1303 | break; | 1313 | break; |
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 84a1fdf67864..e51add05fb8d 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c | |||
@@ -155,7 +155,8 @@ void scsi_host_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) | |||
155 | __blk_put_request(q, rq); | 155 | __blk_put_request(q, rq); |
156 | spin_unlock_irqrestore(q->queue_lock, flags); | 156 | spin_unlock_irqrestore(q->queue_lock, flags); |
157 | 157 | ||
158 | __scsi_put_command(shost, cmd, &shost->shost_gendev); | 158 | __scsi_put_command(shost, cmd); |
159 | put_device(&shost->shost_gendev); | ||
159 | } | 160 | } |
160 | EXPORT_SYMBOL_GPL(scsi_host_put_command); | 161 | EXPORT_SYMBOL_GPL(scsi_host_put_command); |
161 | 162 | ||