diff options
| -rw-r--r-- | drivers/scsi/scsi_scan.c | 26 | ||||
| -rw-r--r-- | drivers/scsi/scsi_sysfs.c | 9 |
2 files changed, 12 insertions, 23 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 752fb5da3de4..5acb83ca5ae5 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
| @@ -387,19 +387,12 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, | |||
| 387 | return found_target; | 387 | return found_target; |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | struct work_queue_wrapper { | 390 | static void scsi_target_reap_usercontext(void *data) |
| 391 | struct work_struct work; | 391 | { |
| 392 | struct scsi_target *starget; | 392 | struct scsi_target *starget = data; |
| 393 | }; | ||
| 394 | |||
| 395 | static void scsi_target_reap_work(void *data) { | ||
| 396 | struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; | ||
| 397 | struct scsi_target *starget = wqw->starget; | ||
| 398 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 393 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
| 399 | unsigned long flags; | 394 | unsigned long flags; |
| 400 | 395 | ||
| 401 | kfree(wqw); | ||
| 402 | |||
| 403 | spin_lock_irqsave(shost->host_lock, flags); | 396 | spin_lock_irqsave(shost->host_lock, flags); |
| 404 | 397 | ||
| 405 | if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { | 398 | if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { |
| @@ -428,18 +421,7 @@ static void scsi_target_reap_work(void *data) { | |||
| 428 | */ | 421 | */ |
| 429 | void scsi_target_reap(struct scsi_target *starget) | 422 | void scsi_target_reap(struct scsi_target *starget) |
| 430 | { | 423 | { |
| 431 | struct work_queue_wrapper *wqw = | 424 | scsi_execute_in_process_context(scsi_target_reap_usercontext, starget); |
| 432 | kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC); | ||
| 433 | |||
| 434 | if (!wqw) { | ||
| 435 | starget_printk(KERN_ERR, starget, | ||
| 436 | "Failed to allocate memory in scsi_reap_target()\n"); | ||
| 437 | return; | ||
| 438 | } | ||
| 439 | |||
| 440 | INIT_WORK(&wqw->work, scsi_target_reap_work, wqw); | ||
| 441 | wqw->starget = starget; | ||
| 442 | schedule_work(&wqw->work); | ||
| 443 | } | 425 | } |
| 444 | 426 | ||
| 445 | /** | 427 | /** |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index a77b32deaf8f..902a5def8e62 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
| @@ -217,8 +217,9 @@ static void scsi_device_cls_release(struct class_device *class_dev) | |||
| 217 | put_device(&sdev->sdev_gendev); | 217 | put_device(&sdev->sdev_gendev); |
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | static void scsi_device_dev_release(struct device *dev) | 220 | static void scsi_device_dev_release_usercontext(void *data) |
| 221 | { | 221 | { |
| 222 | struct device *dev = data; | ||
| 222 | struct scsi_device *sdev; | 223 | struct scsi_device *sdev; |
| 223 | struct device *parent; | 224 | struct device *parent; |
| 224 | struct scsi_target *starget; | 225 | struct scsi_target *starget; |
| @@ -237,6 +238,7 @@ static void scsi_device_dev_release(struct device *dev) | |||
| 237 | 238 | ||
| 238 | if (sdev->request_queue) { | 239 | if (sdev->request_queue) { |
| 239 | sdev->request_queue->queuedata = NULL; | 240 | sdev->request_queue->queuedata = NULL; |
| 241 | /* user context needed to free queue */ | ||
| 240 | scsi_free_queue(sdev->request_queue); | 242 | scsi_free_queue(sdev->request_queue); |
| 241 | /* temporary expedient, try to catch use of queue lock | 243 | /* temporary expedient, try to catch use of queue lock |
| 242 | * after free of sdev */ | 244 | * after free of sdev */ |
| @@ -252,6 +254,11 @@ static void scsi_device_dev_release(struct device *dev) | |||
| 252 | put_device(parent); | 254 | put_device(parent); |
| 253 | } | 255 | } |
| 254 | 256 | ||
| 257 | static void scsi_device_dev_release(struct device *dev) | ||
| 258 | { | ||
| 259 | scsi_execute_in_process_context(scsi_device_dev_release_usercontext, dev); | ||
| 260 | } | ||
| 261 | |||
| 255 | static struct class sdev_class = { | 262 | static struct class sdev_class = { |
| 256 | .name = "scsi_device", | 263 | .name = "scsi_device", |
| 257 | .release = scsi_device_cls_release, | 264 | .release = scsi_device_cls_release, |
