]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/scsi_transport_fc.c
driver core: remove KOBJ_NAME_LEN define
[linux-2.6-omap-h63xx.git] / drivers / scsi / scsi_transport_fc.c
index 6b092a6c295d52d0b63b7d5659b880c63c07ed7a..a272b9a2c86945314a8ae4693cc18b2a37dce2cb 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) {
@@ -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;
 }