Merge tag 'fcoe' into for-linus
authorJames Bottomley <JBottomley@Parallels.com>
Sat, 13 Jul 2013 04:22:56 +0000 (08:22 +0400)
committerJames Bottomley <JBottomley@Parallels.com>
Sat, 13 Jul 2013 04:22:56 +0000 (08:22 +0400)
A short series of fixes to libfc, libfcoe and fcoe.
Most patches fix formatting problems, one changes
the behavior of which discovered ports can/will be
logged into and another fixes a memory leak.

drivers/scsi/fcoe/fcoe.c
drivers/scsi/fcoe/fcoe_ctlr.c
drivers/scsi/fcoe/fcoe_sysfs.c
drivers/scsi/fcoe/fcoe_transport.c
drivers/scsi/libfc/fc_exch.c
drivers/scsi/libfc/fc_rport.c

index 32ae6c6..3336e57 100644 (file)
@@ -774,7 +774,6 @@ static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev)
        struct fcoe_port *port;
        struct net_device *realdev;
        int rc;
-       struct netdev_fcoe_hbainfo fdmi;
 
        port = lport_priv(lport);
        fcoe = port->priv;
@@ -788,9 +787,13 @@ static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev)
                return;
 
        if (realdev->netdev_ops->ndo_fcoe_get_hbainfo) {
-               memset(&fdmi, 0, sizeof(fdmi));
+               struct netdev_fcoe_hbainfo *fdmi;
+               fdmi = kzalloc(sizeof(*fdmi), GFP_KERNEL);
+               if (!fdmi)
+                       return;
+
                rc = realdev->netdev_ops->ndo_fcoe_get_hbainfo(realdev,
-                                                              &fdmi);
+                                                              fdmi);
                if (rc) {
                        printk(KERN_INFO "fcoe: Failed to retrieve FDMI "
                                        "information from netdev.\n");
@@ -800,38 +803,39 @@ static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev)
                snprintf(fc_host_serial_number(lport->host),
                         FC_SERIAL_NUMBER_SIZE,
                         "%s",
-                        fdmi.serial_number);
+                        fdmi->serial_number);
                snprintf(fc_host_manufacturer(lport->host),
                         FC_SERIAL_NUMBER_SIZE,
                         "%s",
-                        fdmi.manufacturer);
+                        fdmi->manufacturer);
                snprintf(fc_host_model(lport->host),
                         FC_SYMBOLIC_NAME_SIZE,
                         "%s",
-                        fdmi.model);
+                        fdmi->model);
                snprintf(fc_host_model_description(lport->host),
                         FC_SYMBOLIC_NAME_SIZE,
                         "%s",
-                        fdmi.model_description);
+                        fdmi->model_description);
                snprintf(fc_host_hardware_version(lport->host),
                         FC_VERSION_STRING_SIZE,
                         "%s",
-                        fdmi.hardware_version);
+                        fdmi->hardware_version);
                snprintf(fc_host_driver_version(lport->host),
                         FC_VERSION_STRING_SIZE,
                         "%s",
-                        fdmi.driver_version);
+                        fdmi->driver_version);
                snprintf(fc_host_optionrom_version(lport->host),
                         FC_VERSION_STRING_SIZE,
                         "%s",
-                        fdmi.optionrom_version);
+                        fdmi->optionrom_version);
                snprintf(fc_host_firmware_version(lport->host),
                         FC_VERSION_STRING_SIZE,
                         "%s",
-                        fdmi.firmware_version);
+                        fdmi->firmware_version);
 
                /* Enable FDMI lport states */
                lport->fdmi_enabled = 1;
+               kfree(fdmi);
        } else {
                lport->fdmi_enabled = 0;
                printk(KERN_INFO "fcoe: No FDMI support.\n");
index 795843d..203415e 100644 (file)
@@ -2090,7 +2090,11 @@ static struct fc_rport_operations fcoe_ctlr_vn_rport_ops = {
  */
 static void fcoe_ctlr_disc_stop_locked(struct fc_lport *lport)
 {
+       struct fc_rport_priv *rdata;
+
        mutex_lock(&lport->disc.disc_mutex);
+       list_for_each_entry_rcu(rdata, &lport->disc.rports, peers)
+               lport->tt.rport_logoff(rdata);
        lport->disc.disc_callback = NULL;
        mutex_unlock(&lport->disc.disc_mutex);
 }
index 8c05ae0..c9382d6 100644 (file)
@@ -507,7 +507,7 @@ static const struct attribute_group *fcoe_fcf_attr_groups[] = {
        NULL,
 };
 
-struct bus_type fcoe_bus_type;
+static struct bus_type fcoe_bus_type;
 
 static int fcoe_bus_match(struct device *dev,
                          struct device_driver *drv)
@@ -541,25 +541,25 @@ static void fcoe_fcf_device_release(struct device *dev)
        kfree(fcf);
 }
 
-struct device_type fcoe_ctlr_device_type = {
+static struct device_type fcoe_ctlr_device_type = {
        .name = "fcoe_ctlr",
        .groups = fcoe_ctlr_attr_groups,
        .release = fcoe_ctlr_device_release,
 };
 
-struct device_type fcoe_fcf_device_type = {
+static struct device_type fcoe_fcf_device_type = {
        .name = "fcoe_fcf",
        .groups = fcoe_fcf_attr_groups,
        .release = fcoe_fcf_device_release,
 };
 
-struct bus_attribute fcoe_bus_attr_group[] = {
+static struct bus_attribute fcoe_bus_attr_group[] = {
        __ATTR(ctlr_create, S_IWUSR, NULL, fcoe_ctlr_create_store),
        __ATTR(ctlr_destroy, S_IWUSR, NULL, fcoe_ctlr_destroy_store),
        __ATTR_NULL
 };
 
-struct bus_type fcoe_bus_type = {
+static struct bus_type fcoe_bus_type = {
        .name = "fcoe",
        .match = &fcoe_bus_match,
        .bus_attrs = fcoe_bus_attr_group,
@@ -569,7 +569,7 @@ struct bus_type fcoe_bus_type = {
  * fcoe_ctlr_device_flush_work() - Flush a FIP ctlr's workqueue
  * @ctlr: Pointer to the FIP ctlr whose workqueue is to be flushed
  */
-void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr)
+static void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr)
 {
        if (!fcoe_ctlr_work_q(ctlr)) {
                printk(KERN_ERR
@@ -590,8 +590,8 @@ void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr)
  * Return value:
  *     1 on success / 0 already queued / < 0 for error
  */
-int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr,
-                              struct work_struct *work)
+static int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr,
+                                      struct work_struct *work)
 {
        if (unlikely(!fcoe_ctlr_work_q(ctlr))) {
                printk(KERN_ERR
@@ -609,7 +609,7 @@ int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr,
  * fcoe_ctlr_device_flush_devloss() - Flush a FIP ctlr's devloss workqueue
  * @ctlr: Pointer to FIP ctlr whose workqueue is to be flushed
  */
-void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr)
+static void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr)
 {
        if (!fcoe_ctlr_devloss_work_q(ctlr)) {
                printk(KERN_ERR
@@ -631,9 +631,9 @@ void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr)
  * Return value:
  *     1 on success / 0 already queued / < 0 for error
  */
-int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr,
-                                      struct delayed_work *work,
-                                      unsigned long delay)
+static int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr,
+                                              struct delayed_work *work,
+                                              unsigned long delay)
 {
        if (unlikely(!fcoe_ctlr_devloss_work_q(ctlr))) {
                printk(KERN_ERR
index f3a5a53..f1ae5ed 100644 (file)
@@ -180,24 +180,10 @@ void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
 {
        struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
        struct net_device *netdev = fcoe_get_netdev(fip->lp);
-       struct fcoe_fc_els_lesb *fcoe_lesb;
-       struct fc_els_lesb fc_lesb;
-
-       __fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
-       fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
-
-       ctlr_dev->lesb.lesb_link_fail =
-               ntohl(fcoe_lesb->lesb_link_fail);
-       ctlr_dev->lesb.lesb_vlink_fail =
-               ntohl(fcoe_lesb->lesb_vlink_fail);
-       ctlr_dev->lesb.lesb_miss_fka =
-               ntohl(fcoe_lesb->lesb_miss_fka);
-       ctlr_dev->lesb.lesb_symb_err =
-               ntohl(fcoe_lesb->lesb_symb_err);
-       ctlr_dev->lesb.lesb_err_block =
-               ntohl(fcoe_lesb->lesb_err_block);
-       ctlr_dev->lesb.lesb_fcs_error =
-               ntohl(fcoe_lesb->lesb_fcs_error);
+       struct fc_els_lesb *fc_lesb;
+
+       fc_lesb = (struct fc_els_lesb *)(&ctlr_dev->lesb);
+       __fcoe_get_lesb(fip->lp, fc_lesb, netdev);
 }
 EXPORT_SYMBOL_GPL(fcoe_ctlr_get_lesb);
 
@@ -721,7 +707,6 @@ ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
 {
        struct net_device *netdev = NULL;
        struct fcoe_transport *ft = NULL;
-       struct fcoe_ctlr_device *ctlr_dev = NULL;
        int rc = 0;
        int err;
 
@@ -768,9 +753,8 @@ ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
                goto out_putdev;
        }
 
-       LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n",
-                             ft->name, (ctlr_dev) ? "succeeded" : "failed",
-                             netdev->name);
+       LIBFCOE_TRANSPORT_DBG("transport %s succeeded to create fcoe on %s.\n",
+                             ft->name, netdev->name);
 
 out_putdev:
        dev_put(netdev);
index 8b928c6..5879929 100644 (file)
@@ -337,7 +337,7 @@ static void fc_exch_release(struct fc_exch *ep)
  * fc_exch_timer_cancel() - cancel exch timer
  * @ep:                The exchange whose timer to be canceled
  */
-static inline  void fc_exch_timer_cancel(struct fc_exch *ep)
+static inline void fc_exch_timer_cancel(struct fc_exch *ep)
 {
        if (cancel_delayed_work(&ep->timeout_work)) {
                FC_EXCH_DBG(ep, "Exchange timer canceled\n");
@@ -1567,7 +1567,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
                    fc_exch_rctl_name(fh->fh_r_ctl));
 
        if (cancel_delayed_work_sync(&ep->timeout_work)) {
-               FC_EXCH_DBG(ep, "Exchange timer canceled\n");
+               FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n");
                fc_exch_release(ep);    /* release from pending timer hold */
        }
 
index 6bbb944..c710d90 100644 (file)
@@ -926,6 +926,20 @@ err:
        kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
 }
 
+static bool
+fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata)
+{
+       if (rdata->ids.roles == FC_PORT_ROLE_UNKNOWN)
+               return true;
+       if ((rdata->ids.roles & FC_PORT_ROLE_FCP_TARGET) &&
+           (lport->service_params & FCP_SPPF_INIT_FCN))
+               return true;
+       if ((rdata->ids.roles & FC_PORT_ROLE_FCP_INITIATOR) &&
+           (lport->service_params & FCP_SPPF_TARG_FCN))
+               return true;
+       return false;
+}
+
 /**
  * fc_rport_enter_plogi() - Send Port Login (PLOGI) request
  * @rdata: The remote port to send a PLOGI to
@@ -938,6 +952,12 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
        struct fc_lport *lport = rdata->local_port;
        struct fc_frame *fp;
 
+       if (!fc_rport_compatible_roles(lport, rdata)) {
+               FC_RPORT_DBG(rdata, "PLOGI suppressed for incompatible role\n");
+               fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
+               return;
+       }
+
        FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n",
                     fc_rport_state(rdata));
 
@@ -1646,6 +1666,13 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
                rjt_data.explan = ELS_EXPL_NONE;
                goto reject;
        }
+       if (!fc_rport_compatible_roles(lport, rdata)) {
+               FC_RPORT_DBG(rdata, "Received PLOGI for incompatible role\n");
+               mutex_unlock(&rdata->rp_mutex);
+               rjt_data.reason = ELS_RJT_LOGIC;
+               rjt_data.explan = ELS_EXPL_NONE;
+               goto reject;
+       }
 
        /*
         * Get session payload size from incoming PLOGI.