diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 32ae6c67ea3a..3336e5754930 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -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"); diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 795843dde8ec..203415e02518 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -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); } diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c index 8c05ae017f5b..c9382d6eee78 100644 --- a/drivers/scsi/fcoe/fcoe_sysfs.c +++ b/drivers/scsi/fcoe/fcoe_sysfs.c @@ -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 diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index f3a5a53e8631..f1ae5edb2de1 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c @@ -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; + 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); + 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); diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 8b928c67e4b9..587992952b3c 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -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 */ } diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 6bbb9447b75d..c710d908fda6 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -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.