diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-22 15:55:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-22 15:55:29 -0400 |
commit | 424a6f6ef990b7e9f56f6627bfc6c46b493faeb4 (patch) | |
tree | 0028356ed8003495fbbe1f716f359e3c8ebc35b6 /drivers/scsi/fcoe | |
parent | 1ab142d499294b844ecc81e8004db4ce029b0b61 (diff) | |
parent | cd8df932d894f3128c884e3ae1b2b484540513db (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.c | 167 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe.h | 3 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe_transport.c | 4 |
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 | ||
392 | out_nomod: | 407 | out_putmod: |
393 | module_put(THIS_MODULE); | 408 | module_put(THIS_MODULE); |
394 | out: | 409 | out: |
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 | */ | ||
402 | static 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 | */ | ||
420 | static 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 | */ | ||
429 | static 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 | */ | ||
729 | static 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 | ||
1076 | out_lp_destroy: | 1137 | out_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 | */ |
78 | struct fcoe_interface { | 76 | struct 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 | } |