diff options
Diffstat (limited to 'drivers/scsi/bnx2fc')
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc.h | 3 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_els.c | 26 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 226 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_hwi.c | 16 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_io.c | 32 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_tgt.c | 23 |
6 files changed, 218 insertions, 108 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h index dd335a2a797..63de1c7cd0c 100644 --- a/drivers/scsi/bnx2fc/bnx2fc.h +++ b/drivers/scsi/bnx2fc/bnx2fc.h | |||
@@ -62,7 +62,7 @@ | |||
62 | #include "bnx2fc_constants.h" | 62 | #include "bnx2fc_constants.h" |
63 | 63 | ||
64 | #define BNX2FC_NAME "bnx2fc" | 64 | #define BNX2FC_NAME "bnx2fc" |
65 | #define BNX2FC_VERSION "1.0.4" | 65 | #define BNX2FC_VERSION "1.0.8" |
66 | 66 | ||
67 | #define PFX "bnx2fc: " | 67 | #define PFX "bnx2fc: " |
68 | 68 | ||
@@ -224,6 +224,7 @@ struct bnx2fc_interface { | |||
224 | struct fcoe_ctlr ctlr; | 224 | struct fcoe_ctlr ctlr; |
225 | u8 vlan_enabled; | 225 | u8 vlan_enabled; |
226 | int vlan_id; | 226 | int vlan_id; |
227 | bool enabled; | ||
227 | }; | 228 | }; |
228 | 229 | ||
229 | #define bnx2fc_from_ctlr(fip) container_of(fip, struct bnx2fc_interface, ctlr) | 230 | #define bnx2fc_from_ctlr(fip) container_of(fip, struct bnx2fc_interface, ctlr) |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c index d66dcbd0df1..fd382fe33f6 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_els.c +++ b/drivers/scsi/bnx2fc/bnx2fc_els.c | |||
@@ -391,18 +391,6 @@ void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg) | |||
391 | BNX2FC_IO_DBG(rec_req, "rec_compl: orig xid = 0x%x", orig_io_req->xid); | 391 | BNX2FC_IO_DBG(rec_req, "rec_compl: orig xid = 0x%x", orig_io_req->xid); |
392 | tgt = orig_io_req->tgt; | 392 | tgt = orig_io_req->tgt; |
393 | 393 | ||
394 | if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags)) { | ||
395 | BNX2FC_IO_DBG(rec_req, "completed" | ||
396 | "orig_io - 0x%x\n", | ||
397 | orig_io_req->xid); | ||
398 | goto rec_compl_done; | ||
399 | } | ||
400 | if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) { | ||
401 | BNX2FC_IO_DBG(rec_req, "abts in prog " | ||
402 | "orig_io - 0x%x\n", | ||
403 | orig_io_req->xid); | ||
404 | goto rec_compl_done; | ||
405 | } | ||
406 | /* Handle REC timeout case */ | 394 | /* Handle REC timeout case */ |
407 | if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &rec_req->req_flags)) { | 395 | if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &rec_req->req_flags)) { |
408 | BNX2FC_IO_DBG(rec_req, "timed out, abort " | 396 | BNX2FC_IO_DBG(rec_req, "timed out, abort " |
@@ -433,6 +421,20 @@ void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg) | |||
433 | } | 421 | } |
434 | goto rec_compl_done; | 422 | goto rec_compl_done; |
435 | } | 423 | } |
424 | |||
425 | if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags)) { | ||
426 | BNX2FC_IO_DBG(rec_req, "completed" | ||
427 | "orig_io - 0x%x\n", | ||
428 | orig_io_req->xid); | ||
429 | goto rec_compl_done; | ||
430 | } | ||
431 | if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) { | ||
432 | BNX2FC_IO_DBG(rec_req, "abts in prog " | ||
433 | "orig_io - 0x%x\n", | ||
434 | orig_io_req->xid); | ||
435 | goto rec_compl_done; | ||
436 | } | ||
437 | |||
436 | mp_req = &(rec_req->mp_req); | 438 | mp_req = &(rec_req->mp_req); |
437 | fc_hdr = &(mp_req->resp_fc_hdr); | 439 | fc_hdr = &(mp_req->resp_fc_hdr); |
438 | resp_len = mp_req->resp_len; | 440 | resp_len = mp_req->resp_len; |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 820a1840c3f..85bcc4b5596 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c | |||
@@ -22,7 +22,7 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu); | |||
22 | 22 | ||
23 | #define DRV_MODULE_NAME "bnx2fc" | 23 | #define DRV_MODULE_NAME "bnx2fc" |
24 | #define DRV_MODULE_VERSION BNX2FC_VERSION | 24 | #define DRV_MODULE_VERSION BNX2FC_VERSION |
25 | #define DRV_MODULE_RELDATE "Jun 23, 2011" | 25 | #define DRV_MODULE_RELDATE "Oct 02, 2011" |
26 | 26 | ||
27 | 27 | ||
28 | static char version[] __devinitdata = | 28 | static char version[] __devinitdata = |
@@ -56,6 +56,7 @@ static struct scsi_host_template bnx2fc_shost_template; | |||
56 | static struct fc_function_template bnx2fc_transport_function; | 56 | static struct fc_function_template bnx2fc_transport_function; |
57 | static struct fc_function_template bnx2fc_vport_xport_function; | 57 | static struct fc_function_template bnx2fc_vport_xport_function; |
58 | static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode); | 58 | static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode); |
59 | static void __bnx2fc_destroy(struct bnx2fc_interface *interface); | ||
59 | static int bnx2fc_destroy(struct net_device *net_device); | 60 | static int bnx2fc_destroy(struct net_device *net_device); |
60 | static int bnx2fc_enable(struct net_device *netdev); | 61 | static int bnx2fc_enable(struct net_device *netdev); |
61 | static int bnx2fc_disable(struct net_device *netdev); | 62 | static int bnx2fc_disable(struct net_device *netdev); |
@@ -64,7 +65,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb); | |||
64 | 65 | ||
65 | static void bnx2fc_start_disc(struct bnx2fc_interface *interface); | 66 | static void bnx2fc_start_disc(struct bnx2fc_interface *interface); |
66 | static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev); | 67 | static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev); |
67 | static int bnx2fc_net_config(struct fc_lport *lp); | ||
68 | static int bnx2fc_lport_config(struct fc_lport *lport); | 68 | static int bnx2fc_lport_config(struct fc_lport *lport); |
69 | static int bnx2fc_em_config(struct fc_lport *lport); | 69 | static int bnx2fc_em_config(struct fc_lport *lport); |
70 | static int bnx2fc_bind_adapter_devices(struct bnx2fc_hba *hba); | 70 | static int bnx2fc_bind_adapter_devices(struct bnx2fc_hba *hba); |
@@ -78,6 +78,7 @@ static void bnx2fc_destroy_work(struct work_struct *work); | |||
78 | static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device *phys_dev); | 78 | static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device *phys_dev); |
79 | static struct bnx2fc_interface *bnx2fc_interface_lookup(struct net_device | 79 | static struct bnx2fc_interface *bnx2fc_interface_lookup(struct net_device |
80 | *phys_dev); | 80 | *phys_dev); |
81 | static inline void bnx2fc_interface_put(struct bnx2fc_interface *interface); | ||
81 | static struct bnx2fc_hba *bnx2fc_find_hba_for_cnic(struct cnic_dev *cnic); | 82 | static struct bnx2fc_hba *bnx2fc_find_hba_for_cnic(struct cnic_dev *cnic); |
82 | 83 | ||
83 | static int bnx2fc_fw_init(struct bnx2fc_hba *hba); | 84 | static int bnx2fc_fw_init(struct bnx2fc_hba *hba); |
@@ -98,6 +99,25 @@ static struct notifier_block bnx2fc_cpu_notifier = { | |||
98 | .notifier_call = bnx2fc_cpu_callback, | 99 | .notifier_call = bnx2fc_cpu_callback, |
99 | }; | 100 | }; |
100 | 101 | ||
102 | static inline struct net_device *bnx2fc_netdev(const struct fc_lport *lport) | ||
103 | { | ||
104 | return ((struct bnx2fc_interface *) | ||
105 | ((struct fcoe_port *)lport_priv(lport))->priv)->netdev; | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | * bnx2fc_get_lesb() - Fill the FCoE Link Error Status Block | ||
110 | * @lport: the local port | ||
111 | * @fc_lesb: the link error status block | ||
112 | */ | ||
113 | static void bnx2fc_get_lesb(struct fc_lport *lport, | ||
114 | struct fc_els_lesb *fc_lesb) | ||
115 | { | ||
116 | struct net_device *netdev = bnx2fc_netdev(lport); | ||
117 | |||
118 | __fcoe_get_lesb(lport, fc_lesb, netdev); | ||
119 | } | ||
120 | |||
101 | static void bnx2fc_clean_rx_queue(struct fc_lport *lp) | 121 | static void bnx2fc_clean_rx_queue(struct fc_lport *lp) |
102 | { | 122 | { |
103 | struct fcoe_percpu_s *bg; | 123 | struct fcoe_percpu_s *bg; |
@@ -545,6 +565,14 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) | |||
545 | break; | 565 | break; |
546 | } | 566 | } |
547 | } | 567 | } |
568 | |||
569 | if (fh->fh_r_ctl == FC_RCTL_BA_ABTS) { | ||
570 | /* Drop incoming ABTS */ | ||
571 | put_cpu(); | ||
572 | kfree_skb(skb); | ||
573 | return; | ||
574 | } | ||
575 | |||
548 | if (le32_to_cpu(fr_crc(fp)) != | 576 | if (le32_to_cpu(fr_crc(fp)) != |
549 | ~crc32(~0, skb->data, fr_len)) { | 577 | ~crc32(~0, skb->data, fr_len)) { |
550 | if (stats->InvalidCRCCount < 5) | 578 | if (stats->InvalidCRCCount < 5) |
@@ -727,7 +755,7 @@ void bnx2fc_get_link_state(struct bnx2fc_hba *hba) | |||
727 | clear_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state); | 755 | clear_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state); |
728 | } | 756 | } |
729 | 757 | ||
730 | static int bnx2fc_net_config(struct fc_lport *lport) | 758 | static int bnx2fc_net_config(struct fc_lport *lport, struct net_device *netdev) |
731 | { | 759 | { |
732 | struct bnx2fc_hba *hba; | 760 | struct bnx2fc_hba *hba; |
733 | struct bnx2fc_interface *interface; | 761 | struct bnx2fc_interface *interface; |
@@ -753,11 +781,16 @@ static int bnx2fc_net_config(struct fc_lport *lport) | |||
753 | bnx2fc_link_speed_update(lport); | 781 | bnx2fc_link_speed_update(lport); |
754 | 782 | ||
755 | if (!lport->vport) { | 783 | if (!lport->vport) { |
756 | wwnn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr, 1, 0); | 784 | if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) |
785 | wwnn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr, | ||
786 | 1, 0); | ||
757 | BNX2FC_HBA_DBG(lport, "WWNN = 0x%llx\n", wwnn); | 787 | BNX2FC_HBA_DBG(lport, "WWNN = 0x%llx\n", wwnn); |
758 | fc_set_wwnn(lport, wwnn); | 788 | fc_set_wwnn(lport, wwnn); |
759 | 789 | ||
760 | wwpn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr, 2, 0); | 790 | if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) |
791 | wwpn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr, | ||
792 | 2, 0); | ||
793 | |||
761 | BNX2FC_HBA_DBG(lport, "WWPN = 0x%llx\n", wwpn); | 794 | BNX2FC_HBA_DBG(lport, "WWPN = 0x%llx\n", wwpn); |
762 | fc_set_wwpn(lport, wwpn); | 795 | fc_set_wwpn(lport, wwpn); |
763 | } | 796 | } |
@@ -769,8 +802,8 @@ static void bnx2fc_destroy_timer(unsigned long data) | |||
769 | { | 802 | { |
770 | struct bnx2fc_hba *hba = (struct bnx2fc_hba *)data; | 803 | struct bnx2fc_hba *hba = (struct bnx2fc_hba *)data; |
771 | 804 | ||
772 | BNX2FC_MISC_DBG("ERROR:bnx2fc_destroy_timer - " | 805 | printk(KERN_ERR PFX "ERROR:bnx2fc_destroy_timer - " |
773 | "Destroy compl not received!!\n"); | 806 | "Destroy compl not received!!\n"); |
774 | set_bit(BNX2FC_FLAG_DESTROY_CMPL, &hba->flags); | 807 | set_bit(BNX2FC_FLAG_DESTROY_CMPL, &hba->flags); |
775 | wake_up_interruptible(&hba->destroy_wait); | 808 | wake_up_interruptible(&hba->destroy_wait); |
776 | } | 809 | } |
@@ -783,7 +816,7 @@ static void bnx2fc_destroy_timer(unsigned long data) | |||
783 | * @vlan_id: vlan id - associated vlan id with this event | 816 | * @vlan_id: vlan id - associated vlan id with this event |
784 | * | 817 | * |
785 | * Handles NETDEV_UP, NETDEV_DOWN, NETDEV_GOING_DOWN,NETDEV_CHANGE and | 818 | * Handles NETDEV_UP, NETDEV_DOWN, NETDEV_GOING_DOWN,NETDEV_CHANGE and |
786 | * NETDEV_CHANGE_MTU events | 819 | * NETDEV_CHANGE_MTU events. Handle NETDEV_UNREGISTER only for vlans. |
787 | */ | 820 | */ |
788 | static void bnx2fc_indicate_netevent(void *context, unsigned long event, | 821 | static void bnx2fc_indicate_netevent(void *context, unsigned long event, |
789 | u16 vlan_id) | 822 | u16 vlan_id) |
@@ -791,12 +824,11 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, | |||
791 | struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context; | 824 | struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context; |
792 | struct fc_lport *lport; | 825 | struct fc_lport *lport; |
793 | struct fc_lport *vport; | 826 | struct fc_lport *vport; |
794 | struct bnx2fc_interface *interface; | 827 | struct bnx2fc_interface *interface, *tmp; |
795 | int wait_for_upload = 0; | 828 | int wait_for_upload = 0; |
796 | u32 link_possible = 1; | 829 | u32 link_possible = 1; |
797 | 830 | ||
798 | /* Ignore vlans for now */ | 831 | if (vlan_id != 0 && event != NETDEV_UNREGISTER) |
799 | if (vlan_id != 0) | ||
800 | return; | 832 | return; |
801 | 833 | ||
802 | switch (event) { | 834 | switch (event) { |
@@ -820,6 +852,18 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, | |||
820 | case NETDEV_CHANGE: | 852 | case NETDEV_CHANGE: |
821 | break; | 853 | break; |
822 | 854 | ||
855 | case NETDEV_UNREGISTER: | ||
856 | if (!vlan_id) | ||
857 | return; | ||
858 | mutex_lock(&bnx2fc_dev_lock); | ||
859 | list_for_each_entry_safe(interface, tmp, &if_list, list) { | ||
860 | if (interface->hba == hba && | ||
861 | interface->vlan_id == (vlan_id & VLAN_VID_MASK)) | ||
862 | __bnx2fc_destroy(interface); | ||
863 | } | ||
864 | mutex_unlock(&bnx2fc_dev_lock); | ||
865 | return; | ||
866 | |||
823 | default: | 867 | default: |
824 | printk(KERN_ERR PFX "Unkonwn netevent %ld", event); | 868 | printk(KERN_ERR PFX "Unkonwn netevent %ld", event); |
825 | return; | 869 | return; |
@@ -838,8 +882,15 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, | |||
838 | bnx2fc_link_speed_update(lport); | 882 | bnx2fc_link_speed_update(lport); |
839 | 883 | ||
840 | if (link_possible && !bnx2fc_link_ok(lport)) { | 884 | if (link_possible && !bnx2fc_link_ok(lport)) { |
841 | printk(KERN_ERR "indicate_netevent: ctlr_link_up\n"); | 885 | /* Reset max recv frame size to default */ |
842 | fcoe_ctlr_link_up(&interface->ctlr); | 886 | fc_set_mfs(lport, BNX2FC_MFS); |
887 | /* | ||
888 | * ctlr link up will only be handled during | ||
889 | * enable to avoid sending discovery solicitation | ||
890 | * on a stale vlan | ||
891 | */ | ||
892 | if (interface->enabled) | ||
893 | fcoe_ctlr_link_up(&interface->ctlr); | ||
843 | } else if (fcoe_ctlr_link_down(&interface->ctlr)) { | 894 | } else if (fcoe_ctlr_link_down(&interface->ctlr)) { |
844 | mutex_lock(&lport->lp_mutex); | 895 | mutex_lock(&lport->lp_mutex); |
845 | list_for_each_entry(vport, &lport->vports, list) | 896 | list_for_each_entry(vport, &lport->vports, list) |
@@ -995,6 +1046,17 @@ static int bnx2fc_vport_create(struct fc_vport *vport, bool disabled) | |||
995 | struct bnx2fc_interface *interface = port->priv; | 1046 | struct bnx2fc_interface *interface = port->priv; |
996 | struct net_device *netdev = interface->netdev; | 1047 | struct net_device *netdev = interface->netdev; |
997 | struct fc_lport *vn_port; | 1048 | struct fc_lport *vn_port; |
1049 | int rc; | ||
1050 | char buf[32]; | ||
1051 | |||
1052 | rc = fcoe_validate_vport_create(vport); | ||
1053 | if (rc) { | ||
1054 | fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf)); | ||
1055 | printk(KERN_ERR PFX "Failed to create vport, " | ||
1056 | "WWPN (0x%s) already exists\n", | ||
1057 | buf); | ||
1058 | return rc; | ||
1059 | } | ||
998 | 1060 | ||
999 | if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) { | 1061 | if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) { |
1000 | printk(KERN_ERR PFX "vn ports cannot be created on" | 1062 | printk(KERN_ERR PFX "vn ports cannot be created on" |
@@ -1024,16 +1086,46 @@ static int bnx2fc_vport_create(struct fc_vport *vport, bool disabled) | |||
1024 | return 0; | 1086 | return 0; |
1025 | } | 1087 | } |
1026 | 1088 | ||
1089 | static void bnx2fc_free_vport(struct bnx2fc_hba *hba, struct fc_lport *lport) | ||
1090 | { | ||
1091 | struct bnx2fc_lport *blport, *tmp; | ||
1092 | |||
1093 | spin_lock_bh(&hba->hba_lock); | ||
1094 | list_for_each_entry_safe(blport, tmp, &hba->vports, list) { | ||
1095 | if (blport->lport == lport) { | ||
1096 | list_del(&blport->list); | ||
1097 | kfree(blport); | ||
1098 | } | ||
1099 | } | ||
1100 | spin_unlock_bh(&hba->hba_lock); | ||
1101 | } | ||
1102 | |||
1027 | static int bnx2fc_vport_destroy(struct fc_vport *vport) | 1103 | static int bnx2fc_vport_destroy(struct fc_vport *vport) |
1028 | { | 1104 | { |
1029 | struct Scsi_Host *shost = vport_to_shost(vport); | 1105 | struct Scsi_Host *shost = vport_to_shost(vport); |
1030 | struct fc_lport *n_port = shost_priv(shost); | 1106 | struct fc_lport *n_port = shost_priv(shost); |
1031 | struct fc_lport *vn_port = vport->dd_data; | 1107 | struct fc_lport *vn_port = vport->dd_data; |
1032 | struct fcoe_port *port = lport_priv(vn_port); | 1108 | struct fcoe_port *port = lport_priv(vn_port); |
1109 | struct bnx2fc_interface *interface = port->priv; | ||
1110 | struct fc_lport *v_port; | ||
1111 | bool found = false; | ||
1033 | 1112 | ||
1034 | mutex_lock(&n_port->lp_mutex); | 1113 | mutex_lock(&n_port->lp_mutex); |
1114 | list_for_each_entry(v_port, &n_port->vports, list) | ||
1115 | if (v_port->vport == vport) { | ||
1116 | found = true; | ||
1117 | break; | ||
1118 | } | ||
1119 | |||
1120 | if (!found) { | ||
1121 | mutex_unlock(&n_port->lp_mutex); | ||
1122 | return -ENOENT; | ||
1123 | } | ||
1035 | list_del(&vn_port->list); | 1124 | list_del(&vn_port->list); |
1036 | mutex_unlock(&n_port->lp_mutex); | 1125 | mutex_unlock(&n_port->lp_mutex); |
1126 | bnx2fc_free_vport(interface->hba, port->lport); | ||
1127 | bnx2fc_port_shutdown(port->lport); | ||
1128 | bnx2fc_interface_put(interface); | ||
1037 | queue_work(bnx2fc_wq, &port->destroy_work); | 1129 | queue_work(bnx2fc_wq, &port->destroy_work); |
1038 | return 0; | 1130 | return 0; |
1039 | } | 1131 | } |
@@ -1054,7 +1146,7 @@ static int bnx2fc_vport_disable(struct fc_vport *vport, bool disable) | |||
1054 | } | 1146 | } |
1055 | 1147 | ||
1056 | 1148 | ||
1057 | static int bnx2fc_netdev_setup(struct bnx2fc_interface *interface) | 1149 | static int bnx2fc_interface_setup(struct bnx2fc_interface *interface) |
1058 | { | 1150 | { |
1059 | struct net_device *netdev = interface->netdev; | 1151 | struct net_device *netdev = interface->netdev; |
1060 | struct net_device *physdev = interface->hba->phys_dev; | 1152 | struct net_device *physdev = interface->hba->phys_dev; |
@@ -1252,7 +1344,7 @@ struct bnx2fc_interface *bnx2fc_interface_create(struct bnx2fc_hba *hba, | |||
1252 | interface->ctlr.get_src_addr = bnx2fc_get_src_mac; | 1344 | interface->ctlr.get_src_addr = bnx2fc_get_src_mac; |
1253 | set_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags); | 1345 | set_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags); |
1254 | 1346 | ||
1255 | rc = bnx2fc_netdev_setup(interface); | 1347 | rc = bnx2fc_interface_setup(interface); |
1256 | if (!rc) | 1348 | if (!rc) |
1257 | return interface; | 1349 | return interface; |
1258 | 1350 | ||
@@ -1318,7 +1410,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, | |||
1318 | fc_set_wwpn(lport, vport->port_name); | 1410 | fc_set_wwpn(lport, vport->port_name); |
1319 | } | 1411 | } |
1320 | /* Configure netdev and networking properties of the lport */ | 1412 | /* Configure netdev and networking properties of the lport */ |
1321 | rc = bnx2fc_net_config(lport); | 1413 | rc = bnx2fc_net_config(lport, interface->netdev); |
1322 | if (rc) { | 1414 | if (rc) { |
1323 | printk(KERN_ERR PFX "Error on bnx2fc_net_config\n"); | 1415 | printk(KERN_ERR PFX "Error on bnx2fc_net_config\n"); |
1324 | goto lp_config_err; | 1416 | goto lp_config_err; |
@@ -1372,7 +1464,7 @@ free_blport: | |||
1372 | return NULL; | 1464 | return NULL; |
1373 | } | 1465 | } |
1374 | 1466 | ||
1375 | static void bnx2fc_netdev_cleanup(struct bnx2fc_interface *interface) | 1467 | static void bnx2fc_net_cleanup(struct bnx2fc_interface *interface) |
1376 | { | 1468 | { |
1377 | /* Dont listen for Ethernet packets anymore */ | 1469 | /* Dont listen for Ethernet packets anymore */ |
1378 | __dev_remove_pack(&interface->fcoe_packet_type); | 1470 | __dev_remove_pack(&interface->fcoe_packet_type); |
@@ -1380,10 +1472,11 @@ static void bnx2fc_netdev_cleanup(struct bnx2fc_interface *interface) | |||
1380 | synchronize_net(); | 1472 | synchronize_net(); |
1381 | } | 1473 | } |
1382 | 1474 | ||
1383 | static void bnx2fc_if_destroy(struct fc_lport *lport, struct bnx2fc_hba *hba) | 1475 | static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface) |
1384 | { | 1476 | { |
1477 | struct fc_lport *lport = interface->ctlr.lp; | ||
1385 | struct fcoe_port *port = lport_priv(lport); | 1478 | struct fcoe_port *port = lport_priv(lport); |
1386 | struct bnx2fc_lport *blport, *tmp; | 1479 | struct bnx2fc_hba *hba = interface->hba; |
1387 | 1480 | ||
1388 | /* Stop the transmit retry timer */ | 1481 | /* Stop the transmit retry timer */ |
1389 | del_timer_sync(&port->timer); | 1482 | del_timer_sync(&port->timer); |
@@ -1391,6 +1484,14 @@ static void bnx2fc_if_destroy(struct fc_lport *lport, struct bnx2fc_hba *hba) | |||
1391 | /* Free existing transmit skbs */ | 1484 | /* Free existing transmit skbs */ |
1392 | fcoe_clean_pending_queue(lport); | 1485 | fcoe_clean_pending_queue(lport); |
1393 | 1486 | ||
1487 | bnx2fc_net_cleanup(interface); | ||
1488 | |||
1489 | bnx2fc_free_vport(hba, lport); | ||
1490 | } | ||
1491 | |||
1492 | static void bnx2fc_if_destroy(struct fc_lport *lport) | ||
1493 | { | ||
1494 | |||
1394 | /* Free queued packets for the receive thread */ | 1495 | /* Free queued packets for the receive thread */ |
1395 | bnx2fc_clean_rx_queue(lport); | 1496 | bnx2fc_clean_rx_queue(lport); |
1396 | 1497 | ||
@@ -1407,19 +1508,22 @@ static void bnx2fc_if_destroy(struct fc_lport *lport, struct bnx2fc_hba *hba) | |||
1407 | /* Free memory used by statistical counters */ | 1508 | /* Free memory used by statistical counters */ |
1408 | fc_lport_free_stats(lport); | 1509 | fc_lport_free_stats(lport); |
1409 | 1510 | ||
1410 | spin_lock_bh(&hba->hba_lock); | ||
1411 | list_for_each_entry_safe(blport, tmp, &hba->vports, list) { | ||
1412 | if (blport->lport == lport) { | ||
1413 | list_del(&blport->list); | ||
1414 | kfree(blport); | ||
1415 | } | ||
1416 | } | ||
1417 | spin_unlock_bh(&hba->hba_lock); | ||
1418 | |||
1419 | /* Release Scsi_Host */ | 1511 | /* Release Scsi_Host */ |
1420 | scsi_host_put(lport->host); | 1512 | scsi_host_put(lport->host); |
1421 | } | 1513 | } |
1422 | 1514 | ||
1515 | static void __bnx2fc_destroy(struct bnx2fc_interface *interface) | ||
1516 | { | ||
1517 | struct fc_lport *lport = interface->ctlr.lp; | ||
1518 | struct fcoe_port *port = lport_priv(lport); | ||
1519 | |||
1520 | bnx2fc_interface_cleanup(interface); | ||
1521 | bnx2fc_stop(interface); | ||
1522 | list_del(&interface->list); | ||
1523 | bnx2fc_interface_put(interface); | ||
1524 | queue_work(bnx2fc_wq, &port->destroy_work); | ||
1525 | } | ||
1526 | |||
1423 | /** | 1527 | /** |
1424 | * bnx2fc_destroy - Destroy a bnx2fc FCoE interface | 1528 | * bnx2fc_destroy - Destroy a bnx2fc FCoE interface |
1425 | * | 1529 | * |
@@ -1433,8 +1537,6 @@ static void bnx2fc_if_destroy(struct fc_lport *lport, struct bnx2fc_hba *hba) | |||
1433 | static int bnx2fc_destroy(struct net_device *netdev) | 1537 | static int bnx2fc_destroy(struct net_device *netdev) |
1434 | { | 1538 | { |
1435 | struct bnx2fc_interface *interface = NULL; | 1539 | struct bnx2fc_interface *interface = NULL; |
1436 | struct bnx2fc_hba *hba; | ||
1437 | struct fc_lport *lport; | ||
1438 | int rc = 0; | 1540 | int rc = 0; |
1439 | 1541 | ||
1440 | rtnl_lock(); | 1542 | rtnl_lock(); |
@@ -1447,15 +1549,9 @@ static int bnx2fc_destroy(struct net_device *netdev) | |||
1447 | goto netdev_err; | 1549 | goto netdev_err; |
1448 | } | 1550 | } |
1449 | 1551 | ||
1450 | hba = interface->hba; | ||
1451 | 1552 | ||
1452 | bnx2fc_netdev_cleanup(interface); | ||
1453 | lport = interface->ctlr.lp; | ||
1454 | bnx2fc_stop(interface); | ||
1455 | list_del(&interface->list); | ||
1456 | destroy_workqueue(interface->timer_work_queue); | 1553 | destroy_workqueue(interface->timer_work_queue); |
1457 | bnx2fc_interface_put(interface); | 1554 | __bnx2fc_destroy(interface); |
1458 | bnx2fc_if_destroy(lport, hba); | ||
1459 | 1555 | ||
1460 | netdev_err: | 1556 | netdev_err: |
1461 | mutex_unlock(&bnx2fc_dev_lock); | 1557 | mutex_unlock(&bnx2fc_dev_lock); |
@@ -1467,22 +1563,13 @@ static void bnx2fc_destroy_work(struct work_struct *work) | |||
1467 | { | 1563 | { |
1468 | struct fcoe_port *port; | 1564 | struct fcoe_port *port; |
1469 | struct fc_lport *lport; | 1565 | struct fc_lport *lport; |
1470 | struct bnx2fc_interface *interface; | ||
1471 | struct bnx2fc_hba *hba; | ||
1472 | 1566 | ||
1473 | port = container_of(work, struct fcoe_port, destroy_work); | 1567 | port = container_of(work, struct fcoe_port, destroy_work); |
1474 | lport = port->lport; | 1568 | lport = port->lport; |
1475 | interface = port->priv; | ||
1476 | hba = interface->hba; | ||
1477 | 1569 | ||
1478 | BNX2FC_HBA_DBG(lport, "Entered bnx2fc_destroy_work\n"); | 1570 | BNX2FC_HBA_DBG(lport, "Entered bnx2fc_destroy_work\n"); |
1479 | 1571 | ||
1480 | bnx2fc_port_shutdown(lport); | 1572 | bnx2fc_if_destroy(lport); |
1481 | rtnl_lock(); | ||
1482 | mutex_lock(&bnx2fc_dev_lock); | ||
1483 | bnx2fc_if_destroy(lport, hba); | ||
1484 | mutex_unlock(&bnx2fc_dev_lock); | ||
1485 | rtnl_unlock(); | ||
1486 | } | 1573 | } |
1487 | 1574 | ||
1488 | static void bnx2fc_unbind_adapter_devices(struct bnx2fc_hba *hba) | 1575 | static void bnx2fc_unbind_adapter_devices(struct bnx2fc_hba *hba) |
@@ -1661,6 +1748,7 @@ static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba) | |||
1661 | wait_event_interruptible(hba->destroy_wait, | 1748 | wait_event_interruptible(hba->destroy_wait, |
1662 | test_bit(BNX2FC_FLAG_DESTROY_CMPL, | 1749 | test_bit(BNX2FC_FLAG_DESTROY_CMPL, |
1663 | &hba->flags)); | 1750 | &hba->flags)); |
1751 | clear_bit(BNX2FC_FLAG_DESTROY_CMPL, &hba->flags); | ||
1664 | /* This should never happen */ | 1752 | /* This should never happen */ |
1665 | if (signal_pending(current)) | 1753 | if (signal_pending(current)) |
1666 | flush_signals(current); | 1754 | flush_signals(current); |
@@ -1723,7 +1811,7 @@ static void bnx2fc_start_disc(struct bnx2fc_interface *interface) | |||
1723 | lport = interface->ctlr.lp; | 1811 | lport = interface->ctlr.lp; |
1724 | BNX2FC_HBA_DBG(lport, "calling fc_fabric_login\n"); | 1812 | BNX2FC_HBA_DBG(lport, "calling fc_fabric_login\n"); |
1725 | 1813 | ||
1726 | if (!bnx2fc_link_ok(lport)) { | 1814 | if (!bnx2fc_link_ok(lport) && interface->enabled) { |
1727 | BNX2FC_HBA_DBG(lport, "ctlr_link_up\n"); | 1815 | BNX2FC_HBA_DBG(lport, "ctlr_link_up\n"); |
1728 | fcoe_ctlr_link_up(&interface->ctlr); | 1816 | fcoe_ctlr_link_up(&interface->ctlr); |
1729 | fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; | 1817 | fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; |
@@ -1737,6 +1825,11 @@ static void bnx2fc_start_disc(struct bnx2fc_interface *interface) | |||
1737 | if (++wait_cnt > 12) | 1825 | if (++wait_cnt > 12) |
1738 | break; | 1826 | break; |
1739 | } | 1827 | } |
1828 | |||
1829 | /* Reset max receive frame size to default */ | ||
1830 | if (fc_set_mfs(lport, BNX2FC_MFS)) | ||
1831 | return; | ||
1832 | |||
1740 | fc_lport_init(lport); | 1833 | fc_lport_init(lport); |
1741 | fc_fabric_login(lport); | 1834 | fc_fabric_login(lport); |
1742 | } | 1835 | } |
@@ -1800,6 +1893,7 @@ static int bnx2fc_disable(struct net_device *netdev) | |||
1800 | rc = -ENODEV; | 1893 | rc = -ENODEV; |
1801 | printk(KERN_ERR PFX "bnx2fc_disable: interface or lport not found\n"); | 1894 | printk(KERN_ERR PFX "bnx2fc_disable: interface or lport not found\n"); |
1802 | } else { | 1895 | } else { |
1896 | interface->enabled = false; | ||
1803 | fcoe_ctlr_link_down(&interface->ctlr); | 1897 | fcoe_ctlr_link_down(&interface->ctlr); |
1804 | fcoe_clean_pending_queue(interface->ctlr.lp); | 1898 | fcoe_clean_pending_queue(interface->ctlr.lp); |
1805 | } | 1899 | } |
@@ -1822,8 +1916,10 @@ static int bnx2fc_enable(struct net_device *netdev) | |||
1822 | if (!interface || !interface->ctlr.lp) { | 1916 | if (!interface || !interface->ctlr.lp) { |
1823 | rc = -ENODEV; | 1917 | rc = -ENODEV; |
1824 | printk(KERN_ERR PFX "bnx2fc_enable: interface or lport not found\n"); | 1918 | printk(KERN_ERR PFX "bnx2fc_enable: interface or lport not found\n"); |
1825 | } else if (!bnx2fc_link_ok(interface->ctlr.lp)) | 1919 | } else if (!bnx2fc_link_ok(interface->ctlr.lp)) { |
1826 | fcoe_ctlr_link_up(&interface->ctlr); | 1920 | fcoe_ctlr_link_up(&interface->ctlr); |
1921 | interface->enabled = true; | ||
1922 | } | ||
1827 | 1923 | ||
1828 | mutex_unlock(&bnx2fc_dev_lock); | 1924 | mutex_unlock(&bnx2fc_dev_lock); |
1829 | rtnl_unlock(); | 1925 | rtnl_unlock(); |
@@ -1923,7 +2019,6 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) | |||
1923 | if (!lport) { | 2019 | if (!lport) { |
1924 | printk(KERN_ERR PFX "Failed to create interface (%s)\n", | 2020 | printk(KERN_ERR PFX "Failed to create interface (%s)\n", |
1925 | netdev->name); | 2021 | netdev->name); |
1926 | bnx2fc_netdev_cleanup(interface); | ||
1927 | rc = -EINVAL; | 2022 | rc = -EINVAL; |
1928 | goto if_create_err; | 2023 | goto if_create_err; |
1929 | } | 2024 | } |
@@ -1936,8 +2031,15 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) | |||
1936 | /* Make this master N_port */ | 2031 | /* Make this master N_port */ |
1937 | interface->ctlr.lp = lport; | 2032 | interface->ctlr.lp = lport; |
1938 | 2033 | ||
2034 | if (!bnx2fc_link_ok(lport)) { | ||
2035 | fcoe_ctlr_link_up(&interface->ctlr); | ||
2036 | fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; | ||
2037 | set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state); | ||
2038 | } | ||
2039 | |||
1939 | BNX2FC_HBA_DBG(lport, "create: START DISC\n"); | 2040 | BNX2FC_HBA_DBG(lport, "create: START DISC\n"); |
1940 | bnx2fc_start_disc(interface); | 2041 | bnx2fc_start_disc(interface); |
2042 | interface->enabled = true; | ||
1941 | /* | 2043 | /* |
1942 | * Release from kref_init in bnx2fc_interface_setup, on success | 2044 | * Release from kref_init in bnx2fc_interface_setup, on success |
1943 | * lport should be holding a reference taken in bnx2fc_if_create | 2045 | * lport should be holding a reference taken in bnx2fc_if_create |
@@ -1951,6 +2053,7 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) | |||
1951 | if_create_err: | 2053 | if_create_err: |
1952 | destroy_workqueue(interface->timer_work_queue); | 2054 | destroy_workqueue(interface->timer_work_queue); |
1953 | ifput_err: | 2055 | ifput_err: |
2056 | bnx2fc_net_cleanup(interface); | ||
1954 | bnx2fc_interface_put(interface); | 2057 | bnx2fc_interface_put(interface); |
1955 | netdev_err: | 2058 | netdev_err: |
1956 | module_put(THIS_MODULE); | 2059 | module_put(THIS_MODULE); |
@@ -2017,7 +2120,6 @@ static void bnx2fc_ulp_exit(struct cnic_dev *dev) | |||
2017 | { | 2120 | { |
2018 | struct bnx2fc_hba *hba; | 2121 | struct bnx2fc_hba *hba; |
2019 | struct bnx2fc_interface *interface, *tmp; | 2122 | struct bnx2fc_interface *interface, *tmp; |
2020 | struct fc_lport *lport; | ||
2021 | 2123 | ||
2022 | BNX2FC_MISC_DBG("Entered bnx2fc_ulp_exit\n"); | 2124 | BNX2FC_MISC_DBG("Entered bnx2fc_ulp_exit\n"); |
2023 | 2125 | ||
@@ -2039,18 +2141,10 @@ static void bnx2fc_ulp_exit(struct cnic_dev *dev) | |||
2039 | list_del_init(&hba->list); | 2141 | list_del_init(&hba->list); |
2040 | adapter_count--; | 2142 | adapter_count--; |
2041 | 2143 | ||
2042 | list_for_each_entry_safe(interface, tmp, &if_list, list) { | 2144 | list_for_each_entry_safe(interface, tmp, &if_list, list) |
2043 | /* destroy not called yet, move to quiesced list */ | 2145 | /* destroy not called yet, move to quiesced list */ |
2044 | if (interface->hba == hba) { | 2146 | if (interface->hba == hba) |
2045 | bnx2fc_netdev_cleanup(interface); | 2147 | __bnx2fc_destroy(interface); |
2046 | bnx2fc_stop(interface); | ||
2047 | |||
2048 | list_del(&interface->list); | ||
2049 | lport = interface->ctlr.lp; | ||
2050 | bnx2fc_interface_put(interface); | ||
2051 | bnx2fc_if_destroy(lport, hba); | ||
2052 | } | ||
2053 | } | ||
2054 | mutex_unlock(&bnx2fc_dev_lock); | 2148 | mutex_unlock(&bnx2fc_dev_lock); |
2055 | 2149 | ||
2056 | bnx2fc_ulp_stop(hba); | 2150 | bnx2fc_ulp_stop(hba); |
@@ -2119,7 +2213,7 @@ static void bnx2fc_percpu_thread_create(unsigned int cpu) | |||
2119 | (void *)p, | 2213 | (void *)p, |
2120 | "bnx2fc_thread/%d", cpu); | 2214 | "bnx2fc_thread/%d", cpu); |
2121 | /* bind thread to the cpu */ | 2215 | /* bind thread to the cpu */ |
2122 | if (likely(!IS_ERR(p->iothread))) { | 2216 | if (likely(!IS_ERR(thread))) { |
2123 | kthread_bind(thread, cpu); | 2217 | kthread_bind(thread, cpu); |
2124 | p->iothread = thread; | 2218 | p->iothread = thread; |
2125 | wake_up_process(thread); | 2219 | wake_up_process(thread); |
@@ -2131,7 +2225,6 @@ static void bnx2fc_percpu_thread_destroy(unsigned int cpu) | |||
2131 | struct bnx2fc_percpu_s *p; | 2225 | struct bnx2fc_percpu_s *p; |
2132 | struct task_struct *thread; | 2226 | struct task_struct *thread; |
2133 | struct bnx2fc_work *work, *tmp; | 2227 | struct bnx2fc_work *work, *tmp; |
2134 | LIST_HEAD(work_list); | ||
2135 | 2228 | ||
2136 | BNX2FC_MISC_DBG("destroying io thread for CPU %d\n", cpu); | 2229 | BNX2FC_MISC_DBG("destroying io thread for CPU %d\n", cpu); |
2137 | 2230 | ||
@@ -2143,7 +2236,7 @@ static void bnx2fc_percpu_thread_destroy(unsigned int cpu) | |||
2143 | 2236 | ||
2144 | 2237 | ||
2145 | /* Free all work in the list */ | 2238 | /* Free all work in the list */ |
2146 | list_for_each_entry_safe(work, tmp, &work_list, list) { | 2239 | list_for_each_entry_safe(work, tmp, &p->work_list, list) { |
2147 | list_del_init(&work->list); | 2240 | list_del_init(&work->list); |
2148 | bnx2fc_process_cq_compl(work->tgt, work->wqe); | 2241 | bnx2fc_process_cq_compl(work->tgt, work->wqe); |
2149 | kfree(work); | 2242 | kfree(work); |
@@ -2376,6 +2469,7 @@ static struct fc_function_template bnx2fc_transport_function = { | |||
2376 | .vport_create = bnx2fc_vport_create, | 2469 | .vport_create = bnx2fc_vport_create, |
2377 | .vport_delete = bnx2fc_vport_destroy, | 2470 | .vport_delete = bnx2fc_vport_destroy, |
2378 | .vport_disable = bnx2fc_vport_disable, | 2471 | .vport_disable = bnx2fc_vport_disable, |
2472 | .bsg_request = fc_lport_bsg_request, | ||
2379 | }; | 2473 | }; |
2380 | 2474 | ||
2381 | static struct fc_function_template bnx2fc_vport_xport_function = { | 2475 | static struct fc_function_template bnx2fc_vport_xport_function = { |
@@ -2409,6 +2503,7 @@ static struct fc_function_template bnx2fc_vport_xport_function = { | |||
2409 | .get_fc_host_stats = fc_get_host_stats, | 2503 | .get_fc_host_stats = fc_get_host_stats, |
2410 | .issue_fc_host_lip = bnx2fc_fcoe_reset, | 2504 | .issue_fc_host_lip = bnx2fc_fcoe_reset, |
2411 | .terminate_rport_io = fc_rport_terminate_io, | 2505 | .terminate_rport_io = fc_rport_terminate_io, |
2506 | .bsg_request = fc_lport_bsg_request, | ||
2412 | }; | 2507 | }; |
2413 | 2508 | ||
2414 | /** | 2509 | /** |
@@ -2438,6 +2533,7 @@ static struct libfc_function_template bnx2fc_libfc_fcn_templ = { | |||
2438 | .elsct_send = bnx2fc_elsct_send, | 2533 | .elsct_send = bnx2fc_elsct_send, |
2439 | .fcp_abort_io = bnx2fc_abort_io, | 2534 | .fcp_abort_io = bnx2fc_abort_io, |
2440 | .fcp_cleanup = bnx2fc_cleanup, | 2535 | .fcp_cleanup = bnx2fc_cleanup, |
2536 | .get_lesb = bnx2fc_get_lesb, | ||
2441 | .rport_event_callback = bnx2fc_rport_event_handler, | 2537 | .rport_event_callback = bnx2fc_rport_event_handler, |
2442 | }; | 2538 | }; |
2443 | 2539 | ||
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c index 72cfb14acd3..1923a25cb6a 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c | |||
@@ -1009,6 +1009,7 @@ int bnx2fc_process_new_cqes(struct bnx2fc_rport *tgt) | |||
1009 | u32 cq_cons; | 1009 | u32 cq_cons; |
1010 | struct fcoe_cqe *cqe; | 1010 | struct fcoe_cqe *cqe; |
1011 | u32 num_free_sqes = 0; | 1011 | u32 num_free_sqes = 0; |
1012 | u32 num_cqes = 0; | ||
1012 | u16 wqe; | 1013 | u16 wqe; |
1013 | 1014 | ||
1014 | /* | 1015 | /* |
@@ -1058,10 +1059,11 @@ unlock: | |||
1058 | wake_up_process(fps->iothread); | 1059 | wake_up_process(fps->iothread); |
1059 | else | 1060 | else |
1060 | bnx2fc_process_cq_compl(tgt, wqe); | 1061 | bnx2fc_process_cq_compl(tgt, wqe); |
1062 | num_free_sqes++; | ||
1061 | } | 1063 | } |
1062 | cqe++; | 1064 | cqe++; |
1063 | tgt->cq_cons_idx++; | 1065 | tgt->cq_cons_idx++; |
1064 | num_free_sqes++; | 1066 | num_cqes++; |
1065 | 1067 | ||
1066 | if (tgt->cq_cons_idx == BNX2FC_CQ_WQES_MAX) { | 1068 | if (tgt->cq_cons_idx == BNX2FC_CQ_WQES_MAX) { |
1067 | tgt->cq_cons_idx = 0; | 1069 | tgt->cq_cons_idx = 0; |
@@ -1070,8 +1072,10 @@ unlock: | |||
1070 | 1 - tgt->cq_curr_toggle_bit; | 1072 | 1 - tgt->cq_curr_toggle_bit; |
1071 | } | 1073 | } |
1072 | } | 1074 | } |
1073 | if (num_free_sqes) { | 1075 | if (num_cqes) { |
1074 | bnx2fc_arm_cq(tgt); | 1076 | /* Arm CQ only if doorbell is mapped */ |
1077 | if (tgt->ctx_base) | ||
1078 | bnx2fc_arm_cq(tgt); | ||
1075 | atomic_add(num_free_sqes, &tgt->free_sqes); | 1079 | atomic_add(num_free_sqes, &tgt->free_sqes); |
1076 | } | 1080 | } |
1077 | spin_unlock_bh(&tgt->cq_lock); | 1081 | spin_unlock_bh(&tgt->cq_lock); |
@@ -1739,11 +1743,13 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req, | |||
1739 | /* Init state to NORMAL */ | 1743 | /* Init state to NORMAL */ |
1740 | task->txwr_rxrd.const_ctx.init_flags |= task_type << | 1744 | task->txwr_rxrd.const_ctx.init_flags |= task_type << |
1741 | FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT; | 1745 | FCOE_TCE_TX_WR_RX_RD_CONST_TASK_TYPE_SHIFT; |
1742 | if (dev_type == TYPE_TAPE) | 1746 | if (dev_type == TYPE_TAPE) { |
1743 | task->txwr_rxrd.const_ctx.init_flags |= | 1747 | task->txwr_rxrd.const_ctx.init_flags |= |
1744 | FCOE_TASK_DEV_TYPE_TAPE << | 1748 | FCOE_TASK_DEV_TYPE_TAPE << |
1745 | FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT; | 1749 | FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT; |
1746 | else | 1750 | io_req->rec_retry = 0; |
1751 | io_req->rec_retry = 0; | ||
1752 | } else | ||
1747 | task->txwr_rxrd.const_ctx.init_flags |= | 1753 | task->txwr_rxrd.const_ctx.init_flags |= |
1748 | FCOE_TASK_DEV_TYPE_DISK << | 1754 | FCOE_TASK_DEV_TYPE_DISK << |
1749 | FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT; | 1755 | FCOE_TCE_TX_WR_RX_RD_CONST_DEV_TYPE_SHIFT; |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 6cc3789075b..0c64d184d73 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c | |||
@@ -17,7 +17,7 @@ | |||
17 | static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len, | 17 | static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len, |
18 | int bd_index); | 18 | int bd_index); |
19 | static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req); | 19 | static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req); |
20 | static void bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req); | 20 | static int bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req); |
21 | static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req); | 21 | static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req); |
22 | static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req); | 22 | static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req); |
23 | static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, | 23 | static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, |
@@ -1251,7 +1251,6 @@ void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnp_req, | |||
1251 | seq_clnp_req->xid); | 1251 | seq_clnp_req->xid); |
1252 | goto free_cb_arg; | 1252 | goto free_cb_arg; |
1253 | } | 1253 | } |
1254 | kref_get(&orig_io_req->refcount); | ||
1255 | 1254 | ||
1256 | spin_unlock_bh(&tgt->tgt_lock); | 1255 | spin_unlock_bh(&tgt->tgt_lock); |
1257 | rc = bnx2fc_send_srr(orig_io_req, offset, r_ctl); | 1256 | rc = bnx2fc_send_srr(orig_io_req, offset, r_ctl); |
@@ -1569,6 +1568,8 @@ static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len, | |||
1569 | 1568 | ||
1570 | static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req) | 1569 | static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req) |
1571 | { | 1570 | { |
1571 | struct bnx2fc_interface *interface = io_req->port->priv; | ||
1572 | struct bnx2fc_hba *hba = interface->hba; | ||
1572 | struct scsi_cmnd *sc = io_req->sc_cmd; | 1573 | struct scsi_cmnd *sc = io_req->sc_cmd; |
1573 | struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl; | 1574 | struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl; |
1574 | struct scatterlist *sg; | 1575 | struct scatterlist *sg; |
@@ -1580,7 +1581,8 @@ static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req) | |||
1580 | u64 addr; | 1581 | u64 addr; |
1581 | int i; | 1582 | int i; |
1582 | 1583 | ||
1583 | sg_count = scsi_dma_map(sc); | 1584 | sg_count = dma_map_sg(&hba->pcidev->dev, scsi_sglist(sc), |
1585 | scsi_sg_count(sc), sc->sc_data_direction); | ||
1584 | scsi_for_each_sg(sc, sg, sg_count, i) { | 1586 | scsi_for_each_sg(sc, sg, sg_count, i) { |
1585 | sg_len = sg_dma_len(sg); | 1587 | sg_len = sg_dma_len(sg); |
1586 | addr = sg_dma_address(sg); | 1588 | addr = sg_dma_address(sg); |
@@ -1605,20 +1607,24 @@ static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req) | |||
1605 | return bd_count; | 1607 | return bd_count; |
1606 | } | 1608 | } |
1607 | 1609 | ||
1608 | static void bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req) | 1610 | static int bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req) |
1609 | { | 1611 | { |
1610 | struct scsi_cmnd *sc = io_req->sc_cmd; | 1612 | struct scsi_cmnd *sc = io_req->sc_cmd; |
1611 | struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl; | 1613 | struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl; |
1612 | int bd_count; | 1614 | int bd_count; |
1613 | 1615 | ||
1614 | if (scsi_sg_count(sc)) | 1616 | if (scsi_sg_count(sc)) { |
1615 | bd_count = bnx2fc_map_sg(io_req); | 1617 | bd_count = bnx2fc_map_sg(io_req); |
1616 | else { | 1618 | if (bd_count == 0) |
1619 | return -ENOMEM; | ||
1620 | } else { | ||
1617 | bd_count = 0; | 1621 | bd_count = 0; |
1618 | bd[0].buf_addr_lo = bd[0].buf_addr_hi = 0; | 1622 | bd[0].buf_addr_lo = bd[0].buf_addr_hi = 0; |
1619 | bd[0].buf_len = bd[0].flags = 0; | 1623 | bd[0].buf_len = bd[0].flags = 0; |
1620 | } | 1624 | } |
1621 | io_req->bd_tbl->bd_valid = bd_count; | 1625 | io_req->bd_tbl->bd_valid = bd_count; |
1626 | |||
1627 | return 0; | ||
1622 | } | 1628 | } |
1623 | 1629 | ||
1624 | static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req) | 1630 | static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req) |
@@ -1790,12 +1796,6 @@ int bnx2fc_queuecommand(struct Scsi_Host *host, | |||
1790 | tgt = (struct bnx2fc_rport *)&rp[1]; | 1796 | tgt = (struct bnx2fc_rport *)&rp[1]; |
1791 | 1797 | ||
1792 | if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) { | 1798 | if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) { |
1793 | if (test_bit(BNX2FC_FLAG_UPLD_REQ_COMPL, &tgt->flags)) { | ||
1794 | sc_cmd->result = DID_NO_CONNECT << 16; | ||
1795 | sc_cmd->scsi_done(sc_cmd); | ||
1796 | return 0; | ||
1797 | |||
1798 | } | ||
1799 | /* | 1799 | /* |
1800 | * Session is not offloaded yet. Let SCSI-ml retry | 1800 | * Session is not offloaded yet. Let SCSI-ml retry |
1801 | * the command. | 1801 | * the command. |
@@ -1946,7 +1946,13 @@ int bnx2fc_post_io_req(struct bnx2fc_rport *tgt, | |||
1946 | xid = io_req->xid; | 1946 | xid = io_req->xid; |
1947 | 1947 | ||
1948 | /* Build buffer descriptor list for firmware from sg list */ | 1948 | /* Build buffer descriptor list for firmware from sg list */ |
1949 | bnx2fc_build_bd_list_from_sg(io_req); | 1949 | if (bnx2fc_build_bd_list_from_sg(io_req)) { |
1950 | printk(KERN_ERR PFX "BD list creation failed\n"); | ||
1951 | spin_lock_bh(&tgt->tgt_lock); | ||
1952 | kref_put(&io_req->refcount, bnx2fc_cmd_release); | ||
1953 | spin_unlock_bh(&tgt->tgt_lock); | ||
1954 | return -EAGAIN; | ||
1955 | } | ||
1950 | 1956 | ||
1951 | task_idx = xid / BNX2FC_TASKS_PER_PAGE; | 1957 | task_idx = xid / BNX2FC_TASKS_PER_PAGE; |
1952 | index = xid % BNX2FC_TASKS_PER_PAGE; | 1958 | index = xid % BNX2FC_TASKS_PER_PAGE; |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index d5311b577cc..c1800b53127 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c | |||
@@ -76,7 +76,7 @@ static void bnx2fc_offload_session(struct fcoe_port *port, | |||
76 | if (rval) { | 76 | if (rval) { |
77 | printk(KERN_ERR PFX "Failed to allocate conn id for " | 77 | printk(KERN_ERR PFX "Failed to allocate conn id for " |
78 | "port_id (%6x)\n", rport->port_id); | 78 | "port_id (%6x)\n", rport->port_id); |
79 | goto ofld_err; | 79 | goto tgt_init_err; |
80 | } | 80 | } |
81 | 81 | ||
82 | /* Allocate session resources */ | 82 | /* Allocate session resources */ |
@@ -134,18 +134,17 @@ retry_ofld: | |||
134 | /* upload will take care of cleaning up sess resc */ | 134 | /* upload will take care of cleaning up sess resc */ |
135 | lport->tt.rport_logoff(rdata); | 135 | lport->tt.rport_logoff(rdata); |
136 | } | 136 | } |
137 | /* Arm CQ */ | ||
138 | bnx2fc_arm_cq(tgt); | ||
139 | return; | 137 | return; |
140 | 138 | ||
141 | ofld_err: | 139 | ofld_err: |
142 | /* couldn't offload the session. log off from this rport */ | 140 | /* couldn't offload the session. log off from this rport */ |
143 | BNX2FC_TGT_DBG(tgt, "bnx2fc_offload_session - offload error\n"); | 141 | BNX2FC_TGT_DBG(tgt, "bnx2fc_offload_session - offload error\n"); |
144 | lport->tt.rport_logoff(rdata); | ||
145 | /* Free session resources */ | 142 | /* Free session resources */ |
146 | bnx2fc_free_session_resc(hba, tgt); | 143 | bnx2fc_free_session_resc(hba, tgt); |
144 | tgt_init_err: | ||
147 | if (tgt->fcoe_conn_id != -1) | 145 | if (tgt->fcoe_conn_id != -1) |
148 | bnx2fc_free_conn_id(hba, tgt->fcoe_conn_id); | 146 | bnx2fc_free_conn_id(hba, tgt->fcoe_conn_id); |
147 | lport->tt.rport_logoff(rdata); | ||
149 | } | 148 | } |
150 | 149 | ||
151 | void bnx2fc_flush_active_ios(struct bnx2fc_rport *tgt) | 150 | void bnx2fc_flush_active_ios(struct bnx2fc_rport *tgt) |
@@ -624,7 +623,6 @@ static void bnx2fc_free_conn_id(struct bnx2fc_hba *hba, u32 conn_id) | |||
624 | /* called with hba mutex held */ | 623 | /* called with hba mutex held */ |
625 | spin_lock_bh(&hba->hba_lock); | 624 | spin_lock_bh(&hba->hba_lock); |
626 | hba->tgt_ofld_list[conn_id] = NULL; | 625 | hba->tgt_ofld_list[conn_id] = NULL; |
627 | hba->next_conn_id = conn_id; | ||
628 | spin_unlock_bh(&hba->hba_lock); | 626 | spin_unlock_bh(&hba->hba_lock); |
629 | } | 627 | } |
630 | 628 | ||
@@ -791,8 +789,6 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
791 | return 0; | 789 | return 0; |
792 | 790 | ||
793 | mem_alloc_failure: | 791 | mem_alloc_failure: |
794 | bnx2fc_free_session_resc(hba, tgt); | ||
795 | bnx2fc_free_conn_id(hba, tgt->fcoe_conn_id); | ||
796 | return -ENOMEM; | 792 | return -ENOMEM; |
797 | } | 793 | } |
798 | 794 | ||
@@ -807,14 +803,14 @@ mem_alloc_failure: | |||
807 | static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba, | 803 | static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba, |
808 | struct bnx2fc_rport *tgt) | 804 | struct bnx2fc_rport *tgt) |
809 | { | 805 | { |
810 | BNX2FC_TGT_DBG(tgt, "Freeing up session resources\n"); | 806 | void __iomem *ctx_base_ptr; |
811 | 807 | ||
812 | if (tgt->ctx_base) { | 808 | BNX2FC_TGT_DBG(tgt, "Freeing up session resources\n"); |
813 | iounmap(tgt->ctx_base); | ||
814 | tgt->ctx_base = NULL; | ||
815 | } | ||
816 | 809 | ||
817 | spin_lock_bh(&tgt->cq_lock); | 810 | spin_lock_bh(&tgt->cq_lock); |
811 | ctx_base_ptr = tgt->ctx_base; | ||
812 | tgt->ctx_base = NULL; | ||
813 | |||
818 | /* Free LCQ */ | 814 | /* Free LCQ */ |
819 | if (tgt->lcq) { | 815 | if (tgt->lcq) { |
820 | dma_free_coherent(&hba->pcidev->dev, tgt->lcq_mem_size, | 816 | dma_free_coherent(&hba->pcidev->dev, tgt->lcq_mem_size, |
@@ -868,4 +864,7 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba, | |||
868 | tgt->sq = NULL; | 864 | tgt->sq = NULL; |
869 | } | 865 | } |
870 | spin_unlock_bh(&tgt->cq_lock); | 866 | spin_unlock_bh(&tgt->cq_lock); |
867 | |||
868 | if (ctx_base_ptr) | ||
869 | iounmap(ctx_base_ptr); | ||
871 | } | 870 | } |