From: Mike Christie <[EMAIL PROTECTED]>

This is a first stab at removing the libfc dummy rport code
and private remote port code in other drivers. I am just sending the
fc class code to make sure I have the basic idea right.

JamesS had presented two possible solutions for how to deal
with rports that exist and how to resolve dd_data state:
http://www.open-fcoe.org/pipermail/devel/2008-July/000401.html

In one proposal we could have the LLD call some fc class
helpers to find existing rports by wwpn/wwnn. And the
alternative, is to try and make fc_remote_port_add figure
things out and call back into the LLD.

I went with the former, because some of the issues like how to handle
if the class finds a rport with a matching port_id that is not in the
blocked state gets complicated from a callback.

This patch was made over scsi-misc, becuase there are some patches
in there not in the fcoe tree. You can pull his tree into the fcoe
one and apply the patch.

Signed-off-by: Mike Christie <[EMAIL PROTECTED]>
---
 drivers/scsi/scsi_transport_fc.c |  435 ++++++++++++++++++++++----------------
 include/scsi/scsi_transport_fc.h |   12 +-
 2 files changed, 263 insertions(+), 184 deletions(-)

diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index c276d11..a1311b2 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -144,6 +144,7 @@ static struct {
        { FC_PORTSTATE_ERROR,           "Error" },
        { FC_PORTSTATE_LOOPBACK,        "Loopback" },
        { FC_PORTSTATE_DELETED,         "Deleted" },
+       { FC_PORTSTATE_ROGUE,           "Rogue" },
 };
 fc_enum_name_search(port_state, fc_port_state, fc_port_state_names)
 #define FC_PORTSTATE_MAX_NAMELEN       20
@@ -387,6 +388,7 @@ static int fc_host_setup(struct transport_container *tc, 
struct device *dev,
 
        INIT_LIST_HEAD(&fc_host->rports);
        INIT_LIST_HEAD(&fc_host->rport_bindings);
+       INIT_LIST_HEAD(&fc_host->rogue_rports);
        INIT_LIST_HEAD(&fc_host->vports);
        fc_host->next_rport_number = 0;
        fc_host->next_target_id = 0;
@@ -1518,7 +1520,7 @@ store_fc_private_host_tgtid_bind_type(struct device *dev,
                while (!list_empty(&fc_host_rport_bindings(shost))) {
                        get_list_head_entry(rport,
                                &fc_host_rport_bindings(shost), peers);
-                       list_del(&rport->peers);
+                       list_del_init(&rport->peers);
                        rport->port_state = FC_PORTSTATE_DELETED;
                        fc_queue_work(shost, &rport->rport_delete_work);
                }
@@ -2294,14 +2296,14 @@ fc_remove_host(struct Scsi_Host *shost)
        /* Remove any remote ports */
        list_for_each_entry_safe(rport, next_rport,
                        &fc_host->rports, peers) {
-               list_del(&rport->peers);
+               list_del_init(&rport->peers);
                rport->port_state = FC_PORTSTATE_DELETED;
                fc_queue_work(shost, &rport->rport_delete_work);
        }
 
        list_for_each_entry_safe(rport, next_rport,
                        &fc_host->rport_bindings, peers) {
-               list_del(&rport->peers);
+               list_del_init(&rport->peers);
                rport->port_state = FC_PORTSTATE_DELETED;
                fc_queue_work(shost, &rport->rport_delete_work);
        }
@@ -2414,51 +2416,41 @@ fc_rport_final_delete(struct work_struct *work)
        transport_remove_device(dev);
        device_del(dev);
        transport_destroy_device(dev);
-       put_device(&shost->shost_gendev);       /* for fc_host->rport list */
-       put_device(dev);                        /* for self-reference */
+       fc_remote_port_free(rport);
 }
 
-
 /**
- * fc_rport_create - allocates and creates a remote FC port.
+ * fc_remote_port_alloc - allocates a remote FC port.
  * @shost:     scsi host the remote port is connected to.
  * @channel:   Channel on shost port connected to.
- * @ids:       The world wide names, fc address, and FC4 port
- *             roles for the remote port.
  *
- * Allocates and creates the remoter port structure, including the
- * class and sysfs creation.
+ * Allocates the remoter port structure. It has no binding
+ * and no sysfs representation at this time. It is just used to send
+ * discovery requests through.
  *
  * Notes:
  *     This routine assumes no locks are held on entry.
  */
-static struct fc_rport *
-fc_rport_create(struct Scsi_Host *shost, int channel,
-       struct fc_rport_identifiers  *ids)
+struct fc_rport *fc_remote_port_alloc(struct Scsi_Host *shost, int channel)
 {
        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
        struct fc_internal *fci = to_fc_internal(shost->transportt);
        struct fc_rport *rport;
        struct device *dev;
        unsigned long flags;
-       int error;
-       size_t size;
 
-       size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size);
-       rport = kzalloc(size, GFP_KERNEL);
-       if (unlikely(!rport)) {
+       rport = kzalloc(sizeof(struct fc_rport) + fci->f->dd_fcrport_size,
+                       GFP_KERNEL);
+       if (!rport) {
                printk(KERN_ERR "%s: allocation failure\n", __func__);
                return NULL;
        }
 
        rport->maxframe_size = -1;
        rport->supported_classes = FC_COS_UNSPECIFIED;
+       rport->roles = FC_PORT_ROLE_UNKNOWN;
        rport->dev_loss_tmo = fc_dev_loss_tmo;
-       memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name));
-       memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name));
-       rport->port_id = ids->port_id;
-       rport->roles = ids->roles;
-       rport->port_state = FC_PORTSTATE_ONLINE;
+       rport->port_state = FC_PORTSTATE_ROGUE;
        if (fci->f->dd_fcrport_size)
                rport->dd_data = &rport[1];
        rport->channel = channel;
@@ -2470,59 +2462,181 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
        INIT_WORK(&rport->stgt_delete_work, fc_starget_delete);
        INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete);
 
+       dev = &rport->dev;
+       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);
+       device_initialize(dev);                 /* takes self reference */
+
+       spin_lock_irqsave(shost->host_lock, flags);
+       rport->number = fc_host->next_rport_number++;
+       list_add_tail(&rport->peers, &fc_host->rogue_rports);
+       get_device(&shost->shost_gendev); /* for fc_host->*rports list */
+       spin_unlock_irqrestore(shost->host_lock, flags);
+       return rport;
+}
+EXPORT_SYMBOL_GPL(fc_remote_port_alloc);
+
+/**
+ * fc_remote_port_free - drop reference from allocation
+ * @rport:     remote port
+ *
+ * This should be called if the LLD has not called
+ * add on the rport and wishes to free the resources for the rogue port.
+ * For example if discovery failed, then the LLD should call this
+ * function to free the rport that was allocated.
+ */
+void fc_remote_port_free(struct fc_rport *rport)
+{
+       struct Scsi_Host *shost = rport_to_shost(rport);
+       unsigned long flags;
+
+       spin_lock_irqsave(shost->host_lock, flags);
+       if (!list_empty(&rport->peers))
+               list_del(&rport->peers);
+       /* for fc_host->rogue_rports list */
+       put_device(&rport->dev);
+       spin_unlock_irqrestore(shost->host_lock, flags);
+
+       /* for self-reference */
+       put_device(&rport->dev);
+}
+EXPORT_SYMBOL_GPL(fc_remote_port_free);
+
+static struct fc_rport *
+rport_lookup(struct fc_host_attrs *fc_host, struct list_head *list, int 
channel,
+            enum fc_tgtid_binding_type tgtid_bind_type,
+            struct fc_rport_identifiers *ids)
+{
+       struct fc_rport *rport;
+
+       list_for_each_entry(rport, list, peers) {
+               if (rport->channel != channel)
+                       continue;
+
+               switch (tgtid_bind_type) {
+               case FC_TGTID_BIND_BY_WWPN:
+               case FC_TGTID_BIND_NONE:
+                       if (rport->port_name != ids->port_name)
+                               continue;
+                       break;
+               case FC_TGTID_BIND_BY_WWNN:
+                       if (rport->node_name != ids->node_name)
+                               continue;
+                       break;
+               case FC_TGTID_BIND_BY_ID:
+                       if (rport->port_id != ids->port_id)
+                               continue;
+                       break;
+               default:
+                       continue;
+               }
+               get_device(&rport->dev);
+               return rport;
+       }
+       return NULL;
+}
+
+/**
+ * fc_remote_port_lookup - lookup a remote port by id
+ * @shost:             scsi host
+ * @channel:           channel
+ * @tgtid_bind_type:   bind type
+ * @id:                        port id
+ *
+ * If a the port is found, it will be returned with a refcount on it.
+ * The caller must do a put_device on the rport when it is done.
+ * This function will check all rports lists, so the caller must
+ * check the rport port_state before processing.
+ *
+ * Caller must hold host lock.
+ */
+static struct fc_rport *
+__fc_remote_port_lookup(struct Scsi_Host *shost, int channel,
+                       enum fc_tgtid_binding_type tgtid_bind_type,
+                       struct fc_rport_identifiers *ids)
+{
+       struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+       struct fc_rport *rport;
+
+       rport = rport_lookup(fc_host, &fc_host->rports, channel,
+                            tgtid_bind_type, ids);
+       if (rport)
+               return rport;
+
+       rport = rport_lookup(fc_host, &fc_host->rport_bindings, channel,
+                            tgtid_bind_type, ids);
+       if (rport)
+               return rport;
+
+       return rport_lookup(fc_host, &fc_host->rogue_rports, channel,
+                           tgtid_bind_type, ids);
+}
+
+struct fc_rport *
+fc_remote_port_lookup(struct Scsi_Host *shost, int channel,
+                     enum fc_tgtid_binding_type tgtid_bind_type,
+                     struct fc_rport_identifiers *ids)
+{
+       struct fc_rport *rport;
+       unsigned long flags;
+
+       spin_lock_irqsave(shost->host_lock, flags);
+       rport = __fc_remote_port_lookup(shost, channel, tgtid_bind_type, ids);
+       spin_unlock_irqrestore(shost->host_lock, flags);
+       return rport;
+}
+EXPORT_SYMBOL_GPL(fc_remote_port_lookup);
+
+static int remote_port_add(struct fc_rport *rport,
+                          struct fc_rport_identifiers *ids)
+{
+       struct Scsi_Host *shost = rport_to_shost(rport);
+       struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+       struct device *dev;
+       unsigned long flags;
+       int error;
+
        spin_lock_irqsave(shost->host_lock, flags);
+       memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name));
+       memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name));
+       rport->port_id = ids->port_id;
+       rport->roles = ids->roles;
 
        rport->number = fc_host->next_rport_number++;
        if (rport->roles & FC_PORT_ROLE_FCP_TARGET)
                rport->scsi_target_id = fc_host->next_target_id++;
        else
                rport->scsi_target_id = -1;
-       list_add_tail(&rport->peers, &fc_host->rports);
-       get_device(&shost->shost_gendev);       /* for fc_host->rport list */
-
+       list_move_tail(&rport->peers, &fc_host->rports);
        spin_unlock_irqrestore(shost->host_lock, flags);
 
        dev = &rport->dev;
-       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);
-       transport_setup_device(dev);
-
        error = device_add(dev);
        if (error) {
                printk(KERN_ERR "FC Remote Port device_add failed\n");
-               goto delete_rport;
+               put_device(&shost->shost_gendev);
+               return error;
        }
-       transport_add_device(dev);
-       transport_configure_device(dev);
+
+       transport_register_device(dev);
 
        if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
                /* initiate a scan of the target */
                rport->flags |= FC_RPORT_SCAN_PENDING;
                scsi_queue_work(shost, &rport->scan_work);
        }
-
-       return rport;
-
-delete_rport:
-       transport_destroy_device(dev);
-       spin_lock_irqsave(shost->host_lock, flags);
-       list_del(&rport->peers);
-       put_device(&shost->shost_gendev);       /* for fc_host->rport list */
-       spin_unlock_irqrestore(shost->host_lock, flags);
-       put_device(dev->parent);
-       kfree(rport);
-       return NULL;
+       return 0;
 }
 
 /**
  * fc_remote_port_add - notify fc transport of the existence of a remote FC 
port.
- * @shost:     scsi host the remote port is connected to.
- * @channel:   Channel on shost port connected to.
- * @ids:       The world wide names, fc address, and FC4 port
- *             roles for the remote port.
+ * @shost:             scsi host the remote port is connected to.
+ * @rogue_rport:       optional rogue rport.
+ * @channel:           Channel on shost port connected to.
+ * @ids:               The world wide names, fc address, and FC4 port
+ *                     roles for the remote port.
  *
  * The LLDD calls this routine to notify the transport of the existence
  * of a remote port. The LLDD provides the unique identifiers (wwpn,wwn)
@@ -2552,157 +2666,102 @@ delete_rport:
  *
  * Should not be called from interrupt context.
  *
+ * The caller should have resolved rogue with active or deleted
+ * rports before calling.
+ *
  * Notes:
  *     This routine assumes no locks are held on entry.
  */
 struct fc_rport *
 fc_remote_port_add(struct Scsi_Host *shost, int channel,
-       struct fc_rport_identifiers  *ids)
+                  struct fc_rport *rogue_rport,
+                  struct fc_rport_identifiers  *ids)
 {
        struct fc_internal *fci = to_fc_internal(shost->transportt);
        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
        struct fc_rport *rport;
        unsigned long flags;
-       int match = 0;
 
        /* ensure any stgt delete functions are done */
        fc_flush_work(shost);
 
-       /*
-        * Search the list of "active" rports, for an rport that has been
-        * deleted, but we've held off the real delete while the target
-        * is in a "blocked" state.
-        */
        spin_lock_irqsave(shost->host_lock, flags);
+       rport = __fc_remote_port_lookup(shost, channel,
+                                       fc_host->tgtid_bind_type, ids);
+       if (rport) {
+               switch (rport->port_state) {
+               /*
+                * Found rport on the list of "active" rports that has been
+                * deleted, but we've held off the real delete while the target
+                * is in a "blocked" state.
+                */
+               case FC_PORTSTATE_BLOCKED:
+                       memcpy(&rport->node_name, &ids->node_name,
+                               sizeof(rport->node_name));
+                       memcpy(&rport->port_name, &ids->port_name,
+                               sizeof(rport->port_name));
+                       rport->port_id = ids->port_id;
 
-       list_for_each_entry(rport, &fc_host->rports, peers) {
-
-               if ((rport->port_state == FC_PORTSTATE_BLOCKED) &&
-                       (rport->channel == channel)) {
-
-                       switch (fc_host->tgtid_bind_type) {
-                       case FC_TGTID_BIND_BY_WWPN:
-                       case FC_TGTID_BIND_NONE:
-                               if (rport->port_name == ids->port_name)
-                                       match = 1;
-                               break;
-                       case FC_TGTID_BIND_BY_WWNN:
-                               if (rport->node_name == ids->node_name)
-                                       match = 1;
-                               break;
-                       case FC_TGTID_BIND_BY_ID:
-                               if (rport->port_id == ids->port_id)
-                                       match = 1;
-                               break;
-                       }
-
-                       if (match) {
-
-                               memcpy(&rport->node_name, &ids->node_name,
-                                       sizeof(rport->node_name));
-                               memcpy(&rport->port_name, &ids->port_name,
-                                       sizeof(rport->port_name));
-                               rport->port_id = ids->port_id;
-
-                               rport->port_state = FC_PORTSTATE_ONLINE;
-                               rport->roles = ids->roles;
-
-                               spin_unlock_irqrestore(shost->host_lock, flags);
-
-                               if (fci->f->dd_fcrport_size)
-                                       memset(rport->dd_data, 0,
-                                               fci->f->dd_fcrport_size);
+                       rport->port_state = FC_PORTSTATE_ONLINE;
+                       rport->roles = ids->roles;
 
-                               /*
-                                * If we were not a target, cancel the
-                                * io terminate and rport timers, and
-                                * we're done.
-                                *
-                                * If we were a target, but our new role
-                                * doesn't indicate a target, leave the
-                                * timers running expecting the role to
-                                * change as the target fully logs in. If
-                                * it doesn't, the target will be torn down.
-                                *
-                                * If we were a target, and our role shows
-                                * we're still a target, cancel the timers
-                                * and kick off a scan.
-                                */
-
-                               /* was a target, not in roles */
-                               if ((rport->scsi_target_id != -1) &&
-                                   (!(ids->roles & FC_PORT_ROLE_FCP_TARGET)))
-                                       return rport;
-
-                               /*
-                                * Stop the fail io and dev_loss timers.
-                                * If they flush, the port_state will
-                                * be checked and will NOOP the function.
-                                */
-                               if (!cancel_delayed_work(&rport->fail_io_work))
-                                       fc_flush_devloss(shost);
-                               if (!cancel_delayed_work(&rport->dev_loss_work))
-                                       fc_flush_devloss(shost);
-
-                               spin_lock_irqsave(shost->host_lock, flags);
-
-                               rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
-                                                 FC_RPORT_DEVLOSS_PENDING);
-
-                               /* if target, initiate a scan */
-                               if (rport->scsi_target_id != -1) {
-                                       rport->flags |= FC_RPORT_SCAN_PENDING;
-                                       scsi_queue_work(shost,
-                                                       &rport->scan_work);
-                                       spin_unlock_irqrestore(shost->host_lock,
-                                                       flags);
-                                       scsi_target_unblock(&rport->dev);
-                               } else
-                                       spin_unlock_irqrestore(shost->host_lock,
-                                                       flags);
+                       spin_unlock_irqrestore(shost->host_lock, flags);
 
+                       if (fci->f->dd_fcrport_size)
+                               memset(rport->dd_data, 0,
+                                       fci->f->dd_fcrport_size);
+
+                       /*
+                        * If we were not a target, cancel the
+                        * io terminate and rport timers, and
+                        * we're done.
+                        *
+                        * If we were a target, but our new role
+                        * doesn't indicate a target, leave the
+                        * timers running expecting the role to
+                        * change as the target fully logs in. If
+                        * it doesn't, the target will be torn down.
+                        *
+                        * If we were a target, and our role shows
+                        * we're still a target, cancel the timers
+                        * and kick off a scan.
+                        */
+
+                       /* was a target, not in roles */
+                       if ((rport->scsi_target_id != -1) &&
+                           (!(ids->roles & FC_PORT_ROLE_FCP_TARGET)))
                                return rport;
-                       }
-               }
-       }
 
-       /*
-        * Search the bindings array
-        * Note: if never a FCP target, you won't be on this list
-        */
-       if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) {
+                       /*
+                        * Stop the fail io and dev_loss timers.
+                        * If they flush, the port_state will
+                        * be checked and will NOOP the function.
+                        */
+                       if (!cancel_delayed_work(&rport->fail_io_work))
+                               fc_flush_devloss(shost);
+                       if (!cancel_delayed_work(&rport->dev_loss_work))
+                               fc_flush_devloss(shost);
 
-               /* search for a matching consistent binding */
+                       spin_lock_irqsave(shost->host_lock, flags);
 
-               list_for_each_entry(rport, &fc_host->rport_bindings,
-                                       peers) {
-                       if (rport->channel != channel)
-                               continue;
+                       rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
+                                         FC_RPORT_DEVLOSS_PENDING);
 
-                       switch (fc_host->tgtid_bind_type) {
-                       case FC_TGTID_BIND_BY_WWPN:
-                               if (rport->port_name == ids->port_name)
-                                       match = 1;
-                               break;
-                       case FC_TGTID_BIND_BY_WWNN:
-                               if (rport->node_name == ids->node_name)
-                                       match = 1;
-                               break;
-                       case FC_TGTID_BIND_BY_ID:
-                               if (rport->port_id == ids->port_id)
-                                       match = 1;
-                               break;
-                       case FC_TGTID_BIND_NONE: /* to keep compiler happy */
-                               break;
-                       }
+                       /* if target, initiate a scan */
+                       if (rport->scsi_target_id != -1) {
+                               rport->flags |= FC_RPORT_SCAN_PENDING;
+                               scsi_queue_work(shost, &rport->scan_work);
+                               spin_unlock_irqrestore(shost->host_lock, flags);
+                               scsi_target_unblock(&rport->dev);
+                       } else
+                               spin_unlock_irqrestore(shost->host_lock, flags);
 
-                       if (match) {
-                               list_move_tail(&rport->peers, &fc_host->rports);
+                       return rport;
+               /* must have been on rport_bindings */
+               case FC_PORTSTATE_NOTPRESENT:
+                       if (fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE)
                                break;
-                       }
-               }
 
-               if (match) {
                        memcpy(&rport->node_name, &ids->node_name,
                                sizeof(rport->node_name));
                        memcpy(&rport->port_name, &ids->port_name,
@@ -2726,13 +2785,26 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
                                spin_unlock_irqrestore(shost->host_lock, flags);
 
                        return rport;
+               /* new rport */
+               default:
+                       break;
                }
        }
-
        spin_unlock_irqrestore(shost->host_lock, flags);
 
        /* No consistent binding found - create new remote port entry */
-       rport = fc_rport_create(shost, channel, ids);
+       if (rogue_rport)
+               rport = rogue_rport;
+       else {
+               rport = fc_remote_port_alloc(shost, channel);
+               if (!rport)
+                       return NULL;
+       }
+
+       if (remote_port_add(rport, ids)) {
+               fc_remote_port_free(rport);
+               return NULL;
+       }
 
        return rport;
 }
@@ -2980,7 +3052,7 @@ fc_timeout_deleted_rport(struct work_struct *work)
 
        if ((fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) ||
            (rport->scsi_target_id == -1)) {
-               list_del(&rport->peers);
+               list_del_init(&rport->peers);
                rport->port_state = FC_PORTSTATE_DELETED;
                dev_printk(KERN_ERR, &rport->dev,
                        "blocked FC remote port time out: removing"
@@ -3167,7 +3239,6 @@ fc_vport_setup(struct Scsi_Host *shost, int channel, 
struct device *pdev,
                goto delete_vport;
        }
        transport_add_device(dev);
-       transport_configure_device(dev);
 
        error = fci->f->vport_create(vport, ids->disable);
        if (error) {
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 49d8913..4d9a655 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -82,6 +82,7 @@ enum fc_port_state {
        FC_PORTSTATE_ERROR,
        FC_PORTSTATE_LOOPBACK,
        FC_PORTSTATE_DELETED,
+       FC_PORTSTATE_ROGUE,
 };
 
 
@@ -502,6 +503,7 @@ struct fc_host_attrs {
        /* internal data */
        struct list_head rports;
        struct list_head rport_bindings;
+       struct list_head rogue_rports;
        struct list_head vports;
        u32 next_rport_number;
        u32 next_target_id;
@@ -741,8 +743,14 @@ struct scsi_transport_template *fc_attach_transport(
                        struct fc_function_template *);
 void fc_release_transport(struct scsi_transport_template *);
 void fc_remove_host(struct Scsi_Host *);
-struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost,
-                       int channel, struct fc_rport_identifiers  *ids);
+struct fc_rport *fc_remote_port_lookup(struct Scsi_Host *shost, int channel,
+                               enum fc_tgtid_binding_type tgtid_bind_type,
+                               struct fc_rport_identifiers *ids);
+struct fc_rport *fc_remote_port_alloc(struct Scsi_Host *shost, int channel);
+void fc_remote_port_free(struct fc_rport *rport);
+struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost, int channel,
+                       struct fc_rport *rogue_rport,
+                       struct fc_rport_identifiers  *ids);
 void fc_remote_port_delete(struct fc_rport  *rport);
 void fc_remote_port_rolechg(struct fc_rport  *rport, u32 roles);
 int scsi_is_fc_rport(const struct device *);
-- 
1.5.5.1

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to