diff options
author | Len Brown <len.brown@intel.com> | 2006-01-07 03:50:18 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-01-07 03:50:18 -0500 |
commit | ed03f430cdc8c802652467e9097606fedc2c7abc (patch) | |
tree | 30941ec1e6f93e99358fefe18175e5dd800a4379 /drivers/scsi/scsi_scan.c | |
parent | ed349a8a0a780ed27e2a765f16cee54d9b63bfee (diff) | |
parent | 6f957eaf79356a32e838f5f262ee9a60544b1d5b (diff) | |
download | op-kernel-dev-ed03f430cdc8c802652467e9097606fedc2c7abc.zip op-kernel-dev-ed03f430cdc8c802652467e9097606fedc2c7abc.tar.gz |
Pull pnpacpi into acpica branch
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r-- | drivers/scsi/scsi_scan.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 374853d..05ebb9c 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -74,7 +74,7 @@ #define SCSI_SCAN_TARGET_PRESENT 1 #define SCSI_SCAN_LUN_PRESENT 2 -static char *scsi_null_device_strs = "nullnullnullnull"; +static const char *scsi_null_device_strs = "nullnullnullnull"; #define MAX_SCSI_LUNS 512 @@ -266,8 +266,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, /* * if LLDD reports slave not present, don't clutter * console with alloc failure messages - - */ if (ret == -ENXIO) display_failure_msg = 0; @@ -279,7 +277,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, out_device_destroy: transport_destroy_device(&sdev->sdev_gendev); - scsi_free_queue(sdev->request_queue); put_device(&sdev->sdev_gendev); out: if (display_failure_msg) @@ -403,6 +400,36 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, return found_target; } +struct work_queue_wrapper { + struct work_struct work; + struct scsi_target *starget; +}; + +static void scsi_target_reap_work(void *data) { + struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; + struct scsi_target *starget = wqw->starget; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + unsigned long flags; + + kfree(wqw); + + spin_lock_irqsave(shost->host_lock, flags); + + if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { + list_del_init(&starget->siblings); + spin_unlock_irqrestore(shost->host_lock, flags); + transport_remove_device(&starget->dev); + device_del(&starget->dev); + transport_destroy_device(&starget->dev); + put_device(&starget->dev); + return; + + } + spin_unlock_irqrestore(shost->host_lock, flags); + + return; +} + /** * scsi_target_reap - check to see if target is in use and destroy if not * @@ -414,19 +441,18 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, */ void scsi_target_reap(struct scsi_target *starget) { - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + struct work_queue_wrapper *wqw = + kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC); - if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { - list_del_init(&starget->siblings); - spin_unlock_irqrestore(shost->host_lock, flags); - device_del(&starget->dev); - transport_unregister_device(&starget->dev); - put_device(&starget->dev); + if (!wqw) { + starget_printk(KERN_ERR, starget, + "Failed to allocate memory in scsi_reap_target()\n"); return; } - spin_unlock_irqrestore(shost->host_lock, flags); + + INIT_WORK(&wqw->work, scsi_target_reap_work, wqw); + wqw->starget = starget; + schedule_work(&wqw->work); } /** |