Pull delete-sigdelayed into release branch
[pandora-kernel.git] / drivers / scsi / scsi_scan.c
index 05ebb9c..f9ecc3d 100644 (file)
@@ -334,19 +334,6 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
        struct scsi_target *starget;
        struct scsi_target *found_target;
 
-       /*
-        * Obtain the real parent from the transport. The transport
-        * is allowed to fail (no error) if there is nothing at that
-        * target id.
-        */
-       if (shost->transportt->target_parent) {
-               spin_lock_irqsave(shost->host_lock, flags);
-               parent = shost->transportt->target_parent(shost, channel, id);
-               spin_unlock_irqrestore(shost->host_lock, flags);
-               if (!parent)
-                       return NULL;
-       }
-
        starget = kmalloc(size, GFP_KERNEL);
        if (!starget) {
                printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
@@ -400,19 +387,12 @@ 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;
+static void scsi_target_reap_usercontext(void *data)
+{
+       struct scsi_target *starget = data;
        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)) {
@@ -441,18 +421,7 @@ static void scsi_target_reap_work(void *data) {
  */
 void scsi_target_reap(struct scsi_target *starget)
 {
-       struct work_queue_wrapper *wqw = 
-               kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC);
-
-       if (!wqw) {
-               starget_printk(KERN_ERR, starget,
-                              "Failed to allocate memory in scsi_reap_target()\n");
-               return;
-       }
-
-       INIT_WORK(&wqw->work, scsi_target_reap_work, wqw);
-       wqw->starget = starget;
-       schedule_work(&wqw->work);
+       scsi_execute_in_process_context(scsi_target_reap_usercontext, starget);
 }
 
 /**
@@ -783,8 +752,20 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
 
        transport_configure_device(&sdev->sdev_gendev);
 
-       if (sdev->host->hostt->slave_configure)
-               sdev->host->hostt->slave_configure(sdev);
+       if (sdev->host->hostt->slave_configure) {
+               int ret = sdev->host->hostt->slave_configure(sdev);
+               if (ret) {
+                       /*
+                        * if LLDD reports slave not present, don't clutter
+                        * console with alloc failure messages
+                        */
+                       if (ret != -ENXIO) {
+                               sdev_printk(KERN_ERR, sdev,
+                                       "failed to configure device\n");
+                       }
+                       return SCSI_SCAN_NO_RESPONSE;
+               }
+       }
 
        /*
         * Ok, the device is now all set up, we can
@@ -1283,20 +1264,21 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
        struct scsi_device *sdev;
        struct device *parent = &shost->shost_gendev;
        int res;
-       struct scsi_target *starget = scsi_alloc_target(parent, channel, id);
+       struct scsi_target *starget;
 
+       starget = scsi_alloc_target(parent, channel, id);
        if (!starget)
                return ERR_PTR(-ENOMEM);
 
        get_device(&starget->dev);
-       down(&shost->scan_mutex);
+       mutex_lock(&shost->scan_mutex);
        if (scsi_host_scan_allowed(shost)) {
                res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1,
                                             hostdata);
                if (res != SCSI_SCAN_LUN_PRESENT)
                        sdev = ERR_PTR(-ENODEV);
        }
-       up(&shost->scan_mutex);
+       mutex_unlock(&shost->scan_mutex);
        scsi_target_reap(starget);
        put_device(&starget->dev);
 
@@ -1404,10 +1386,10 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
 {
        struct Scsi_Host *shost = dev_to_shost(parent);
 
-       down(&shost->scan_mutex);
+       mutex_lock(&shost->scan_mutex);
        if (scsi_host_scan_allowed(shost))
                __scsi_scan_target(parent, channel, id, lun, rescan);
-       up(&shost->scan_mutex);
+       mutex_unlock(&shost->scan_mutex);
 }
 EXPORT_SYMBOL(scsi_scan_target);
 
@@ -1454,7 +1436,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
            ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
                return -EINVAL;
 
-       down(&shost->scan_mutex);
+       mutex_lock(&shost->scan_mutex);
        if (scsi_host_scan_allowed(shost)) {
                if (channel == SCAN_WILD_CARD)
                        for (channel = 0; channel <= shost->max_channel;
@@ -1464,7 +1446,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
                else
                        scsi_scan_channel(shost, channel, id, lun, rescan);
        }
-       up(&shost->scan_mutex);
+       mutex_unlock(&shost->scan_mutex);
 
        return 0;
 }
@@ -1522,7 +1504,7 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
        struct scsi_device *sdev = NULL;
        struct scsi_target *starget;
 
-       down(&shost->scan_mutex);
+       mutex_lock(&shost->scan_mutex);
        if (!scsi_host_scan_allowed(shost))
                goto out;
        starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
@@ -1536,7 +1518,7 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
        }
        put_device(&starget->dev);
  out:
-       up(&shost->scan_mutex);
+       mutex_unlock(&shost->scan_mutex);
        return sdev;
 }
 EXPORT_SYMBOL(scsi_get_host_dev);