]> err.no Git - linux-2.6/blobdiff - drivers/scsi/scsi_transport_fc.c
ALSA: wm8750: add missing VREF output
[linux-2.6] / drivers / scsi / scsi_transport_fc.c
index 6b092a6c295d52d0b63b7d5659b880c63c07ed7a..56823fd1fb8418811da8fc4418ec271b846b65da 100644 (file)
@@ -417,15 +417,16 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
        fc_host->next_vport_number = 0;
        fc_host->npiv_vports_inuse = 0;
 
-       snprintf(fc_host->work_q_name, KOBJ_NAME_LEN, "fc_wq_%d",
-               shost->host_no);
+       snprintf(fc_host->work_q_name, sizeof(fc_host->work_q_name),
+                "fc_wq_%d", shost->host_no);
        fc_host->work_q = create_singlethread_workqueue(
                                        fc_host->work_q_name);
        if (!fc_host->work_q)
                return -ENOMEM;
 
-       snprintf(fc_host->devloss_work_q_name, KOBJ_NAME_LEN, "fc_dl_%d",
-               shost->host_no);
+       snprintf(fc_host->devloss_work_q_name,
+                sizeof(fc_host->devloss_work_q_name),
+                "fc_dl_%d", shost->host_no);
        fc_host->devloss_work_q = create_singlethread_workqueue(
                                        fc_host->devloss_work_q_name);
        if (!fc_host->devloss_work_q) {
@@ -570,7 +571,7 @@ send_fail:
        name = get_fc_host_event_code_name(event_code);
        printk(KERN_WARNING
                "%s: Dropped Event : host %d %s data 0x%08x - err %d\n",
-               __FUNCTION__, shost->host_no,
+               __func__, shost->host_no,
                (name) ? name : "<unknown>", event_data, err);
        return;
 }
@@ -643,7 +644,7 @@ send_vendor_fail_skb:
 send_vendor_fail:
        printk(KERN_WARNING
                "%s: Dropped Event : host %d vendor_unique - err %d\n",
-               __FUNCTION__, shost->host_no, err);
+               __func__, shost->host_no, err);
        return;
 }
 EXPORT_SYMBOL(fc_host_post_vendor_event);
@@ -1961,12 +1962,17 @@ fc_timed_out(struct scsi_cmnd *scmd)
 }
 
 /*
- * Must be called with shost->host_lock held
+ * Called by fc_user_scan to locate an rport on the shost that
+ * matches the channel and target id, and invoke scsi_scan_target()
+ * on the rport.
  */
-static int fc_user_scan(struct Scsi_Host *shost, uint channel,
-               uint id, uint lun)
+static void
+fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, uint lun)
 {
        struct fc_rport *rport;
+       unsigned long flags;
+
+       spin_lock_irqsave(shost->host_lock, flags);
 
        list_for_each_entry(rport, &fc_host_rports(shost), peers) {
                if (rport->scsi_target_id == -1)
@@ -1975,13 +1981,54 @@ static int fc_user_scan(struct Scsi_Host *shost, uint channel,
                if (rport->port_state != FC_PORTSTATE_ONLINE)
                        continue;
 
-               if ((channel == SCAN_WILD_CARD || channel == rport->channel) &&
-                   (id == SCAN_WILD_CARD || id == rport->scsi_target_id)) {
-                       scsi_scan_target(&rport->dev, rport->channel,
-                                        rport->scsi_target_id, lun, 1);
+               if ((channel == rport->channel) &&
+                   (id == rport->scsi_target_id)) {
+                       spin_unlock_irqrestore(shost->host_lock, flags);
+                       scsi_scan_target(&rport->dev, channel, id, lun, 1);
+                       return;
                }
        }
 
+       spin_unlock_irqrestore(shost->host_lock, flags);
+}
+
+/*
+ * Called via sysfs scan routines. Necessary, as the FC transport
+ * wants to place all target objects below the rport object. So this
+ * routine must invoke the scsi_scan_target() routine with the rport
+ * object as the parent.
+ */
+static int
+fc_user_scan(struct Scsi_Host *shost, uint channel, uint id, uint lun)
+{
+       uint chlo, chhi;
+       uint tgtlo, tgthi;
+
+       if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
+           ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
+           ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
+               return -EINVAL;
+
+       if (channel == SCAN_WILD_CARD) {
+               chlo = 0;
+               chhi = shost->max_channel + 1;
+       } else {
+               chlo = channel;
+               chhi = channel + 1;
+       }
+
+       if (id == SCAN_WILD_CARD) {
+               tgtlo = 0;
+               tgthi = shost->max_id;
+       } else {
+               tgtlo = id;
+               tgthi = id + 1;
+       }
+
+       for ( ; chlo < chhi; chlo++)
+               for ( ; tgtlo < tgthi; tgtlo++)
+                       fc_user_scan_tgt(shost, chlo, tgtlo, lun);
+
        return 0;
 }
 
@@ -2417,7 +2464,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
        size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size);
        rport = kzalloc(size, GFP_KERNEL);
        if (unlikely(!rport)) {
-               printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
+               printk(KERN_ERR "%s: allocation failure\n", __func__);
                return NULL;
        }
 
@@ -3090,7 +3137,7 @@ fc_vport_create(struct Scsi_Host *shost, int channel, struct device *pdev,
        size = (sizeof(struct fc_vport) + fci->f->dd_fcvport_size);
        vport = kzalloc(size, GFP_KERNEL);
        if (unlikely(!vport)) {
-               printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
+               printk(KERN_ERR "%s: allocation failure\n", __func__);
                return -ENOMEM;
        }
 
@@ -3154,7 +3201,7 @@ fc_vport_create(struct Scsi_Host *shost, int channel, struct device *pdev,
                        printk(KERN_ERR
                                "%s: Cannot create vport symlinks for "
                                "%s, err=%d\n",
-                               __FUNCTION__, dev->bus_id, error);
+                               __func__, dev->bus_id, error);
        }
        spin_lock_irqsave(shost->host_lock, flags);
        vport->flags &= ~FC_VPORT_CREATING;
@@ -3267,7 +3314,7 @@ fc_vport_sched_delete(struct work_struct *work)
        if (stat)
                dev_printk(KERN_ERR, vport->dev.parent,
                        "%s: %s could not be deleted created via "
-                       "shost%d channel %d - error %d\n", __FUNCTION__,
+                       "shost%d channel %d - error %d\n", __func__,
                        vport->dev.bus_id, vport->shost->host_no,
                        vport->channel, stat);
 }