aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 15:55:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 15:55:29 -0400
commit424a6f6ef990b7e9f56f6627bfc6c46b493faeb4 (patch)
tree0028356ed8003495fbbe1f716f359e3c8ebc35b6 /drivers/scsi/fcoe
parent1ab142d499294b844ecc81e8004db4ce029b0b61 (diff)
parentcd8df932d894f3128c884e3ae1b2b484540513db (diff)
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
SCSI updates from James Bottomley: "The update includes the usual assortment of driver updates (lpfc, qla2xxx, qla4xxx, bfa, bnx2fc, bnx2i, isci, fcoe, hpsa) plus a huge amount of infrastructure work in the SAS library and transport class as well as an iSCSI update. There's also a new SCSI based virtio driver." * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (177 commits) [SCSI] qla4xxx: Update driver version to 5.02.00-k15 [SCSI] qla4xxx: trivial cleanup [SCSI] qla4xxx: Fix sparse warning [SCSI] qla4xxx: Add support for multiple session per host. [SCSI] qla4xxx: Export CHAP index as sysfs attribute [SCSI] scsi_transport: Export CHAP index as sysfs attribute [SCSI] qla4xxx: Add support to display CHAP list and delete CHAP entry [SCSI] iscsi_transport: Add support to display CHAP list and delete CHAP entry [SCSI] pm8001: fix endian issue with code optimization. [SCSI] pm8001: Fix possible racing condition. [SCSI] pm8001: Fix bogus interrupt state flag issue. [SCSI] ipr: update PCI ID definitions for new adapters [SCSI] qla2xxx: handle default case in qla2x00_request_firmware() [SCSI] isci: improvements in driver unloading routine [SCSI] isci: improve phy event warnings [SCSI] isci: debug, provide state-enum-to-string conversions [SCSI] scsi_transport_sas: 'enable' phys on reset [SCSI] libsas: don't recover end devices attached to disabled phys [SCSI] libsas: fixup target_port_protocols for expanders that don't report sata [SCSI] libsas: set attached device type and target protocols for local phys ...
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r--drivers/scsi/fcoe/fcoe.c167
-rw-r--r--drivers/scsi/fcoe/fcoe.h3
-rw-r--r--drivers/scsi/fcoe/fcoe_transport.c4
3 files changed, 114 insertions, 60 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index cc75cbea936b..ae7d15c44e2a 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -168,6 +168,14 @@ static struct fc_function_template fcoe_nport_fc_functions = {
168 .show_host_supported_fc4s = 1, 168 .show_host_supported_fc4s = 1,
169 .show_host_active_fc4s = 1, 169 .show_host_active_fc4s = 1,
170 .show_host_maxframe_size = 1, 170 .show_host_maxframe_size = 1,
171 .show_host_serial_number = 1,
172 .show_host_manufacturer = 1,
173 .show_host_model = 1,
174 .show_host_model_description = 1,
175 .show_host_hardware_version = 1,
176 .show_host_driver_version = 1,
177 .show_host_firmware_version = 1,
178 .show_host_optionrom_version = 1,
171 179
172 .show_host_port_id = 1, 180 .show_host_port_id = 1,
173 .show_host_supported_speeds = 1, 181 .show_host_supported_speeds = 1,
@@ -208,6 +216,14 @@ static struct fc_function_template fcoe_vport_fc_functions = {
208 .show_host_supported_fc4s = 1, 216 .show_host_supported_fc4s = 1,
209 .show_host_active_fc4s = 1, 217 .show_host_active_fc4s = 1,
210 .show_host_maxframe_size = 1, 218 .show_host_maxframe_size = 1,
219 .show_host_serial_number = 1,
220 .show_host_manufacturer = 1,
221 .show_host_model = 1,
222 .show_host_model_description = 1,
223 .show_host_hardware_version = 1,
224 .show_host_driver_version = 1,
225 .show_host_firmware_version = 1,
226 .show_host_optionrom_version = 1,
211 227
212 .show_host_port_id = 1, 228 .show_host_port_id = 1,
213 .show_host_supported_speeds = 1, 229 .show_host_supported_speeds = 1,
@@ -364,11 +380,10 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
364 if (!fcoe) { 380 if (!fcoe) {
365 FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); 381 FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n");
366 fcoe = ERR_PTR(-ENOMEM); 382 fcoe = ERR_PTR(-ENOMEM);
367 goto out_nomod; 383 goto out_putmod;
368 } 384 }
369 385
370 dev_hold(netdev); 386 dev_hold(netdev);
371 kref_init(&fcoe->kref);
372 387
373 /* 388 /*
374 * Initialize FIP. 389 * Initialize FIP.
@@ -384,54 +399,18 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
384 kfree(fcoe); 399 kfree(fcoe);
385 dev_put(netdev); 400 dev_put(netdev);
386 fcoe = ERR_PTR(err); 401 fcoe = ERR_PTR(err);
387 goto out_nomod; 402 goto out_putmod;
388 } 403 }
389 404
390 goto out; 405 goto out;
391 406
392out_nomod: 407out_putmod:
393 module_put(THIS_MODULE); 408 module_put(THIS_MODULE);
394out: 409out:
395 return fcoe; 410 return fcoe;
396} 411}
397 412
398/** 413/**
399 * fcoe_interface_release() - fcoe_port kref release function
400 * @kref: Embedded reference count in an fcoe_interface struct
401 */
402static void fcoe_interface_release(struct kref *kref)
403{
404 struct fcoe_interface *fcoe;
405 struct net_device *netdev;
406
407 fcoe = container_of(kref, struct fcoe_interface, kref);
408 netdev = fcoe->netdev;
409 /* tear-down the FCoE controller */
410 fcoe_ctlr_destroy(&fcoe->ctlr);
411 kfree(fcoe);
412 dev_put(netdev);
413 module_put(THIS_MODULE);
414}
415
416/**
417 * fcoe_interface_get() - Get a reference to a FCoE interface
418 * @fcoe: The FCoE interface to be held
419 */
420static inline void fcoe_interface_get(struct fcoe_interface *fcoe)
421{
422 kref_get(&fcoe->kref);
423}
424
425/**
426 * fcoe_interface_put() - Put a reference to a FCoE interface
427 * @fcoe: The FCoE interface to be released
428 */
429static inline void fcoe_interface_put(struct fcoe_interface *fcoe)
430{
431 kref_put(&fcoe->kref, fcoe_interface_release);
432}
433
434/**
435 * fcoe_interface_cleanup() - Clean up a FCoE interface 414 * fcoe_interface_cleanup() - Clean up a FCoE interface
436 * @fcoe: The FCoE interface to be cleaned up 415 * @fcoe: The FCoE interface to be cleaned up
437 * 416 *
@@ -478,7 +457,11 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
478 rtnl_unlock(); 457 rtnl_unlock();
479 458
480 /* Release the self-reference taken during fcoe_interface_create() */ 459 /* Release the self-reference taken during fcoe_interface_create() */
481 fcoe_interface_put(fcoe); 460 /* tear-down the FCoE controller */
461 fcoe_ctlr_destroy(fip);
462 kfree(fcoe);
463 dev_put(netdev);
464 module_put(THIS_MODULE);
482} 465}
483 466
484/** 467/**
@@ -734,6 +717,85 @@ static int fcoe_shost_config(struct fc_lport *lport, struct device *dev)
734 return 0; 717 return 0;
735} 718}
736 719
720
721/**
722 * fcoe_fdmi_info() - Get FDMI related info from net devive for SW FCoE
723 * @lport: The local port that is associated with the net device
724 * @netdev: The associated net device
725 *
726 * Must be called after fcoe_shost_config() as it will use local port mutex
727 *
728 */
729static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev)
730{
731 struct fcoe_interface *fcoe;
732 struct fcoe_port *port;
733 struct net_device *realdev;
734 int rc;
735 struct netdev_fcoe_hbainfo fdmi;
736
737 port = lport_priv(lport);
738 fcoe = port->priv;
739 realdev = fcoe->realdev;
740
741 if (!realdev)
742 return;
743
744 /* No FDMI state m/c for NPIV ports */
745 if (lport->vport)
746 return;
747
748 if (realdev->netdev_ops->ndo_fcoe_get_hbainfo) {
749 memset(&fdmi, 0, sizeof(fdmi));
750 rc = realdev->netdev_ops->ndo_fcoe_get_hbainfo(realdev,
751 &fdmi);
752 if (rc) {
753 printk(KERN_INFO "fcoe: Failed to retrieve FDMI "
754 "information from netdev.\n");
755 return;
756 }
757
758 snprintf(fc_host_serial_number(lport->host),
759 FC_SERIAL_NUMBER_SIZE,
760 "%s",
761 fdmi.serial_number);
762 snprintf(fc_host_manufacturer(lport->host),
763 FC_SERIAL_NUMBER_SIZE,
764 "%s",
765 fdmi.manufacturer);
766 snprintf(fc_host_model(lport->host),
767 FC_SYMBOLIC_NAME_SIZE,
768 "%s",
769 fdmi.model);
770 snprintf(fc_host_model_description(lport->host),
771 FC_SYMBOLIC_NAME_SIZE,
772 "%s",
773 fdmi.model_description);
774 snprintf(fc_host_hardware_version(lport->host),
775 FC_VERSION_STRING_SIZE,
776 "%s",
777 fdmi.hardware_version);
778 snprintf(fc_host_driver_version(lport->host),
779 FC_VERSION_STRING_SIZE,
780 "%s",
781 fdmi.driver_version);
782 snprintf(fc_host_optionrom_version(lport->host),
783 FC_VERSION_STRING_SIZE,
784 "%s",
785 fdmi.optionrom_version);
786 snprintf(fc_host_firmware_version(lport->host),
787 FC_VERSION_STRING_SIZE,
788 "%s",
789 fdmi.firmware_version);
790
791 /* Enable FDMI lport states */
792 lport->fdmi_enabled = 1;
793 } else {
794 lport->fdmi_enabled = 0;
795 printk(KERN_INFO "fcoe: No FDMI support.\n");
796 }
797}
798
737/** 799/**
738 * fcoe_oem_match() - The match routine for the offloaded exchange manager 800 * fcoe_oem_match() - The match routine for the offloaded exchange manager
739 * @fp: The I/O frame 801 * @fp: The I/O frame
@@ -881,9 +943,6 @@ static void fcoe_if_destroy(struct fc_lport *lport)
881 dev_uc_del(netdev, port->data_src_addr); 943 dev_uc_del(netdev, port->data_src_addr);
882 rtnl_unlock(); 944 rtnl_unlock();
883 945
884 /* Release reference held in fcoe_if_create() */
885 fcoe_interface_put(fcoe);
886
887 /* Free queued packets for the per-CPU receive threads */ 946 /* Free queued packets for the per-CPU receive threads */
888 fcoe_percpu_clean(lport); 947 fcoe_percpu_clean(lport);
889 948
@@ -1047,6 +1106,9 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
1047 goto out_lp_destroy; 1106 goto out_lp_destroy;
1048 } 1107 }
1049 1108
1109 /* Initialized FDMI information */
1110 fcoe_fdmi_info(lport, netdev);
1111
1050 /* 1112 /*
1051 * fcoe_em_alloc() and fcoe_hostlist_add() both 1113 * fcoe_em_alloc() and fcoe_hostlist_add() both
1052 * need to be atomic with respect to other changes to the 1114 * need to be atomic with respect to other changes to the
@@ -1070,7 +1132,6 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
1070 goto out_lp_destroy; 1132 goto out_lp_destroy;
1071 } 1133 }
1072 1134
1073 fcoe_interface_get(fcoe);
1074 return lport; 1135 return lport;
1075 1136
1076out_lp_destroy: 1137out_lp_destroy:
@@ -2009,20 +2070,13 @@ static void fcoe_destroy_work(struct work_struct *work)
2009{ 2070{
2010 struct fcoe_port *port; 2071 struct fcoe_port *port;
2011 struct fcoe_interface *fcoe; 2072 struct fcoe_interface *fcoe;
2012 int npiv = 0;
2013 2073
2014 port = container_of(work, struct fcoe_port, destroy_work); 2074 port = container_of(work, struct fcoe_port, destroy_work);
2015 mutex_lock(&fcoe_config_mutex); 2075 mutex_lock(&fcoe_config_mutex);
2016 2076
2017 /* set if this is an NPIV port */
2018 npiv = port->lport->vport ? 1 : 0;
2019
2020 fcoe = port->priv; 2077 fcoe = port->priv;
2021 fcoe_if_destroy(port->lport); 2078 fcoe_if_destroy(port->lport);
2022 2079 fcoe_interface_cleanup(fcoe);
2023 /* Do not tear down the fcoe interface for NPIV port */
2024 if (!npiv)
2025 fcoe_interface_cleanup(fcoe);
2026 2080
2027 mutex_unlock(&fcoe_config_mutex); 2081 mutex_unlock(&fcoe_config_mutex);
2028} 2082}
@@ -2593,12 +2647,15 @@ static int fcoe_vport_destroy(struct fc_vport *vport)
2593 struct Scsi_Host *shost = vport_to_shost(vport); 2647 struct Scsi_Host *shost = vport_to_shost(vport);
2594 struct fc_lport *n_port = shost_priv(shost); 2648 struct fc_lport *n_port = shost_priv(shost);
2595 struct fc_lport *vn_port = vport->dd_data; 2649 struct fc_lport *vn_port = vport->dd_data;
2596 struct fcoe_port *port = lport_priv(vn_port);
2597 2650
2598 mutex_lock(&n_port->lp_mutex); 2651 mutex_lock(&n_port->lp_mutex);
2599 list_del(&vn_port->list); 2652 list_del(&vn_port->list);
2600 mutex_unlock(&n_port->lp_mutex); 2653 mutex_unlock(&n_port->lp_mutex);
2601 queue_work(fcoe_wq, &port->destroy_work); 2654
2655 mutex_lock(&fcoe_config_mutex);
2656 fcoe_if_destroy(vn_port);
2657 mutex_unlock(&fcoe_config_mutex);
2658
2602 return 0; 2659 return 0;
2603} 2660}
2604 2661
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
index bcc89e639495..3c2733a12aa1 100644
--- a/drivers/scsi/fcoe/fcoe.h
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -71,8 +71,6 @@ do { \
71 * @ctlr: The FCoE controller (for FIP) 71 * @ctlr: The FCoE controller (for FIP)
72 * @oem: The offload exchange manager for all local port 72 * @oem: The offload exchange manager for all local port
73 * instances associated with this port 73 * instances associated with this port
74 * @kref: The kernel reference
75 *
76 * This structure is 1:1 with a net devive. 74 * This structure is 1:1 with a net devive.
77 */ 75 */
78struct fcoe_interface { 76struct fcoe_interface {
@@ -83,7 +81,6 @@ struct fcoe_interface {
83 struct packet_type fip_packet_type; 81 struct packet_type fip_packet_type;
84 struct fcoe_ctlr ctlr; 82 struct fcoe_ctlr ctlr;
85 struct fc_exch_mgr *oem; 83 struct fc_exch_mgr *oem;
86 struct kref kref;
87}; 84};
88 85
89#define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr) 86#define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr)
diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c
index 4d119a326d3b..710e149d41b6 100644
--- a/drivers/scsi/fcoe/fcoe_transport.c
+++ b/drivers/scsi/fcoe/fcoe_transport.c
@@ -619,8 +619,8 @@ static int libfcoe_device_notification(struct notifier_block *notifier,
619 619
620 switch (event) { 620 switch (event) {
621 case NETDEV_UNREGISTER: 621 case NETDEV_UNREGISTER:
622 printk(KERN_ERR "libfcoe_device_notification: NETDEV_UNREGISTER %s\n", 622 LIBFCOE_TRANSPORT_DBG("NETDEV_UNREGISTER %s\n",
623 netdev->name); 623 netdev->name);
624 fcoe_del_netdev_mapping(netdev); 624 fcoe_del_netdev_mapping(netdev);
625 break; 625 break;
626 } 626 }