]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/scsi/scsi_transport_fc.c
[SCSI] st: make all the fragment buffers the same size
[mv-sheeva.git] / drivers / scsi / scsi_transport_fc.c
index d5f7653bb94bad8b4fd559b54fe2cc7bca1cf28c..dcef78776503a70866185d08936a7e835bff60fb 100644 (file)
@@ -2133,8 +2133,7 @@ fc_attach_transport(struct fc_function_template *ft)
        SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles);
        SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state);
        SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id);
-       if (ft->terminate_rport_io)
-               SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);
+       SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);
 
        BUG_ON(count > FC_RPORT_NUM_ATTRS);
 
@@ -2328,6 +2327,22 @@ fc_remove_host(struct Scsi_Host *shost)
 }
 EXPORT_SYMBOL(fc_remove_host);
 
+static void fc_terminate_rport_io(struct fc_rport *rport)
+{
+       struct Scsi_Host *shost = rport_to_shost(rport);
+       struct fc_internal *i = to_fc_internal(shost->transportt);
+
+       /* Involve the LLDD if possible to terminate all io on the rport. */
+       if (i->f->terminate_rport_io)
+               i->f->terminate_rport_io(rport);
+
+       /*
+        * must unblock to flush queued IO. The caller will have set
+        * the port_state or flags, so that fc_remote_port_chkready will
+        * fail IO.
+        */
+       scsi_target_unblock(&rport->dev);
+}
 
 /**
  * fc_starget_delete - called to delete the scsi decendents of an rport
@@ -2340,13 +2355,8 @@ fc_starget_delete(struct work_struct *work)
 {
        struct fc_rport *rport =
                container_of(work, struct fc_rport, stgt_delete_work);
-       struct Scsi_Host *shost = rport_to_shost(rport);
-       struct fc_internal *i = to_fc_internal(shost->transportt);
-
-       /* Involve the LLDD if possible to terminate all io on the rport. */
-       if (i->f->terminate_rport_io)
-               i->f->terminate_rport_io(rport);
 
+       fc_terminate_rport_io(rport);
        scsi_remove_target(&rport->dev);
 }
 
@@ -2372,10 +2382,7 @@ fc_rport_final_delete(struct work_struct *work)
        if (rport->flags & FC_RPORT_SCAN_PENDING)
                scsi_flush_work(shost);
 
-       /* involve the LLDD to terminate all pending i/o */
-       if (i->f->terminate_rport_io)
-               i->f->terminate_rport_io(rport);
-
+       fc_terminate_rport_io(rport);
        /*
         * Cancel any outstanding timers. These should really exist
         * only when rmmod'ing the LLDD and we're asking for
@@ -2479,8 +2486,8 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
        device_initialize(dev);                 /* takes self reference */
        dev->parent = get_device(&shost->shost_gendev); /* parent reference */
        dev->release = fc_rport_dev_release;
-       sprintf(dev->bus_id, "rport-%d:%d-%d",
-               shost->host_no, channel, rport->number);
+       dev_set_name(dev, "rport-%d:%d-%d",
+                    shost->host_no, channel, rport->number);
        transport_setup_device(dev);
 
        error = device_add(dev);
@@ -2639,7 +2646,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
 
                                spin_lock_irqsave(shost->host_lock, flags);
 
-                               rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
+                               rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
+                                                 FC_RPORT_DEVLOSS_PENDING);
 
                                /* if target, initiate a scan */
                                if (rport->scsi_target_id != -1) {
@@ -2702,6 +2710,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
                        rport->port_id = ids->port_id;
                        rport->roles = ids->roles;
                        rport->port_state = FC_PORTSTATE_ONLINE;
+                       rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
 
                        if (fci->f->dd_fcrport_size)
                                memset(rport->dd_data, 0,
@@ -2784,7 +2793,6 @@ void
 fc_remote_port_delete(struct fc_rport  *rport)
 {
        struct Scsi_Host *shost = rport_to_shost(rport);
-       struct fc_internal *i = to_fc_internal(shost->transportt);
        int timeout = rport->dev_loss_tmo;
        unsigned long flags;
 
@@ -2830,7 +2838,7 @@ fc_remote_port_delete(struct fc_rport  *rport)
 
        /* see if we need to kill io faster than waiting for device loss */
        if ((rport->fast_io_fail_tmo != -1) &&
-           (rport->fast_io_fail_tmo < timeout) && (i->f->terminate_rport_io))
+           (rport->fast_io_fail_tmo < timeout))
                fc_queue_devloss_work(shost, &rport->fail_io_work,
                                        rport->fast_io_fail_tmo * HZ);
 
@@ -2906,7 +2914,8 @@ fc_remote_port_rolechg(struct fc_rport  *rport, u32 roles)
                        fc_flush_devloss(shost);
 
                spin_lock_irqsave(shost->host_lock, flags);
-               rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
+               rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
+                                 FC_RPORT_DEVLOSS_PENDING);
                spin_unlock_irqrestore(shost->host_lock, flags);
 
                /* ensure any stgt delete functions are done */
@@ -3001,6 +3010,17 @@ fc_timeout_deleted_rport(struct work_struct *work)
        rport->supported_classes = FC_COS_UNSPECIFIED;
        rport->roles = FC_PORT_ROLE_UNKNOWN;
        rport->port_state = FC_PORTSTATE_NOTPRESENT;
+       rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
+
+       /*
+        * Pre-emptively kill I/O rather than waiting for the work queue
+        * item to teardown the starget. (FCOE libFC folks prefer this
+        * and to have the rport_port_id still set when it's done).
+        */
+       spin_unlock_irqrestore(shost->host_lock, flags);
+       fc_terminate_rport_io(rport);
+
+       BUG_ON(rport->port_state != FC_PORTSTATE_NOTPRESENT);
 
        /* remove the identifiers that aren't used in the consisting binding */
        switch (fc_host->tgtid_bind_type) {
@@ -3025,9 +3045,6 @@ fc_timeout_deleted_rport(struct work_struct *work)
         * went away and didn't come back - we'll remove
         * all attached scsi devices.
         */
-       spin_unlock_irqrestore(shost->host_lock, flags);
-
-       scsi_target_unblock(&rport->dev);
        fc_queue_work(shost, &rport->stgt_delete_work);
 }
 
@@ -3043,13 +3060,12 @@ fc_timeout_fail_rport_io(struct work_struct *work)
 {
        struct fc_rport *rport =
                container_of(work, struct fc_rport, fail_io_work.work);
-       struct Scsi_Host *shost = rport_to_shost(rport);
-       struct fc_internal *i = to_fc_internal(shost->transportt);
 
        if (rport->port_state != FC_PORTSTATE_BLOCKED)
                return;
 
-       i->f->terminate_rport_io(rport);
+       rport->flags |= FC_RPORT_FAST_FAIL_TIMEDOUT;
+       fc_terminate_rport_io(rport);
 }
 
 /**
@@ -3148,8 +3164,8 @@ fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev,
        device_initialize(dev);                 /* takes self reference */
        dev->parent = get_device(pdev);         /* takes parent reference */
        dev->release = fc_vport_dev_release;
-       sprintf(dev->bus_id, "vport-%d:%d-%d",
-               shost->host_no, channel, vport->number);
+       dev_set_name(dev, "vport-%d:%d-%d",
+                    shost->host_no, channel, vport->number);
        transport_setup_device(dev);
 
        error = device_add(dev);
@@ -3172,19 +3188,19 @@ fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev,
         */
        if (pdev != &shost->shost_gendev) {
                error = sysfs_create_link(&shost->shost_gendev.kobj,
-                                &dev->kobj, dev->bus_id);
+                                &dev->kobj, dev_name(dev));
                if (error)
                        printk(KERN_ERR
                                "%s: Cannot create vport symlinks for "
                                "%s, err=%d\n",
-                               __func__, dev->bus_id, error);
+                               __func__, dev_name(dev), error);
        }
        spin_lock_irqsave(shost->host_lock, flags);
        vport->flags &= ~FC_VPORT_CREATING;
        spin_unlock_irqrestore(shost->host_lock, flags);
 
        dev_printk(KERN_NOTICE, pdev,
-                       "%s created via shost%d channel %d\n", dev->bus_id,
+                       "%s created via shost%d channel %d\n", dev_name(dev),
                        shost->host_no, channel);
 
        *ret_vport = vport;
@@ -3281,7 +3297,7 @@ fc_vport_terminate(struct fc_vport *vport)
                return stat;
 
        if (dev->parent != &shost->shost_gendev)
-               sysfs_remove_link(&shost->shost_gendev.kobj, dev->bus_id);
+               sysfs_remove_link(&shost->shost_gendev.kobj, dev_name(dev));
        transport_remove_device(dev);
        device_del(dev);
        transport_destroy_device(dev);
@@ -3313,7 +3329,7 @@ fc_vport_sched_delete(struct work_struct *work)
                dev_printk(KERN_ERR, vport->dev.parent,
                        "%s: %s could not be deleted created via "
                        "shost%d channel %d - error %d\n", __func__,
-                       vport->dev.bus_id, vport->shost->host_no,
+                       dev_name(&vport->dev), vport->shost->host_no,
                        vport->channel, stat);
 }