aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-18 19:54:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-18 19:54:31 -0400
commit961cde93dee2658000ead32abffb8ddf0727abe0 (patch)
tree2419e204132abe2ec2bb7f08bd20042573cc9bd6
parentf82c37e7bb4c4d9b6a476c642d5c2d2efbd6f240 (diff)
parent0d9dc7c8b9b7fa0f53647423b41056ee1beed735 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (69 commits) [SCSI] scsi_transport_fc: Fix synchronization issue while deleting vport [SCSI] bfa: Update the driver version to 2.1.2.1. [SCSI] bfa: Remove unused header files and did some cleanup. [SCSI] bfa: Handle SCSI IO underrun case. [SCSI] bfa: FCS and include file changes. [SCSI] bfa: Modified the portstats get/clear logic [SCSI] bfa: Replace bfa_get_attr() with specific APIs [SCSI] bfa: New portlog entries for events (FIP/FLOGI/FDISC/LOGO). [SCSI] bfa: Rename pport to fcport in BFA FCS. [SCSI] bfa: IOC fixes, check for IOC down condition. [SCSI] bfa: In MSIX mode, ignore spurious RME interrupts when FCoE ports are in FW mismatch state. [SCSI] bfa: Fix Command Queue (CPE) full condition check and ack CPE interrupt. [SCSI] bfa: IOC recovery fix in fcmode. [SCSI] bfa: AEN and byte alignment fixes. [SCSI] bfa: Introduce a link notification state machine. [SCSI] bfa: Added firmware save clear feature for BFA driver. [SCSI] bfa: FCS authentication related changes. [SCSI] bfa: PCI VPD, FIP and include file changes. [SCSI] bfa: Fix to copy fpma MAC when requested by user space application. [SCSI] bfa: RPORT state machine: direct attach mode fix. ...
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c2
-rw-r--r--drivers/scsi/Kconfig6
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c7
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c4
-rw-r--r--drivers/scsi/be2iscsi/be_main.c201
-rw-r--r--drivers/scsi/be2iscsi/be_main.h11
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c14
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h8
-rw-r--r--drivers/scsi/bfa/Makefile8
-rw-r--r--drivers/scsi/bfa/bfa_core.c19
-rw-r--r--drivers/scsi/bfa/bfa_fcport.c1709
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c63
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c75
-rw-r--r--drivers/scsi/bfa/bfa_fcs_port.c11
-rw-r--r--drivers/scsi/bfa/bfa_fcs_uf.c8
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c13
-rw-r--r--drivers/scsi/bfa/bfa_hw_ct.c9
-rw-r--r--drivers/scsi/bfa/bfa_intr.c111
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c762
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h57
-rw-r--r--drivers/scsi/bfa/bfa_ioc_cb.c274
-rw-r--r--drivers/scsi/bfa/bfa_ioc_ct.c423
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.c24
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.h3
-rw-r--r--drivers/scsi/bfa/bfa_ioim.c22
-rw-r--r--drivers/scsi/bfa/bfa_itnim.c30
-rw-r--r--drivers/scsi/bfa/bfa_lps.c134
-rw-r--r--drivers/scsi/bfa/bfa_module.c4
-rw-r--r--drivers/scsi/bfa/bfa_modules_priv.h2
-rw-r--r--drivers/scsi/bfa/bfa_port_priv.h57
-rw-r--r--drivers/scsi/bfa/bfa_priv.h2
-rw-r--r--drivers/scsi/bfa/bfa_rport.c26
-rw-r--r--drivers/scsi/bfa/bfa_trcmod_priv.h62
-rw-r--r--drivers/scsi/bfa/bfa_tskim.c14
-rw-r--r--drivers/scsi/bfa/bfad.c208
-rw-r--r--drivers/scsi/bfa/bfad_attr.c76
-rw-r--r--drivers/scsi/bfa/bfad_attr.h9
-rw-r--r--drivers/scsi/bfa/bfad_drv.h35
-rw-r--r--drivers/scsi/bfa/bfad_im.c53
-rw-r--r--drivers/scsi/bfa/bfad_im.h5
-rw-r--r--drivers/scsi/bfa/bfad_intr.c11
-rw-r--r--drivers/scsi/bfa/fabric.c59
-rw-r--r--drivers/scsi/bfa/fcbuild.h6
-rw-r--r--drivers/scsi/bfa/fcpim.c51
-rw-r--r--drivers/scsi/bfa/fcs_fabric.h2
-rw-r--r--drivers/scsi/bfa/fcs_fcpim.h5
-rw-r--r--drivers/scsi/bfa/fcs_lport.h7
-rw-r--r--drivers/scsi/bfa/fcs_port.h3
-rw-r--r--drivers/scsi/bfa/fcs_rport.h3
-rw-r--r--drivers/scsi/bfa/fcs_uf.h3
-rw-r--r--drivers/scsi/bfa/fcs_vport.h8
-rw-r--r--drivers/scsi/bfa/fdmi.c79
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen.h50
-rw-r--r--drivers/scsi/bfa/include/bfa.h22
-rw-r--r--drivers/scsi/bfa/include/bfa_svc.h101
-rw-r--r--drivers/scsi/bfa/include/bfa_timer.h2
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi.h4
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_cbreg.h16
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ctreg.h26
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ioc.h2
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_lps.h8
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_pport.h172
-rw-r--r--drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h4
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_log.h2
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_plog.h9
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_sm.h8
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_aen.h10
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_auth.h22
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_cee.h14
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_driver.h3
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ethport.h1
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_fcport.h94
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_im_common.h32
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_im_team.h72
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ioc.h3
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h12
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_lport.h4
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_mfg.h111
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_port.h19
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pport.h151
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_status.h17
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h1
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs.h5
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h8
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_hal.h6
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_linux.h16
-rw-r--r--drivers/scsi/bfa/include/protocol/fc.h5
-rw-r--r--drivers/scsi/bfa/include/protocol/pcifw.h75
-rw-r--r--drivers/scsi/bfa/loop.c2
-rw-r--r--drivers/scsi/bfa/lport_api.c5
-rw-r--r--drivers/scsi/bfa/ms.c29
-rw-r--r--drivers/scsi/bfa/ns.c36
-rw-r--r--drivers/scsi/bfa/rport.c91
-rw-r--r--drivers/scsi/bfa/rport_api.c2
-rw-r--r--drivers/scsi/bfa/rport_ftrs.c12
-rw-r--r--drivers/scsi/bfa/scn.c10
-rw-r--r--drivers/scsi/bfa/vport.c86
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c2
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_emc.c6
-rw-r--r--drivers/scsi/hpsa.c330
-rw-r--r--drivers/scsi/hpsa.h7
-rw-r--r--drivers/scsi/hpsa_cmd.h20
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c27
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c19
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.h1
-rw-r--r--drivers/scsi/ibmvscsi/iseries_vscsi.c6
-rw-r--r--drivers/scsi/ibmvscsi/rpa_vscsi.c13
-rw-r--r--drivers/scsi/ipr.c1756
-rw-r--r--drivers/scsi/ipr.h467
-rw-r--r--drivers/scsi/iscsi_tcp.c2
-rw-r--r--drivers/scsi/libiscsi.c23
-rw-r--r--drivers/scsi/lpfc/lpfc.h10
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.c332
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.h12
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h7
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c142
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c527
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c277
-rw-r--r--drivers/scsi/lpfc/lpfc_logmsg.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c8
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c49
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c413
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h38
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c7
-rw-r--r--drivers/scsi/osd/osd_initiator.c4
-rw-r--r--drivers/scsi/raid_class.c2
-rw-r--r--drivers/scsi/scsi_transport_fc.c24
-rw-r--r--drivers/scsi/sd.c4
-rw-r--r--include/scsi/libiscsi.h3
133 files changed, 7204 insertions, 3525 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 71237f8f78f7..e78af36d3a0e 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -613,7 +613,7 @@ static struct scsi_host_template iscsi_iser_sht = {
613 .cmd_per_lun = ISER_DEF_CMD_PER_LUN, 613 .cmd_per_lun = ISER_DEF_CMD_PER_LUN,
614 .eh_abort_handler = iscsi_eh_abort, 614 .eh_abort_handler = iscsi_eh_abort,
615 .eh_device_reset_handler= iscsi_eh_device_reset, 615 .eh_device_reset_handler= iscsi_eh_device_reset,
616 .eh_target_reset_handler= iscsi_eh_target_reset, 616 .eh_target_reset_handler = iscsi_eh_recover_target,
617 .target_alloc = iscsi_target_alloc, 617 .target_alloc = iscsi_target_alloc,
618 .use_clustering = DISABLE_CLUSTERING, 618 .use_clustering = DISABLE_CLUSTERING,
619 .proc_name = "iscsi_iser", 619 .proc_name = "iscsi_iser",
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 9191d1ea6451..75f2336807cb 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1,9 +1,15 @@
1menu "SCSI device support" 1menu "SCSI device support"
2 2
3config SCSI_MOD
4 tristate
5 default y if SCSI=n || SCSI=y
6 default m if SCSI=m
7
3config RAID_ATTRS 8config RAID_ATTRS
4 tristate "RAID Transport Class" 9 tristate "RAID Transport Class"
5 default n 10 default n
6 depends on BLOCK 11 depends on BLOCK
12 depends on SCSI_MOD
7 ---help--- 13 ---help---
8 Provides RAID 14 Provides RAID
9 15
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 67098578fba4..cda6642c7368 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -32,18 +32,11 @@ void be_mcc_notify(struct beiscsi_hba *phba)
32unsigned int alloc_mcc_tag(struct beiscsi_hba *phba) 32unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
33{ 33{
34 unsigned int tag = 0; 34 unsigned int tag = 0;
35 unsigned int num = 0;
36 35
37mcc_tag_rdy:
38 if (phba->ctrl.mcc_tag_available) { 36 if (phba->ctrl.mcc_tag_available) {
39 tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index]; 37 tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
40 phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0; 38 phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
41 phba->ctrl.mcc_numtag[tag] = 0; 39 phba->ctrl.mcc_numtag[tag] = 0;
42 } else {
43 udelay(100);
44 num++;
45 if (num < mcc_timeout)
46 goto mcc_tag_rdy;
47 } 40 }
48 if (tag) { 41 if (tag) {
49 phba->ctrl.mcc_tag_available--; 42 phba->ctrl.mcc_tag_available--;
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 29a3aaf35f9f..c3928cb8b042 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -482,7 +482,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
482 tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep); 482 tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep);
483 if (!tag) { 483 if (!tag) {
484 SE_DEBUG(DBG_LVL_1, 484 SE_DEBUG(DBG_LVL_1,
485 "mgmt_invalidate_connection Failed for cid=%d \n", 485 "mgmt_open_connection Failed for cid=%d \n",
486 beiscsi_ep->ep_cid); 486 beiscsi_ep->ep_cid);
487 } else { 487 } else {
488 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 488 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
@@ -701,7 +701,7 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
701 if (!tag) { 701 if (!tag) {
702 SE_DEBUG(DBG_LVL_1, 702 SE_DEBUG(DBG_LVL_1,
703 "mgmt_invalidate_connection Failed for cid=%d \n", 703 "mgmt_invalidate_connection Failed for cid=%d \n",
704 beiscsi_ep->ep_cid); 704 beiscsi_ep->ep_cid);
705 } else { 705 } else {
706 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 706 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
707 phba->ctrl.mcc_numtag[tag]); 707 phba->ctrl.mcc_numtag[tag]);
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 7c22616ab141..fcfb29e02d8a 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -58,6 +58,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
58 return 0; 58 return 0;
59} 59}
60 60
61static int beiscsi_eh_abort(struct scsi_cmnd *sc)
62{
63 struct iscsi_cls_session *cls_session;
64 struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
65 struct beiscsi_io_task *aborted_io_task;
66 struct iscsi_conn *conn;
67 struct beiscsi_conn *beiscsi_conn;
68 struct beiscsi_hba *phba;
69 struct iscsi_session *session;
70 struct invalidate_command_table *inv_tbl;
71 unsigned int cid, tag, num_invalidate;
72
73 cls_session = starget_to_session(scsi_target(sc->device));
74 session = cls_session->dd_data;
75
76 spin_lock_bh(&session->lock);
77 if (!aborted_task || !aborted_task->sc) {
78 /* we raced */
79 spin_unlock_bh(&session->lock);
80 return SUCCESS;
81 }
82
83 aborted_io_task = aborted_task->dd_data;
84 if (!aborted_io_task->scsi_cmnd) {
85 /* raced or invalid command */
86 spin_unlock_bh(&session->lock);
87 return SUCCESS;
88 }
89 spin_unlock_bh(&session->lock);
90 conn = aborted_task->conn;
91 beiscsi_conn = conn->dd_data;
92 phba = beiscsi_conn->phba;
93
94 /* invalidate iocb */
95 cid = beiscsi_conn->beiscsi_conn_cid;
96 inv_tbl = phba->inv_tbl;
97 memset(inv_tbl, 0x0, sizeof(*inv_tbl));
98 inv_tbl->cid = cid;
99 inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
100 num_invalidate = 1;
101 tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
102 if (!tag) {
103 shost_printk(KERN_WARNING, phba->shost,
104 "mgmt_invalidate_icds could not be"
105 " submitted\n");
106 return FAILED;
107 } else {
108 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
109 phba->ctrl.mcc_numtag[tag]);
110 free_mcc_tag(&phba->ctrl, tag);
111 }
112
113 return iscsi_eh_abort(sc);
114}
115
116static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
117{
118 struct iscsi_task *abrt_task;
119 struct beiscsi_io_task *abrt_io_task;
120 struct iscsi_conn *conn;
121 struct beiscsi_conn *beiscsi_conn;
122 struct beiscsi_hba *phba;
123 struct iscsi_session *session;
124 struct iscsi_cls_session *cls_session;
125 struct invalidate_command_table *inv_tbl;
126 unsigned int cid, tag, i, num_invalidate;
127 int rc = FAILED;
128
129 /* invalidate iocbs */
130 cls_session = starget_to_session(scsi_target(sc->device));
131 session = cls_session->dd_data;
132 spin_lock_bh(&session->lock);
133 if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
134 goto unlock;
135
136 conn = session->leadconn;
137 beiscsi_conn = conn->dd_data;
138 phba = beiscsi_conn->phba;
139 cid = beiscsi_conn->beiscsi_conn_cid;
140 inv_tbl = phba->inv_tbl;
141 memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN);
142 num_invalidate = 0;
143 for (i = 0; i < conn->session->cmds_max; i++) {
144 abrt_task = conn->session->cmds[i];
145 abrt_io_task = abrt_task->dd_data;
146 if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE)
147 continue;
148
149 if (abrt_task->sc->device->lun != abrt_task->sc->device->lun)
150 continue;
151
152 inv_tbl->cid = cid;
153 inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index;
154 num_invalidate++;
155 inv_tbl++;
156 }
157 spin_unlock_bh(&session->lock);
158 inv_tbl = phba->inv_tbl;
159
160 tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
161 if (!tag) {
162 shost_printk(KERN_WARNING, phba->shost,
163 "mgmt_invalidate_icds could not be"
164 " submitted\n");
165 return FAILED;
166 } else {
167 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
168 phba->ctrl.mcc_numtag[tag]);
169 free_mcc_tag(&phba->ctrl, tag);
170 }
171
172 return iscsi_eh_device_reset(sc);
173unlock:
174 spin_unlock_bh(&session->lock);
175 return rc;
176}
177
61/*------------------- PCI Driver operations and data ----------------- */ 178/*------------------- PCI Driver operations and data ----------------- */
62static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { 179static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
63 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, 180 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
@@ -74,12 +191,12 @@ static struct scsi_host_template beiscsi_sht = {
74 .name = "ServerEngines 10Gbe open-iscsi Initiator Driver", 191 .name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
75 .proc_name = DRV_NAME, 192 .proc_name = DRV_NAME,
76 .queuecommand = iscsi_queuecommand, 193 .queuecommand = iscsi_queuecommand,
77 .eh_abort_handler = iscsi_eh_abort,
78 .change_queue_depth = iscsi_change_queue_depth, 194 .change_queue_depth = iscsi_change_queue_depth,
79 .slave_configure = beiscsi_slave_configure, 195 .slave_configure = beiscsi_slave_configure,
80 .target_alloc = iscsi_target_alloc, 196 .target_alloc = iscsi_target_alloc,
81 .eh_device_reset_handler = iscsi_eh_device_reset, 197 .eh_abort_handler = beiscsi_eh_abort,
82 .eh_target_reset_handler = iscsi_eh_target_reset, 198 .eh_device_reset_handler = beiscsi_eh_device_reset,
199 .eh_target_reset_handler = iscsi_eh_session_reset,
83 .sg_tablesize = BEISCSI_SGLIST_ELEMENTS, 200 .sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
84 .can_queue = BE2_IO_DEPTH, 201 .can_queue = BE2_IO_DEPTH,
85 .this_id = -1, 202 .this_id = -1,
@@ -242,7 +359,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba)
242 + BE2_TMFS 359 + BE2_TMFS
243 + BE2_NOPOUT_REQ)); 360 + BE2_NOPOUT_REQ));
244 phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; 361 phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count;
245 phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count;; 362 phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2;
246 phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;; 363 phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;;
247 phba->params.num_sge_per_io = BE2_SGE; 364 phba->params.num_sge_per_io = BE2_SGE;
248 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; 365 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
@@ -946,14 +1063,18 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
946 case HWH_TYPE_IO: 1063 case HWH_TYPE_IO:
947 case HWH_TYPE_IO_RD: 1064 case HWH_TYPE_IO_RD:
948 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == 1065 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
949 ISCSI_OP_NOOP_OUT) { 1066 ISCSI_OP_NOOP_OUT)
950 be_complete_nopin_resp(beiscsi_conn, task, psol); 1067 be_complete_nopin_resp(beiscsi_conn, task, psol);
951 } else 1068 else
952 be_complete_io(beiscsi_conn, task, psol); 1069 be_complete_io(beiscsi_conn, task, psol);
953 break; 1070 break;
954 1071
955 case HWH_TYPE_LOGOUT: 1072 case HWH_TYPE_LOGOUT:
956 be_complete_logout(beiscsi_conn, task, psol); 1073 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
1074 be_complete_logout(beiscsi_conn, task, psol);
1075 else
1076 be_complete_tmf(beiscsi_conn, task, psol);
1077
957 break; 1078 break;
958 1079
959 case HWH_TYPE_LOGIN: 1080 case HWH_TYPE_LOGIN:
@@ -962,10 +1083,6 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
962 "- Solicited path \n"); 1083 "- Solicited path \n");
963 break; 1084 break;
964 1085
965 case HWH_TYPE_TMF:
966 be_complete_tmf(beiscsi_conn, task, psol);
967 break;
968
969 case HWH_TYPE_NOP: 1086 case HWH_TYPE_NOP:
970 be_complete_nopin_resp(beiscsi_conn, task, psol); 1087 be_complete_nopin_resp(beiscsi_conn, task, psol);
971 break; 1088 break;
@@ -2052,7 +2169,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
2052 num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / 2169 num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
2053 ((sizeof(struct iscsi_wrb) * 2170 ((sizeof(struct iscsi_wrb) *
2054 phba->params.wrbs_per_cxn)); 2171 phba->params.wrbs_per_cxn));
2055 for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) { 2172 for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
2056 pwrb_context = &phwi_ctrlr->wrb_context[index]; 2173 pwrb_context = &phwi_ctrlr->wrb_context[index];
2057 if (num_cxn_wrb) { 2174 if (num_cxn_wrb) {
2058 for (j = 0; j < phba->params.wrbs_per_cxn; j++) { 2175 for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
@@ -3073,14 +3190,18 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
3073 reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; 3190 reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
3074 SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr); 3191 SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
3075 iowrite32(reg, addr); 3192 iowrite32(reg, addr);
3076 for (i = 0; i <= phba->num_cpus; i++) { 3193 if (!phba->msix_enabled) {
3077 eq = &phwi_context->be_eq[i].q; 3194 eq = &phwi_context->be_eq[0].q;
3078 SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); 3195 SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
3079 hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); 3196 hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
3197 } else {
3198 for (i = 0; i <= phba->num_cpus; i++) {
3199 eq = &phwi_context->be_eq[i].q;
3200 SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
3201 hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
3202 }
3080 } 3203 }
3081 } else 3204 }
3082 shost_printk(KERN_WARNING, phba->shost,
3083 "In hwi_enable_intr, Not Enabled \n");
3084 return true; 3205 return true;
3085} 3206}
3086 3207
@@ -3476,19 +3597,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
3476 3597
3477static int beiscsi_mtask(struct iscsi_task *task) 3598static int beiscsi_mtask(struct iscsi_task *task)
3478{ 3599{
3479 struct beiscsi_io_task *aborted_io_task, *io_task = task->dd_data; 3600 struct beiscsi_io_task *io_task = task->dd_data;
3480 struct iscsi_conn *conn = task->conn; 3601 struct iscsi_conn *conn = task->conn;
3481 struct beiscsi_conn *beiscsi_conn = conn->dd_data; 3602 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
3482 struct beiscsi_hba *phba = beiscsi_conn->phba; 3603 struct beiscsi_hba *phba = beiscsi_conn->phba;
3483 struct iscsi_session *session;
3484 struct iscsi_wrb *pwrb = NULL; 3604 struct iscsi_wrb *pwrb = NULL;
3485 struct hwi_controller *phwi_ctrlr;
3486 struct hwi_wrb_context *pwrb_context;
3487 struct wrb_handle *pwrb_handle;
3488 unsigned int doorbell = 0; 3605 unsigned int doorbell = 0;
3489 unsigned int i, cid; 3606 unsigned int cid;
3490 struct iscsi_task *aborted_task;
3491 unsigned int tag;
3492 3607
3493 cid = beiscsi_conn->beiscsi_conn_cid; 3608 cid = beiscsi_conn->beiscsi_conn_cid;
3494 pwrb = io_task->pwrb_handle->pwrb; 3609 pwrb = io_task->pwrb_handle->pwrb;
@@ -3499,6 +3614,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
3499 io_task->pwrb_handle->wrb_index); 3614 io_task->pwrb_handle->wrb_index);
3500 AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, 3615 AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb,
3501 io_task->psgl_handle->sgl_index); 3616 io_task->psgl_handle->sgl_index);
3617
3502 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { 3618 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
3503 case ISCSI_OP_LOGIN: 3619 case ISCSI_OP_LOGIN:
3504 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, 3620 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
@@ -3523,33 +3639,6 @@ static int beiscsi_mtask(struct iscsi_task *task)
3523 hwi_write_buffer(pwrb, task); 3639 hwi_write_buffer(pwrb, task);
3524 break; 3640 break;
3525 case ISCSI_OP_SCSI_TMFUNC: 3641 case ISCSI_OP_SCSI_TMFUNC:
3526 session = conn->session;
3527 i = ((struct iscsi_tm *)task->hdr)->rtt;
3528 phwi_ctrlr = phba->phwi_ctrlr;
3529 pwrb_context = &phwi_ctrlr->wrb_context[cid -
3530 phba->fw_config.iscsi_cid_start];
3531 pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i)
3532 >> 16];
3533 aborted_task = pwrb_handle->pio_handle;
3534 if (!aborted_task)
3535 return 0;
3536
3537 aborted_io_task = aborted_task->dd_data;
3538 if (!aborted_io_task->scsi_cmnd)
3539 return 0;
3540
3541 tag = mgmt_invalidate_icds(phba,
3542 aborted_io_task->psgl_handle->sgl_index,
3543 cid);
3544 if (!tag) {
3545 shost_printk(KERN_WARNING, phba->shost,
3546 "mgmt_invalidate_icds could not be"
3547 " submitted\n");
3548 } else {
3549 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
3550 phba->ctrl.mcc_numtag[tag]);
3551 free_mcc_tag(&phba->ctrl, tag);
3552 }
3553 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, 3642 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3554 INI_TMF_CMD); 3643 INI_TMF_CMD);
3555 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3644 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
@@ -3558,7 +3647,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
3558 case ISCSI_OP_LOGOUT: 3647 case ISCSI_OP_LOGOUT:
3559 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3648 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3560 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, 3649 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3561 HWH_TYPE_LOGOUT); 3650 HWH_TYPE_LOGOUT);
3562 hwi_write_buffer(pwrb, task); 3651 hwi_write_buffer(pwrb, task);
3563 break; 3652 break;
3564 3653
@@ -3584,17 +3673,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
3584 3673
3585static int beiscsi_task_xmit(struct iscsi_task *task) 3674static int beiscsi_task_xmit(struct iscsi_task *task)
3586{ 3675{
3587 struct iscsi_conn *conn = task->conn;
3588 struct beiscsi_io_task *io_task = task->dd_data; 3676 struct beiscsi_io_task *io_task = task->dd_data;
3589 struct scsi_cmnd *sc = task->sc; 3677 struct scsi_cmnd *sc = task->sc;
3590 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
3591 struct scatterlist *sg; 3678 struct scatterlist *sg;
3592 int num_sg; 3679 int num_sg;
3593 unsigned int writedir = 0, xferlen = 0; 3680 unsigned int writedir = 0, xferlen = 0;
3594 3681
3595 SE_DEBUG(DBG_LVL_4, "\n cid=%d In beiscsi_task_xmit task=%p conn=%p \t"
3596 "beiscsi_conn=%p \n", beiscsi_conn->beiscsi_conn_cid,
3597 task, conn, beiscsi_conn);
3598 if (!sc) 3682 if (!sc)
3599 return beiscsi_mtask(task); 3683 return beiscsi_mtask(task);
3600 3684
@@ -3699,7 +3783,6 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3699 " Failed in beiscsi_hba_alloc \n"); 3783 " Failed in beiscsi_hba_alloc \n");
3700 goto disable_pci; 3784 goto disable_pci;
3701 } 3785 }
3702 SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba);
3703 3786
3704 switch (pcidev->device) { 3787 switch (pcidev->device) {
3705 case BE_DEVICE_ID1: 3788 case BE_DEVICE_ID1:
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index c53a80ab796c..87ec21280a37 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -257,6 +257,11 @@ struct hba_parameters {
257 unsigned int num_sge; 257 unsigned int num_sge;
258}; 258};
259 259
260struct invalidate_command_table {
261 unsigned short icd;
262 unsigned short cid;
263} __packed;
264
260struct beiscsi_hba { 265struct beiscsi_hba {
261 struct hba_parameters params; 266 struct hba_parameters params;
262 struct hwi_controller *phwi_ctrlr; 267 struct hwi_controller *phwi_ctrlr;
@@ -329,6 +334,8 @@ struct beiscsi_hba {
329 struct work_struct work_cqs; /* The work being queued */ 334 struct work_struct work_cqs; /* The work being queued */
330 struct be_ctrl_info ctrl; 335 struct be_ctrl_info ctrl;
331 unsigned int generation; 336 unsigned int generation;
337 struct invalidate_command_table inv_tbl[128];
338
332}; 339};
333 340
334struct beiscsi_session { 341struct beiscsi_session {
@@ -491,8 +498,6 @@ struct hwi_async_entry {
491 struct list_head data_busy_list; 498 struct list_head data_busy_list;
492}; 499};
493 500
494#define BE_MIN_ASYNC_ENTRIES 128
495
496struct hwi_async_pdu_context { 501struct hwi_async_pdu_context {
497 struct { 502 struct {
498 struct be_bus_address pa_base; 503 struct be_bus_address pa_base;
@@ -533,7 +538,7 @@ struct hwi_async_pdu_context {
533 * This is a varying size list! Do not add anything 538 * This is a varying size list! Do not add anything
534 * after this entry!! 539 * after this entry!!
535 */ 540 */
536 struct hwi_async_entry async_entry[BE_MIN_ASYNC_ENTRIES]; 541 struct hwi_async_entry async_entry[BE2_MAX_SESSIONS * 2];
537}; 542};
538 543
539#define PDUCQE_CODE_MASK 0x0000003F 544#define PDUCQE_CODE_MASK 0x0000003F
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 317bcd042ced..72617b650a7e 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -145,14 +145,15 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
145} 145}
146 146
147unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, 147unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
148 unsigned int icd, unsigned int cid) 148 struct invalidate_command_table *inv_tbl,
149 unsigned int num_invalidate, unsigned int cid)
149{ 150{
150 struct be_dma_mem nonemb_cmd; 151 struct be_dma_mem nonemb_cmd;
151 struct be_ctrl_info *ctrl = &phba->ctrl; 152 struct be_ctrl_info *ctrl = &phba->ctrl;
152 struct be_mcc_wrb *wrb; 153 struct be_mcc_wrb *wrb;
153 struct be_sge *sge; 154 struct be_sge *sge;
154 struct invalidate_commands_params_in *req; 155 struct invalidate_commands_params_in *req;
155 unsigned int tag = 0; 156 unsigned int i, tag = 0;
156 157
157 spin_lock(&ctrl->mbox_lock); 158 spin_lock(&ctrl->mbox_lock);
158 tag = alloc_mcc_tag(phba); 159 tag = alloc_mcc_tag(phba);
@@ -183,9 +184,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
183 sizeof(*req)); 184 sizeof(*req));
184 req->ref_handle = 0; 185 req->ref_handle = 0;
185 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; 186 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
186 req->icd_count = 0; 187 for (i = 0; i < num_invalidate; i++) {
187 req->table[req->icd_count].icd = icd; 188 req->table[i].icd = inv_tbl->icd;
188 req->table[req->icd_count].cid = cid; 189 req->table[i].cid = inv_tbl->cid;
190 req->icd_count++;
191 inv_tbl++;
192 }
189 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); 193 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
190 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); 194 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
191 sge->len = cpu_to_le32(nonemb_cmd.size); 195 sge->len = cpu_to_le32(nonemb_cmd.size);
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index ecead6a5aa56..3d316b82feb1 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
94 unsigned short cid, 94 unsigned short cid,
95 unsigned int upload_flag); 95 unsigned int upload_flag);
96unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, 96unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
97 unsigned int icd, unsigned int cid); 97 struct invalidate_command_table *inv_tbl,
98 unsigned int num_invalidate, unsigned int cid);
98 99
99struct iscsi_invalidate_connection_params_in { 100struct iscsi_invalidate_connection_params_in {
100 struct be_cmd_req_hdr hdr; 101 struct be_cmd_req_hdr hdr;
@@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params {
116 struct iscsi_invalidate_connection_params_out response; 117 struct iscsi_invalidate_connection_params_out response;
117} __packed; 118} __packed;
118 119
119struct invalidate_command_table {
120 unsigned short icd;
121 unsigned short cid;
122} __packed;
123
124struct invalidate_commands_params_in { 120struct invalidate_commands_params_in {
125 struct be_cmd_req_hdr hdr; 121 struct be_cmd_req_hdr hdr;
126 unsigned int ref_handle; 122 unsigned int ref_handle;
diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile
index 1d6009490d1c..17e06cae71b2 100644
--- a/drivers/scsi/bfa/Makefile
+++ b/drivers/scsi/bfa/Makefile
@@ -2,14 +2,14 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
2 2
3bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o 3bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
4 4
5bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o 5bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o
6bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o 6bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
7bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o 7bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
8bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o 8bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o
9bfa-y += bfa_csdebug.o bfa_sm.o plog.o 9bfa-y += bfa_csdebug.o bfa_sm.o plog.o
10 10
11bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o 11bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
12bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o 12bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o
13bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o 13bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o
14 14
15ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna 15ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna -DBFA_PERF_BUILD
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 44e2d1155c51..0c08e185a766 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -385,6 +385,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
385} 385}
386 386
387/** 387/**
388 * Clear the saved firmware trace information of an IOC.
389 */
390void
391bfa_debug_fwsave_clear(struct bfa_s *bfa)
392{
393 bfa_ioc_debug_fwsave_clear(&bfa->ioc);
394}
395
396/**
388 * Fetch firmware trace data. 397 * Fetch firmware trace data.
389 * 398 *
390 * @param[in] bfa BFA instance 399 * @param[in] bfa BFA instance
@@ -399,4 +408,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
399{ 408{
400 return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen); 409 return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
401} 410}
411
412/**
413 * Reset hw semaphore & usage cnt regs and initialize.
414 */
415void
416bfa_chip_reset(struct bfa_s *bfa)
417{
418 bfa_ioc_ownership_reset(&bfa->ioc);
419 bfa_ioc_pll_init(&bfa->ioc);
420}
402#endif 421#endif
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c
index aef648b55dfc..c589488db0c1 100644
--- a/drivers/scsi/bfa/bfa_fcport.c
+++ b/drivers/scsi/bfa/bfa_fcport.c
@@ -23,40 +23,33 @@
23#include <cs/bfa_plog.h> 23#include <cs/bfa_plog.h>
24#include <aen/bfa_aen_port.h> 24#include <aen/bfa_aen_port.h>
25 25
26BFA_TRC_FILE(HAL, PPORT); 26BFA_TRC_FILE(HAL, FCPORT);
27BFA_MODULE(pport); 27BFA_MODULE(fcport);
28
29#define bfa_pport_callback(__pport, __event) do { \
30 if ((__pport)->bfa->fcs) { \
31 (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \
32 } else { \
33 (__pport)->hcb_event = (__event); \
34 bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \
35 __bfa_cb_port_event, (__pport)); \
36 } \
37} while (0)
38 28
39/* 29/*
40 * The port is considered disabled if corresponding physical port or IOC are 30 * The port is considered disabled if corresponding physical port or IOC are
41 * disabled explicitly 31 * disabled explicitly
42 */ 32 */
43#define BFA_PORT_IS_DISABLED(bfa) \ 33#define BFA_PORT_IS_DISABLED(bfa) \
44 ((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \ 34 ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
45 (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE)) 35 (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
46 36
47/* 37/*
48 * forward declarations 38 * forward declarations
49 */ 39 */
50static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port); 40static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
51static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port); 41static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport);
52static void bfa_pport_update_linkinfo(struct bfa_pport_s *pport); 42static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport);
53static void bfa_pport_reset_linkinfo(struct bfa_pport_s *pport); 43static void bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport);
54static void bfa_pport_set_wwns(struct bfa_pport_s *port); 44static void bfa_fcport_set_wwns(struct bfa_fcport_s *fcport);
55static void __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete); 45static void __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete);
56static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete); 46static void bfa_fcport_callback(struct bfa_fcport_s *fcport,
57static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete); 47 enum bfa_pport_linkstate event);
58static void bfa_port_stats_timeout(void *cbarg); 48static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln,
59static void bfa_port_stats_clr_timeout(void *cbarg); 49 enum bfa_pport_linkstate event);
50static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete);
51static void bfa_fcport_stats_get_timeout(void *cbarg);
52static void bfa_fcport_stats_clr_timeout(void *cbarg);
60 53
61/** 54/**
62 * bfa_pport_private 55 * bfa_pport_private
@@ -65,111 +58,114 @@ static void bfa_port_stats_clr_timeout(void *cbarg);
65/** 58/**
66 * BFA port state machine events 59 * BFA port state machine events
67 */ 60 */
68enum bfa_pport_sm_event { 61enum bfa_fcport_sm_event {
69 BFA_PPORT_SM_START = 1, /* start port state machine */ 62 BFA_FCPORT_SM_START = 1, /* start port state machine */
70 BFA_PPORT_SM_STOP = 2, /* stop port state machine */ 63 BFA_FCPORT_SM_STOP = 2, /* stop port state machine */
71 BFA_PPORT_SM_ENABLE = 3, /* enable port */ 64 BFA_FCPORT_SM_ENABLE = 3, /* enable port */
72 BFA_PPORT_SM_DISABLE = 4, /* disable port state machine */ 65 BFA_FCPORT_SM_DISABLE = 4, /* disable port state machine */
73 BFA_PPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */ 66 BFA_FCPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */
74 BFA_PPORT_SM_LINKUP = 6, /* firmware linkup event */ 67 BFA_FCPORT_SM_LINKUP = 6, /* firmware linkup event */
75 BFA_PPORT_SM_LINKDOWN = 7, /* firmware linkup down */ 68 BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */
76 BFA_PPORT_SM_QRESUME = 8, /* CQ space available */ 69 BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */
77 BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */ 70 BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */
78}; 71};
79 72
80static void bfa_pport_sm_uninit(struct bfa_pport_s *pport, 73/**
81 enum bfa_pport_sm_event event); 74 * BFA port link notification state machine events
82static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, 75 */
83 enum bfa_pport_sm_event event); 76
84static void bfa_pport_sm_enabling(struct bfa_pport_s *pport, 77enum bfa_fcport_ln_sm_event {
85 enum bfa_pport_sm_event event); 78 BFA_FCPORT_LN_SM_LINKUP = 1, /* linkup event */
86static void bfa_pport_sm_linkdown(struct bfa_pport_s *pport, 79 BFA_FCPORT_LN_SM_LINKDOWN = 2, /* linkdown event */
87 enum bfa_pport_sm_event event); 80 BFA_FCPORT_LN_SM_NOTIFICATION = 3 /* done notification */
88static void bfa_pport_sm_linkup(struct bfa_pport_s *pport, 81};
89 enum bfa_pport_sm_event event); 82
90static void bfa_pport_sm_disabling(struct bfa_pport_s *pport, 83static void bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
91 enum bfa_pport_sm_event event); 84 enum bfa_fcport_sm_event event);
92static void bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport, 85static void bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
93 enum bfa_pport_sm_event event); 86 enum bfa_fcport_sm_event event);
94static void bfa_pport_sm_disabled(struct bfa_pport_s *pport, 87static void bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
95 enum bfa_pport_sm_event event); 88 enum bfa_fcport_sm_event event);
96static void bfa_pport_sm_stopped(struct bfa_pport_s *pport, 89static void bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
97 enum bfa_pport_sm_event event); 90 enum bfa_fcport_sm_event event);
98static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport, 91static void bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
99 enum bfa_pport_sm_event event); 92 enum bfa_fcport_sm_event event);
100static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport, 93static void bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
101 enum bfa_pport_sm_event event); 94 enum bfa_fcport_sm_event event);
95static void bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
96 enum bfa_fcport_sm_event event);
97static void bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
98 enum bfa_fcport_sm_event event);
99static void bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
100 enum bfa_fcport_sm_event event);
101static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
102 enum bfa_fcport_sm_event event);
103static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
104 enum bfa_fcport_sm_event event);
105
106static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
107 enum bfa_fcport_ln_sm_event event);
108static void bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
109 enum bfa_fcport_ln_sm_event event);
110static void bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
111 enum bfa_fcport_ln_sm_event event);
112static void bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
113 enum bfa_fcport_ln_sm_event event);
114static void bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
115 enum bfa_fcport_ln_sm_event event);
116static void bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
117 enum bfa_fcport_ln_sm_event event);
118static void bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
119 enum bfa_fcport_ln_sm_event event);
102 120
103static struct bfa_sm_table_s hal_pport_sm_table[] = { 121static struct bfa_sm_table_s hal_pport_sm_table[] = {
104 {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT}, 122 {BFA_SM(bfa_fcport_sm_uninit), BFA_PPORT_ST_UNINIT},
105 {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT}, 123 {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
106 {BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING}, 124 {BFA_SM(bfa_fcport_sm_enabling), BFA_PPORT_ST_ENABLING},
107 {BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN}, 125 {BFA_SM(bfa_fcport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
108 {BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP}, 126 {BFA_SM(bfa_fcport_sm_linkup), BFA_PPORT_ST_LINKUP},
109 {BFA_SM(bfa_pport_sm_disabling_qwait), 127 {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PPORT_ST_DISABLING_QWAIT},
110 BFA_PPORT_ST_DISABLING_QWAIT}, 128 {BFA_SM(bfa_fcport_sm_disabling), BFA_PPORT_ST_DISABLING},
111 {BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING}, 129 {BFA_SM(bfa_fcport_sm_disabled), BFA_PPORT_ST_DISABLED},
112 {BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED}, 130 {BFA_SM(bfa_fcport_sm_stopped), BFA_PPORT_ST_STOPPED},
113 {BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED}, 131 {BFA_SM(bfa_fcport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
114 {BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN}, 132 {BFA_SM(bfa_fcport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
115 {BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
116}; 133};
117 134
118static void 135static void
119bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event) 136bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
120{ 137{
121 union bfa_aen_data_u aen_data; 138 union bfa_aen_data_u aen_data;
122 struct bfa_log_mod_s *logmod = pport->bfa->logm; 139 struct bfa_log_mod_s *logmod = fcport->bfa->logm;
123 wwn_t pwwn = pport->pwwn; 140 wwn_t pwwn = fcport->pwwn;
124 char pwwn_ptr[BFA_STRING_32]; 141 char pwwn_ptr[BFA_STRING_32];
125 struct bfa_ioc_attr_s ioc_attr;
126 142
143 memset(&aen_data, 0, sizeof(aen_data));
127 wwn2str(pwwn_ptr, pwwn); 144 wwn2str(pwwn_ptr, pwwn);
128 switch (event) { 145 bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), pwwn_ptr);
129 case BFA_PORT_AEN_ONLINE:
130 bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr);
131 break;
132 case BFA_PORT_AEN_OFFLINE:
133 bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr);
134 break;
135 case BFA_PORT_AEN_ENABLE:
136 bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr);
137 break;
138 case BFA_PORT_AEN_DISABLE:
139 bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr);
140 break;
141 case BFA_PORT_AEN_DISCONNECT:
142 bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr);
143 break;
144 case BFA_PORT_AEN_QOS_NEG:
145 bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr);
146 break;
147 default:
148 break;
149 }
150 146
151 bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr); 147 aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
152 aen_data.port.ioc_type = ioc_attr.ioc_type;
153 aen_data.port.pwwn = pwwn; 148 aen_data.port.pwwn = pwwn;
154} 149}
155 150
156static void 151static void
157bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) 152bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
153 enum bfa_fcport_sm_event event)
158{ 154{
159 bfa_trc(pport->bfa, event); 155 bfa_trc(fcport->bfa, event);
160 156
161 switch (event) { 157 switch (event) {
162 case BFA_PPORT_SM_START: 158 case BFA_FCPORT_SM_START:
163 /** 159 /**
164 * Start event after IOC is configured and BFA is started. 160 * Start event after IOC is configured and BFA is started.
165 */ 161 */
166 if (bfa_pport_send_enable(pport)) 162 if (bfa_fcport_send_enable(fcport))
167 bfa_sm_set_state(pport, bfa_pport_sm_enabling); 163 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
168 else 164 else
169 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); 165 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
170 break; 166 break;
171 167
172 case BFA_PPORT_SM_ENABLE: 168 case BFA_FCPORT_SM_ENABLE:
173 /** 169 /**
174 * Port is persistently configured to be in enabled state. Do 170 * Port is persistently configured to be in enabled state. Do
175 * not change state. Port enabling is done when START event is 171 * not change state. Port enabling is done when START event is
@@ -177,389 +173,412 @@ bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
177 */ 173 */
178 break; 174 break;
179 175
180 case BFA_PPORT_SM_DISABLE: 176 case BFA_FCPORT_SM_DISABLE:
181 /** 177 /**
182 * If a port is persistently configured to be disabled, the 178 * If a port is persistently configured to be disabled, the
183 * first event will a port disable request. 179 * first event will a port disable request.
184 */ 180 */
185 bfa_sm_set_state(pport, bfa_pport_sm_disabled); 181 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
186 break; 182 break;
187 183
188 case BFA_PPORT_SM_HWFAIL: 184 case BFA_FCPORT_SM_HWFAIL:
189 bfa_sm_set_state(pport, bfa_pport_sm_iocdown); 185 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
190 break; 186 break;
191 187
192 default: 188 default:
193 bfa_sm_fault(pport->bfa, event); 189 bfa_sm_fault(fcport->bfa, event);
194 } 190 }
195} 191}
196 192
197static void 193static void
198bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, 194bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
199 enum bfa_pport_sm_event event) 195 enum bfa_fcport_sm_event event)
200{ 196{
201 bfa_trc(pport->bfa, event); 197 bfa_trc(fcport->bfa, event);
202 198
203 switch (event) { 199 switch (event) {
204 case BFA_PPORT_SM_QRESUME: 200 case BFA_FCPORT_SM_QRESUME:
205 bfa_sm_set_state(pport, bfa_pport_sm_enabling); 201 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
206 bfa_pport_send_enable(pport); 202 bfa_fcport_send_enable(fcport);
207 break; 203 break;
208 204
209 case BFA_PPORT_SM_STOP: 205 case BFA_FCPORT_SM_STOP:
210 bfa_reqq_wcancel(&pport->reqq_wait); 206 bfa_reqq_wcancel(&fcport->reqq_wait);
211 bfa_sm_set_state(pport, bfa_pport_sm_stopped); 207 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
212 break; 208 break;
213 209
214 case BFA_PPORT_SM_ENABLE: 210 case BFA_FCPORT_SM_ENABLE:
215 /** 211 /**
216 * Already enable is in progress. 212 * Already enable is in progress.
217 */ 213 */
218 break; 214 break;
219 215
220 case BFA_PPORT_SM_DISABLE: 216 case BFA_FCPORT_SM_DISABLE:
221 /** 217 /**
222 * Just send disable request to firmware when room becomes 218 * Just send disable request to firmware when room becomes
223 * available in request queue. 219 * available in request queue.
224 */ 220 */
225 bfa_sm_set_state(pport, bfa_pport_sm_disabled); 221 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
226 bfa_reqq_wcancel(&pport->reqq_wait); 222 bfa_reqq_wcancel(&fcport->reqq_wait);
227 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, 223 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
228 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 224 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
229 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); 225 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
230 break; 226 break;
231 227
232 case BFA_PPORT_SM_LINKUP: 228 case BFA_FCPORT_SM_LINKUP:
233 case BFA_PPORT_SM_LINKDOWN: 229 case BFA_FCPORT_SM_LINKDOWN:
234 /** 230 /**
235 * Possible to get link events when doing back-to-back 231 * Possible to get link events when doing back-to-back
236 * enable/disables. 232 * enable/disables.
237 */ 233 */
238 break; 234 break;
239 235
240 case BFA_PPORT_SM_HWFAIL: 236 case BFA_FCPORT_SM_HWFAIL:
241 bfa_reqq_wcancel(&pport->reqq_wait); 237 bfa_reqq_wcancel(&fcport->reqq_wait);
242 bfa_sm_set_state(pport, bfa_pport_sm_iocdown); 238 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
243 break; 239 break;
244 240
245 default: 241 default:
246 bfa_sm_fault(pport->bfa, event); 242 bfa_sm_fault(fcport->bfa, event);
247 } 243 }
248} 244}
249 245
250static void 246static void
251bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) 247bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
248 enum bfa_fcport_sm_event event)
252{ 249{
253 bfa_trc(pport->bfa, event); 250 bfa_trc(fcport->bfa, event);
254 251
255 switch (event) { 252 switch (event) {
256 case BFA_PPORT_SM_FWRSP: 253 case BFA_FCPORT_SM_FWRSP:
257 case BFA_PPORT_SM_LINKDOWN: 254 case BFA_FCPORT_SM_LINKDOWN:
258 bfa_sm_set_state(pport, bfa_pport_sm_linkdown); 255 bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
259 break; 256 break;
260 257
261 case BFA_PPORT_SM_LINKUP: 258 case BFA_FCPORT_SM_LINKUP:
262 bfa_pport_update_linkinfo(pport); 259 bfa_fcport_update_linkinfo(fcport);
263 bfa_sm_set_state(pport, bfa_pport_sm_linkup); 260 bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
264 261
265 bfa_assert(pport->event_cbfn); 262 bfa_assert(fcport->event_cbfn);
266 bfa_pport_callback(pport, BFA_PPORT_LINKUP); 263 bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
267 break; 264 break;
268 265
269 case BFA_PPORT_SM_ENABLE: 266 case BFA_FCPORT_SM_ENABLE:
270 /** 267 /**
271 * Already being enabled. 268 * Already being enabled.
272 */ 269 */
273 break; 270 break;
274 271
275 case BFA_PPORT_SM_DISABLE: 272 case BFA_FCPORT_SM_DISABLE:
276 if (bfa_pport_send_disable(pport)) 273 if (bfa_fcport_send_disable(fcport))
277 bfa_sm_set_state(pport, bfa_pport_sm_disabling); 274 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
278 else 275 else
279 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); 276 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
280 277
281 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, 278 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
282 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 279 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
283 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); 280 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
284 break; 281 break;
285 282
286 case BFA_PPORT_SM_STOP: 283 case BFA_FCPORT_SM_STOP:
287 bfa_sm_set_state(pport, bfa_pport_sm_stopped); 284 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
288 break; 285 break;
289 286
290 case BFA_PPORT_SM_HWFAIL: 287 case BFA_FCPORT_SM_HWFAIL:
291 bfa_sm_set_state(pport, bfa_pport_sm_iocdown); 288 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
292 break; 289 break;
293 290
294 default: 291 default:
295 bfa_sm_fault(pport->bfa, event); 292 bfa_sm_fault(fcport->bfa, event);
296 } 293 }
297} 294}
298 295
299static void 296static void
300bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) 297bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
298 enum bfa_fcport_sm_event event)
301{ 299{
302 bfa_trc(pport->bfa, event); 300 struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
301 bfa_trc(fcport->bfa, event);
303 302
304 switch (event) { 303 switch (event) {
305 case BFA_PPORT_SM_LINKUP: 304 case BFA_FCPORT_SM_LINKUP:
306 bfa_pport_update_linkinfo(pport); 305 bfa_fcport_update_linkinfo(fcport);
307 bfa_sm_set_state(pport, bfa_pport_sm_linkup); 306 bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
308 bfa_assert(pport->event_cbfn); 307 bfa_assert(fcport->event_cbfn);
309 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, 308 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
310 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup"); 309 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
311 bfa_pport_callback(pport, BFA_PPORT_LINKUP); 310
312 bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE); 311 if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
312
313 bfa_trc(fcport->bfa, pevent->link_state.fcf.fipenabled);
314 bfa_trc(fcport->bfa, pevent->link_state.fcf.fipfailed);
315
316 if (pevent->link_state.fcf.fipfailed)
317 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
318 BFA_PL_EID_FIP_FCF_DISC, 0,
319 "FIP FCF Discovery Failed");
320 else
321 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
322 BFA_PL_EID_FIP_FCF_DISC, 0,
323 "FIP FCF Discovered");
324 }
325
326 bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
327 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
313 /** 328 /**
314 * If QoS is enabled and it is not online, 329 * If QoS is enabled and it is not online,
315 * Send a separate event. 330 * Send a separate event.
316 */ 331 */
317 if ((pport->cfg.qos_enabled) 332 if ((fcport->cfg.qos_enabled)
318 && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE)) 333 && (bfa_os_ntohl(fcport->qos_attr.state) != BFA_QOS_ONLINE))
319 bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG); 334 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
320 335
321 break; 336 break;
322 337
323 case BFA_PPORT_SM_LINKDOWN: 338 case BFA_FCPORT_SM_LINKDOWN:
324 /** 339 /**
325 * Possible to get link down event. 340 * Possible to get link down event.
326 */ 341 */
327 break; 342 break;
328 343
329 case BFA_PPORT_SM_ENABLE: 344 case BFA_FCPORT_SM_ENABLE:
330 /** 345 /**
331 * Already enabled. 346 * Already enabled.
332 */ 347 */
333 break; 348 break;
334 349
335 case BFA_PPORT_SM_DISABLE: 350 case BFA_FCPORT_SM_DISABLE:
336 if (bfa_pport_send_disable(pport)) 351 if (bfa_fcport_send_disable(fcport))
337 bfa_sm_set_state(pport, bfa_pport_sm_disabling); 352 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
338 else 353 else
339 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); 354 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
340 355
341 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, 356 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
342 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 357 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
343 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); 358 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
344 break; 359 break;
345 360
346 case BFA_PPORT_SM_STOP: 361 case BFA_FCPORT_SM_STOP:
347 bfa_sm_set_state(pport, bfa_pport_sm_stopped); 362 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
348 break; 363 break;
349 364
350 case BFA_PPORT_SM_HWFAIL: 365 case BFA_FCPORT_SM_HWFAIL:
351 bfa_sm_set_state(pport, bfa_pport_sm_iocdown); 366 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
352 break; 367 break;
353 368
354 default: 369 default:
355 bfa_sm_fault(pport->bfa, event); 370 bfa_sm_fault(fcport->bfa, event);
356 } 371 }
357} 372}
358 373
359static void 374static void
360bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) 375bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
376 enum bfa_fcport_sm_event event)
361{ 377{
362 bfa_trc(pport->bfa, event); 378 bfa_trc(fcport->bfa, event);
363 379
364 switch (event) { 380 switch (event) {
365 case BFA_PPORT_SM_ENABLE: 381 case BFA_FCPORT_SM_ENABLE:
366 /** 382 /**
367 * Already enabled. 383 * Already enabled.
368 */ 384 */
369 break; 385 break;
370 386
371 case BFA_PPORT_SM_DISABLE: 387 case BFA_FCPORT_SM_DISABLE:
372 if (bfa_pport_send_disable(pport)) 388 if (bfa_fcport_send_disable(fcport))
373 bfa_sm_set_state(pport, bfa_pport_sm_disabling); 389 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
374 else 390 else
375 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); 391 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
376 392
377 bfa_pport_reset_linkinfo(pport); 393 bfa_fcport_reset_linkinfo(fcport);
378 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); 394 bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
379 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, 395 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
380 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 396 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
381 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); 397 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
382 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); 398 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
383 break; 399 break;
384 400
385 case BFA_PPORT_SM_LINKDOWN: 401 case BFA_FCPORT_SM_LINKDOWN:
386 bfa_sm_set_state(pport, bfa_pport_sm_linkdown); 402 bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
387 bfa_pport_reset_linkinfo(pport); 403 bfa_fcport_reset_linkinfo(fcport);
388 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); 404 bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
389 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, 405 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
390 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); 406 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
391 if (BFA_PORT_IS_DISABLED(pport->bfa)) 407 if (BFA_PORT_IS_DISABLED(fcport->bfa))
392 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); 408 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
393 else 409 else
394 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); 410 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
395 break; 411 break;
396 412
397 case BFA_PPORT_SM_STOP: 413 case BFA_FCPORT_SM_STOP:
398 bfa_sm_set_state(pport, bfa_pport_sm_stopped); 414 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
399 bfa_pport_reset_linkinfo(pport); 415 bfa_fcport_reset_linkinfo(fcport);
400 if (BFA_PORT_IS_DISABLED(pport->bfa)) 416 if (BFA_PORT_IS_DISABLED(fcport->bfa))
401 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); 417 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
402 else 418 else
403 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); 419 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
404 break; 420 break;
405 421
406 case BFA_PPORT_SM_HWFAIL: 422 case BFA_FCPORT_SM_HWFAIL:
407 bfa_sm_set_state(pport, bfa_pport_sm_iocdown); 423 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
408 bfa_pport_reset_linkinfo(pport); 424 bfa_fcport_reset_linkinfo(fcport);
409 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); 425 bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
410 if (BFA_PORT_IS_DISABLED(pport->bfa)) 426 if (BFA_PORT_IS_DISABLED(fcport->bfa))
411 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); 427 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
412 else 428 else
413 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); 429 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
414 break; 430 break;
415 431
416 default: 432 default:
417 bfa_sm_fault(pport->bfa, event); 433 bfa_sm_fault(fcport->bfa, event);
418 } 434 }
419} 435}
420 436
421static void 437static void
422bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport, 438bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
423 enum bfa_pport_sm_event event) 439 enum bfa_fcport_sm_event event)
424{ 440{
425 bfa_trc(pport->bfa, event); 441 bfa_trc(fcport->bfa, event);
426 442
427 switch (event) { 443 switch (event) {
428 case BFA_PPORT_SM_QRESUME: 444 case BFA_FCPORT_SM_QRESUME:
429 bfa_sm_set_state(pport, bfa_pport_sm_disabling); 445 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
430 bfa_pport_send_disable(pport); 446 bfa_fcport_send_disable(fcport);
431 break; 447 break;
432 448
433 case BFA_PPORT_SM_STOP: 449 case BFA_FCPORT_SM_STOP:
434 bfa_sm_set_state(pport, bfa_pport_sm_stopped); 450 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
435 bfa_reqq_wcancel(&pport->reqq_wait); 451 bfa_reqq_wcancel(&fcport->reqq_wait);
436 break; 452 break;
437 453
438 case BFA_PPORT_SM_DISABLE: 454 case BFA_FCPORT_SM_DISABLE:
439 /** 455 /**
440 * Already being disabled. 456 * Already being disabled.
441 */ 457 */
442 break; 458 break;
443 459
444 case BFA_PPORT_SM_LINKUP: 460 case BFA_FCPORT_SM_LINKUP:
445 case BFA_PPORT_SM_LINKDOWN: 461 case BFA_FCPORT_SM_LINKDOWN:
446 /** 462 /**
447 * Possible to get link events when doing back-to-back 463 * Possible to get link events when doing back-to-back
448 * enable/disables. 464 * enable/disables.
449 */ 465 */
450 break; 466 break;
451 467
452 case BFA_PPORT_SM_HWFAIL: 468 case BFA_FCPORT_SM_HWFAIL:
453 bfa_sm_set_state(pport, bfa_pport_sm_iocfail); 469 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
454 bfa_reqq_wcancel(&pport->reqq_wait); 470 bfa_reqq_wcancel(&fcport->reqq_wait);
455 break; 471 break;
456 472
457 default: 473 default:
458 bfa_sm_fault(pport->bfa, event); 474 bfa_sm_fault(fcport->bfa, event);
459 } 475 }
460} 476}
461 477
462static void 478static void
463bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) 479bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
480 enum bfa_fcport_sm_event event)
464{ 481{
465 bfa_trc(pport->bfa, event); 482 bfa_trc(fcport->bfa, event);
466 483
467 switch (event) { 484 switch (event) {
468 case BFA_PPORT_SM_FWRSP: 485 case BFA_FCPORT_SM_FWRSP:
469 bfa_sm_set_state(pport, bfa_pport_sm_disabled); 486 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
470 break; 487 break;
471 488
472 case BFA_PPORT_SM_DISABLE: 489 case BFA_FCPORT_SM_DISABLE:
473 /** 490 /**
474 * Already being disabled. 491 * Already being disabled.
475 */ 492 */
476 break; 493 break;
477 494
478 case BFA_PPORT_SM_ENABLE: 495 case BFA_FCPORT_SM_ENABLE:
479 if (bfa_pport_send_enable(pport)) 496 if (bfa_fcport_send_enable(fcport))
480 bfa_sm_set_state(pport, bfa_pport_sm_enabling); 497 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
481 else 498 else
482 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); 499 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
483 500
484 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, 501 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
485 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); 502 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
486 bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE); 503 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
487 break; 504 break;
488 505
489 case BFA_PPORT_SM_STOP: 506 case BFA_FCPORT_SM_STOP:
490 bfa_sm_set_state(pport, bfa_pport_sm_stopped); 507 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
491 break; 508 break;
492 509
493 case BFA_PPORT_SM_LINKUP: 510 case BFA_FCPORT_SM_LINKUP:
494 case BFA_PPORT_SM_LINKDOWN: 511 case BFA_FCPORT_SM_LINKDOWN:
495 /** 512 /**
496 * Possible to get link events when doing back-to-back 513 * Possible to get link events when doing back-to-back
497 * enable/disables. 514 * enable/disables.
498 */ 515 */
499 break; 516 break;
500 517
501 case BFA_PPORT_SM_HWFAIL: 518 case BFA_FCPORT_SM_HWFAIL:
502 bfa_sm_set_state(pport, bfa_pport_sm_iocfail); 519 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
503 break; 520 break;
504 521
505 default: 522 default:
506 bfa_sm_fault(pport->bfa, event); 523 bfa_sm_fault(fcport->bfa, event);
507 } 524 }
508} 525}
509 526
510static void 527static void
511bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) 528bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
529 enum bfa_fcport_sm_event event)
512{ 530{
513 bfa_trc(pport->bfa, event); 531 bfa_trc(fcport->bfa, event);
514 532
515 switch (event) { 533 switch (event) {
516 case BFA_PPORT_SM_START: 534 case BFA_FCPORT_SM_START:
517 /** 535 /**
518 * Ignore start event for a port that is disabled. 536 * Ignore start event for a port that is disabled.
519 */ 537 */
520 break; 538 break;
521 539
522 case BFA_PPORT_SM_STOP: 540 case BFA_FCPORT_SM_STOP:
523 bfa_sm_set_state(pport, bfa_pport_sm_stopped); 541 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
524 break; 542 break;
525 543
526 case BFA_PPORT_SM_ENABLE: 544 case BFA_FCPORT_SM_ENABLE:
527 if (bfa_pport_send_enable(pport)) 545 if (bfa_fcport_send_enable(fcport))
528 bfa_sm_set_state(pport, bfa_pport_sm_enabling); 546 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
529 else 547 else
530 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); 548 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
531 549
532 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, 550 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
533 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); 551 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
534 bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE); 552 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
535 break; 553 break;
536 554
537 case BFA_PPORT_SM_DISABLE: 555 case BFA_FCPORT_SM_DISABLE:
538 /** 556 /**
539 * Already disabled. 557 * Already disabled.
540 */ 558 */
541 break; 559 break;
542 560
543 case BFA_PPORT_SM_HWFAIL: 561 case BFA_FCPORT_SM_HWFAIL:
544 bfa_sm_set_state(pport, bfa_pport_sm_iocfail); 562 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
545 break; 563 break;
546 564
547 default: 565 default:
548 bfa_sm_fault(pport->bfa, event); 566 bfa_sm_fault(fcport->bfa, event);
549 } 567 }
550} 568}
551 569
552static void 570static void
553bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) 571bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
572 enum bfa_fcport_sm_event event)
554{ 573{
555 bfa_trc(pport->bfa, event); 574 bfa_trc(fcport->bfa, event);
556 575
557 switch (event) { 576 switch (event) {
558 case BFA_PPORT_SM_START: 577 case BFA_FCPORT_SM_START:
559 if (bfa_pport_send_enable(pport)) 578 if (bfa_fcport_send_enable(fcport))
560 bfa_sm_set_state(pport, bfa_pport_sm_enabling); 579 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
561 else 580 else
562 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); 581 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
563 break; 582 break;
564 583
565 default: 584 default:
@@ -574,16 +593,17 @@ bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
574 * Port is enabled. IOC is down/failed. 593 * Port is enabled. IOC is down/failed.
575 */ 594 */
576static void 595static void
577bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) 596bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
597 enum bfa_fcport_sm_event event)
578{ 598{
579 bfa_trc(pport->bfa, event); 599 bfa_trc(fcport->bfa, event);
580 600
581 switch (event) { 601 switch (event) {
582 case BFA_PPORT_SM_START: 602 case BFA_FCPORT_SM_START:
583 if (bfa_pport_send_enable(pport)) 603 if (bfa_fcport_send_enable(fcport))
584 bfa_sm_set_state(pport, bfa_pport_sm_enabling); 604 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
585 else 605 else
586 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); 606 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
587 break; 607 break;
588 608
589 default: 609 default:
@@ -598,17 +618,18 @@ bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
598 * Port is disabled. IOC is down/failed. 618 * Port is disabled. IOC is down/failed.
599 */ 619 */
600static void 620static void
601bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) 621bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
622 enum bfa_fcport_sm_event event)
602{ 623{
603 bfa_trc(pport->bfa, event); 624 bfa_trc(fcport->bfa, event);
604 625
605 switch (event) { 626 switch (event) {
606 case BFA_PPORT_SM_START: 627 case BFA_FCPORT_SM_START:
607 bfa_sm_set_state(pport, bfa_pport_sm_disabled); 628 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
608 break; 629 break;
609 630
610 case BFA_PPORT_SM_ENABLE: 631 case BFA_FCPORT_SM_ENABLE:
611 bfa_sm_set_state(pport, bfa_pport_sm_iocdown); 632 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
612 break; 633 break;
613 634
614 default: 635 default:
@@ -619,41 +640,226 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
619 } 640 }
620} 641}
621 642
643/**
644 * Link state is down
645 */
646static void
647bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
648 enum bfa_fcport_ln_sm_event event)
649{
650 bfa_trc(ln->fcport->bfa, event);
651
652 switch (event) {
653 case BFA_FCPORT_LN_SM_LINKUP:
654 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
655 bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
656 break;
657
658 default:
659 bfa_sm_fault(ln->fcport->bfa, event);
660 }
661}
662
663/**
664 * Link state is waiting for down notification
665 */
666static void
667bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
668 enum bfa_fcport_ln_sm_event event)
669{
670 bfa_trc(ln->fcport->bfa, event);
671
672 switch (event) {
673 case BFA_FCPORT_LN_SM_LINKUP:
674 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
675 break;
676
677 case BFA_FCPORT_LN_SM_NOTIFICATION:
678 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
679 break;
680
681 default:
682 bfa_sm_fault(ln->fcport->bfa, event);
683 }
684}
685
686/**
687 * Link state is waiting for down notification and there is a pending up
688 */
689static void
690bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
691 enum bfa_fcport_ln_sm_event event)
692{
693 bfa_trc(ln->fcport->bfa, event);
694
695 switch (event) {
696 case BFA_FCPORT_LN_SM_LINKDOWN:
697 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
698 break;
699
700 case BFA_FCPORT_LN_SM_NOTIFICATION:
701 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
702 bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
703 break;
704
705 default:
706 bfa_sm_fault(ln->fcport->bfa, event);
707 }
708}
709
710/**
711 * Link state is up
712 */
713static void
714bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
715 enum bfa_fcport_ln_sm_event event)
716{
717 bfa_trc(ln->fcport->bfa, event);
718
719 switch (event) {
720 case BFA_FCPORT_LN_SM_LINKDOWN:
721 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
722 bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
723 break;
622 724
725 default:
726 bfa_sm_fault(ln->fcport->bfa, event);
727 }
728}
729
730/**
731 * Link state is waiting for up notification
732 */
733static void
734bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
735 enum bfa_fcport_ln_sm_event event)
736{
737 bfa_trc(ln->fcport->bfa, event);
738
739 switch (event) {
740 case BFA_FCPORT_LN_SM_LINKDOWN:
741 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
742 break;
743
744 case BFA_FCPORT_LN_SM_NOTIFICATION:
745 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up);
746 break;
747
748 default:
749 bfa_sm_fault(ln->fcport->bfa, event);
750 }
751}
752
753/**
754 * Link state is waiting for up notification and there is a pending down
755 */
756static void
757bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
758 enum bfa_fcport_ln_sm_event event)
759{
760 bfa_trc(ln->fcport->bfa, event);
761
762 switch (event) {
763 case BFA_FCPORT_LN_SM_LINKUP:
764 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf);
765 break;
766
767 case BFA_FCPORT_LN_SM_NOTIFICATION:
768 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
769 bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
770 break;
771
772 default:
773 bfa_sm_fault(ln->fcport->bfa, event);
774 }
775}
776
777/**
778 * Link state is waiting for up notification and there are pending down and up
779 */
780static void
781bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
782 enum bfa_fcport_ln_sm_event event)
783{
784 bfa_trc(ln->fcport->bfa, event);
785
786 switch (event) {
787 case BFA_FCPORT_LN_SM_LINKDOWN:
788 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
789 break;
790
791 case BFA_FCPORT_LN_SM_NOTIFICATION:
792 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
793 bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
794 break;
795
796 default:
797 bfa_sm_fault(ln->fcport->bfa, event);
798 }
799}
623 800
624/** 801/**
625 * bfa_pport_private 802 * bfa_pport_private
626 */ 803 */
627 804
628static void 805static void
629__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete) 806__bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
630{ 807{
631 struct bfa_pport_s *pport = cbarg; 808 struct bfa_fcport_ln_s *ln = cbarg;
632 809
633 if (complete) 810 if (complete)
634 pport->event_cbfn(pport->event_cbarg, pport->hcb_event); 811 ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event);
812 else
813 bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
635} 814}
636 815
637#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \ 816static void
817bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event)
818{
819 if (fcport->bfa->fcs) {
820 fcport->event_cbfn(fcport->event_cbarg, event);
821 return;
822 }
823
824 switch (event) {
825 case BFA_PPORT_LINKUP:
826 bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP);
827 break;
828 case BFA_PPORT_LINKDOWN:
829 bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
830 break;
831 default:
832 bfa_assert(0);
833 }
834}
835
836static void
837bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event)
838{
839 ln->ln_event = event;
840 bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln);
841}
842
843#define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
638 BFA_CACHELINE_SZ)) 844 BFA_CACHELINE_SZ))
639 845
640static void 846static void
641bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, 847bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
642 u32 *dm_len) 848 u32 *dm_len)
643{ 849{
644 *dm_len += PPORT_STATS_DMA_SZ; 850 *dm_len += FCPORT_STATS_DMA_SZ;
645} 851}
646 852
647static void 853static void
648bfa_pport_qresume(void *cbarg) 854bfa_fcport_qresume(void *cbarg)
649{ 855{
650 struct bfa_pport_s *port = cbarg; 856 struct bfa_fcport_s *fcport = cbarg;
651 857
652 bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME); 858 bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME);
653} 859}
654 860
655static void 861static void
656bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo) 862bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo)
657{ 863{
658 u8 *dm_kva; 864 u8 *dm_kva;
659 u64 dm_pa; 865 u64 dm_pa;
@@ -661,12 +867,12 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
661 dm_kva = bfa_meminfo_dma_virt(meminfo); 867 dm_kva = bfa_meminfo_dma_virt(meminfo);
662 dm_pa = bfa_meminfo_dma_phys(meminfo); 868 dm_pa = bfa_meminfo_dma_phys(meminfo);
663 869
664 pport->stats_kva = dm_kva; 870 fcport->stats_kva = dm_kva;
665 pport->stats_pa = dm_pa; 871 fcport->stats_pa = dm_pa;
666 pport->stats = (union bfa_pport_stats_u *)dm_kva; 872 fcport->stats = (union bfa_fcport_stats_u *)dm_kva;
667 873
668 dm_kva += PPORT_STATS_DMA_SZ; 874 dm_kva += FCPORT_STATS_DMA_SZ;
669 dm_pa += PPORT_STATS_DMA_SZ; 875 dm_pa += FCPORT_STATS_DMA_SZ;
670 876
671 bfa_meminfo_dma_virt(meminfo) = dm_kva; 877 bfa_meminfo_dma_virt(meminfo) = dm_kva;
672 bfa_meminfo_dma_phys(meminfo) = dm_pa; 878 bfa_meminfo_dma_phys(meminfo) = dm_pa;
@@ -676,18 +882,21 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
676 * Memory initialization. 882 * Memory initialization.
677 */ 883 */
678static void 884static void
679bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 885bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
680 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) 886 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
681{ 887{
682 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 888 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
683 struct bfa_pport_cfg_s *port_cfg = &pport->cfg; 889 struct bfa_pport_cfg_s *port_cfg = &fcport->cfg;
890 struct bfa_fcport_ln_s *ln = &fcport->ln;
684 891
685 bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s)); 892 bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
686 pport->bfa = bfa; 893 fcport->bfa = bfa;
894 ln->fcport = fcport;
687 895
688 bfa_pport_mem_claim(pport, meminfo); 896 bfa_fcport_mem_claim(fcport, meminfo);
689 897
690 bfa_sm_set_state(pport, bfa_pport_sm_uninit); 898 bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
899 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
691 900
692 /** 901 /**
693 * initialize and set default configuration 902 * initialize and set default configuration
@@ -699,30 +908,30 @@ bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
699 908
700 port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS; 909 port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
701 910
702 bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport); 911 bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
703} 912}
704 913
705static void 914static void
706bfa_pport_initdone(struct bfa_s *bfa) 915bfa_fcport_initdone(struct bfa_s *bfa)
707{ 916{
708 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 917 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
709 918
710 /** 919 /**
711 * Initialize port attributes from IOC hardware data. 920 * Initialize port attributes from IOC hardware data.
712 */ 921 */
713 bfa_pport_set_wwns(pport); 922 bfa_fcport_set_wwns(fcport);
714 if (pport->cfg.maxfrsize == 0) 923 if (fcport->cfg.maxfrsize == 0)
715 pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); 924 fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
716 pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); 925 fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
717 pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); 926 fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
718 927
719 bfa_assert(pport->cfg.maxfrsize); 928 bfa_assert(fcport->cfg.maxfrsize);
720 bfa_assert(pport->cfg.rx_bbcredit); 929 bfa_assert(fcport->cfg.rx_bbcredit);
721 bfa_assert(pport->speed_sup); 930 bfa_assert(fcport->speed_sup);
722} 931}
723 932
724static void 933static void
725bfa_pport_detach(struct bfa_s *bfa) 934bfa_fcport_detach(struct bfa_s *bfa)
726{ 935{
727} 936}
728 937
@@ -730,95 +939,97 @@ bfa_pport_detach(struct bfa_s *bfa)
730 * Called when IOC is ready. 939 * Called when IOC is ready.
731 */ 940 */
732static void 941static void
733bfa_pport_start(struct bfa_s *bfa) 942bfa_fcport_start(struct bfa_s *bfa)
734{ 943{
735 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START); 944 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
736} 945}
737 946
738/** 947/**
739 * Called before IOC is stopped. 948 * Called before IOC is stopped.
740 */ 949 */
741static void 950static void
742bfa_pport_stop(struct bfa_s *bfa) 951bfa_fcport_stop(struct bfa_s *bfa)
743{ 952{
744 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP); 953 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP);
745} 954}
746 955
747/** 956/**
748 * Called when IOC failure is detected. 957 * Called when IOC failure is detected.
749 */ 958 */
750static void 959static void
751bfa_pport_iocdisable(struct bfa_s *bfa) 960bfa_fcport_iocdisable(struct bfa_s *bfa)
752{ 961{
753 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL); 962 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_HWFAIL);
754} 963}
755 964
756static void 965static void
757bfa_pport_update_linkinfo(struct bfa_pport_s *pport) 966bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
758{ 967{
759 struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event; 968 struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
760 969
761 pport->speed = pevent->link_state.speed; 970 fcport->speed = pevent->link_state.speed;
762 pport->topology = pevent->link_state.topology; 971 fcport->topology = pevent->link_state.topology;
763 972
764 if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP) 973 if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP)
765 pport->myalpa = pevent->link_state.tl.loop_info.myalpa; 974 fcport->myalpa =
975 pevent->link_state.tl.loop_info.myalpa;
766 976
767 /* 977 /*
768 * QoS Details 978 * QoS Details
769 */ 979 */
770 bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr); 980 bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
771 bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr); 981 bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr);
772 982
773 bfa_trc(pport->bfa, pport->speed); 983 bfa_trc(fcport->bfa, fcport->speed);
774 bfa_trc(pport->bfa, pport->topology); 984 bfa_trc(fcport->bfa, fcport->topology);
775} 985}
776 986
777static void 987static void
778bfa_pport_reset_linkinfo(struct bfa_pport_s *pport) 988bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
779{ 989{
780 pport->speed = BFA_PPORT_SPEED_UNKNOWN; 990 fcport->speed = BFA_PPORT_SPEED_UNKNOWN;
781 pport->topology = BFA_PPORT_TOPOLOGY_NONE; 991 fcport->topology = BFA_PPORT_TOPOLOGY_NONE;
782} 992}
783 993
784/** 994/**
785 * Send port enable message to firmware. 995 * Send port enable message to firmware.
786 */ 996 */
787static bfa_boolean_t 997static bfa_boolean_t
788bfa_pport_send_enable(struct bfa_pport_s *port) 998bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
789{ 999{
790 struct bfi_pport_enable_req_s *m; 1000 struct bfi_fcport_enable_req_s *m;
791 1001
792 /** 1002 /**
793 * Increment message tag before queue check, so that responses to old 1003 * Increment message tag before queue check, so that responses to old
794 * requests are discarded. 1004 * requests are discarded.
795 */ 1005 */
796 port->msgtag++; 1006 fcport->msgtag++;
797 1007
798 /** 1008 /**
799 * check for room in queue to send request now 1009 * check for room in queue to send request now
800 */ 1010 */
801 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); 1011 m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
802 if (!m) { 1012 if (!m) {
803 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait); 1013 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1014 &fcport->reqq_wait);
804 return BFA_FALSE; 1015 return BFA_FALSE;
805 } 1016 }
806 1017
807 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ, 1018 bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ,
808 bfa_lpuid(port->bfa)); 1019 bfa_lpuid(fcport->bfa));
809 m->nwwn = port->nwwn; 1020 m->nwwn = fcport->nwwn;
810 m->pwwn = port->pwwn; 1021 m->pwwn = fcport->pwwn;
811 m->port_cfg = port->cfg; 1022 m->port_cfg = fcport->cfg;
812 m->msgtag = port->msgtag; 1023 m->msgtag = fcport->msgtag;
813 m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize); 1024 m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize);
814 bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa); 1025 bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
815 bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo); 1026 bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
816 bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi); 1027 bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
817 1028
818 /** 1029 /**
819 * queue I/O message to firmware 1030 * queue I/O message to firmware
820 */ 1031 */
821 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); 1032 bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
822 return BFA_TRUE; 1033 return BFA_TRUE;
823} 1034}
824 1035
@@ -826,74 +1037,226 @@ bfa_pport_send_enable(struct bfa_pport_s *port)
826 * Send port disable message to firmware. 1037 * Send port disable message to firmware.
827 */ 1038 */
828static bfa_boolean_t 1039static bfa_boolean_t
829bfa_pport_send_disable(struct bfa_pport_s *port) 1040bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
830{ 1041{
831 bfi_pport_disable_req_t *m; 1042 struct bfi_fcport_req_s *m;
832 1043
833 /** 1044 /**
834 * Increment message tag before queue check, so that responses to old 1045 * Increment message tag before queue check, so that responses to old
835 * requests are discarded. 1046 * requests are discarded.
836 */ 1047 */
837 port->msgtag++; 1048 fcport->msgtag++;
838 1049
839 /** 1050 /**
840 * check for room in queue to send request now 1051 * check for room in queue to send request now
841 */ 1052 */
842 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); 1053 m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
843 if (!m) { 1054 if (!m) {
844 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait); 1055 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1056 &fcport->reqq_wait);
845 return BFA_FALSE; 1057 return BFA_FALSE;
846 } 1058 }
847 1059
848 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ, 1060 bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ,
849 bfa_lpuid(port->bfa)); 1061 bfa_lpuid(fcport->bfa));
850 m->msgtag = port->msgtag; 1062 m->msgtag = fcport->msgtag;
851 1063
852 /** 1064 /**
853 * queue I/O message to firmware 1065 * queue I/O message to firmware
854 */ 1066 */
855 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); 1067 bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
856 1068
857 return BFA_TRUE; 1069 return BFA_TRUE;
858} 1070}
859 1071
860static void 1072static void
861bfa_pport_set_wwns(struct bfa_pport_s *port) 1073bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
862{ 1074{
863 port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc); 1075 fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc);
864 port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc); 1076 fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc);
865 1077
866 bfa_trc(port->bfa, port->pwwn); 1078 bfa_trc(fcport->bfa, fcport->pwwn);
867 bfa_trc(port->bfa, port->nwwn); 1079 bfa_trc(fcport->bfa, fcport->nwwn);
868} 1080}
869 1081
870static void 1082static void
871bfa_port_send_txcredit(void *port_cbarg) 1083bfa_fcport_send_txcredit(void *port_cbarg)
872{ 1084{
873 1085
874 struct bfa_pport_s *port = port_cbarg; 1086 struct bfa_fcport_s *fcport = port_cbarg;
875 struct bfi_pport_set_svc_params_req_s *m; 1087 struct bfi_fcport_set_svc_params_req_s *m;
876 1088
877 /** 1089 /**
878 * check for room in queue to send request now 1090 * check for room in queue to send request now
879 */ 1091 */
880 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); 1092 m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
881 if (!m) { 1093 if (!m) {
882 bfa_trc(port->bfa, port->cfg.tx_bbcredit); 1094 bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit);
883 return; 1095 return;
884 } 1096 }
885 1097
886 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ, 1098 bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
887 bfa_lpuid(port->bfa)); 1099 bfa_lpuid(fcport->bfa));
888 m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit); 1100 m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit);
889 1101
890 /** 1102 /**
891 * queue I/O message to firmware 1103 * queue I/O message to firmware
892 */ 1104 */
893 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); 1105 bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
894} 1106}
895 1107
1108static void
1109bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
1110 struct bfa_qos_stats_s *s)
1111{
1112 u32 *dip = (u32 *) d;
1113 u32 *sip = (u32 *) s;
1114 int i;
1115
1116 /* Now swap the 32 bit fields */
1117 for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
1118 dip[i] = bfa_os_ntohl(sip[i]);
1119}
896 1120
1121static void
1122bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
1123 struct bfa_fcoe_stats_s *s)
1124{
1125 u32 *dip = (u32 *) d;
1126 u32 *sip = (u32 *) s;
1127 int i;
1128
1129 for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
1130 i = i + 2) {
1131#ifdef __BIGENDIAN
1132 dip[i] = bfa_os_ntohl(sip[i]);
1133 dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
1134#else
1135 dip[i] = bfa_os_ntohl(sip[i + 1]);
1136 dip[i + 1] = bfa_os_ntohl(sip[i]);
1137#endif
1138 }
1139}
1140
1141static void
1142__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
1143{
1144 struct bfa_fcport_s *fcport = cbarg;
1145
1146 if (complete) {
1147 if (fcport->stats_status == BFA_STATUS_OK) {
1148
1149 /* Swap FC QoS or FCoE stats */
1150 if (bfa_ioc_get_fcmode(&fcport->bfa->ioc))
1151 bfa_fcport_qos_stats_swap(
1152 &fcport->stats_ret->fcqos,
1153 &fcport->stats->fcqos);
1154 else
1155 bfa_fcport_fcoe_stats_swap(
1156 &fcport->stats_ret->fcoe,
1157 &fcport->stats->fcoe);
1158 }
1159 fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
1160 } else {
1161 fcport->stats_busy = BFA_FALSE;
1162 fcport->stats_status = BFA_STATUS_OK;
1163 }
1164}
1165
1166static void
1167bfa_fcport_stats_get_timeout(void *cbarg)
1168{
1169 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1170
1171 bfa_trc(fcport->bfa, fcport->stats_qfull);
1172
1173 if (fcport->stats_qfull) {
1174 bfa_reqq_wcancel(&fcport->stats_reqq_wait);
1175 fcport->stats_qfull = BFA_FALSE;
1176 }
1177
1178 fcport->stats_status = BFA_STATUS_ETIMER;
1179 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get,
1180 fcport);
1181}
1182
1183static void
1184bfa_fcport_send_stats_get(void *cbarg)
1185{
1186 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1187 struct bfi_fcport_req_s *msg;
1188
1189 msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1190
1191 if (!msg) {
1192 fcport->stats_qfull = BFA_TRUE;
1193 bfa_reqq_winit(&fcport->stats_reqq_wait,
1194 bfa_fcport_send_stats_get, fcport);
1195 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1196 &fcport->stats_reqq_wait);
1197 return;
1198 }
1199 fcport->stats_qfull = BFA_FALSE;
1200
1201 bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
1202 bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
1203 bfa_lpuid(fcport->bfa));
1204 bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1205}
1206
1207static void
1208__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
1209{
1210 struct bfa_fcport_s *fcport = cbarg;
1211
1212 if (complete) {
1213 fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
1214 } else {
1215 fcport->stats_busy = BFA_FALSE;
1216 fcport->stats_status = BFA_STATUS_OK;
1217 }
1218}
1219
1220static void
1221bfa_fcport_stats_clr_timeout(void *cbarg)
1222{
1223 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1224
1225 bfa_trc(fcport->bfa, fcport->stats_qfull);
1226
1227 if (fcport->stats_qfull) {
1228 bfa_reqq_wcancel(&fcport->stats_reqq_wait);
1229 fcport->stats_qfull = BFA_FALSE;
1230 }
1231
1232 fcport->stats_status = BFA_STATUS_ETIMER;
1233 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
1234 __bfa_cb_fcport_stats_clr, fcport);
1235}
1236
1237static void
1238bfa_fcport_send_stats_clear(void *cbarg)
1239{
1240 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1241 struct bfi_fcport_req_s *msg;
1242
1243 msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1244
1245 if (!msg) {
1246 fcport->stats_qfull = BFA_TRUE;
1247 bfa_reqq_winit(&fcport->stats_reqq_wait,
1248 bfa_fcport_send_stats_clear, fcport);
1249 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1250 &fcport->stats_reqq_wait);
1251 return;
1252 }
1253 fcport->stats_qfull = BFA_FALSE;
1254
1255 bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
1256 bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
1257 bfa_lpuid(fcport->bfa));
1258 bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1259}
897 1260
898/** 1261/**
899 * bfa_pport_public 1262 * bfa_pport_public
@@ -903,32 +1266,32 @@ bfa_port_send_txcredit(void *port_cbarg)
903 * Firmware message handler. 1266 * Firmware message handler.
904 */ 1267 */
905void 1268void
906bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 1269bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
907{ 1270{
908 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1271 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
909 union bfi_pport_i2h_msg_u i2hmsg; 1272 union bfi_fcport_i2h_msg_u i2hmsg;
910 1273
911 i2hmsg.msg = msg; 1274 i2hmsg.msg = msg;
912 pport->event_arg.i2hmsg = i2hmsg; 1275 fcport->event_arg.i2hmsg = i2hmsg;
913 1276
914 switch (msg->mhdr.msg_id) { 1277 switch (msg->mhdr.msg_id) {
915 case BFI_PPORT_I2H_ENABLE_RSP: 1278 case BFI_FCPORT_I2H_ENABLE_RSP:
916 if (pport->msgtag == i2hmsg.enable_rsp->msgtag) 1279 if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
917 bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP); 1280 bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
918 break; 1281 break;
919 1282
920 case BFI_PPORT_I2H_DISABLE_RSP: 1283 case BFI_FCPORT_I2H_DISABLE_RSP:
921 if (pport->msgtag == i2hmsg.enable_rsp->msgtag) 1284 if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
922 bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP); 1285 bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
923 break; 1286 break;
924 1287
925 case BFI_PPORT_I2H_EVENT: 1288 case BFI_FCPORT_I2H_EVENT:
926 switch (i2hmsg.event->link_state.linkstate) { 1289 switch (i2hmsg.event->link_state.linkstate) {
927 case BFA_PPORT_LINKUP: 1290 case BFA_PPORT_LINKUP:
928 bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP); 1291 bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
929 break; 1292 break;
930 case BFA_PPORT_LINKDOWN: 1293 case BFA_PPORT_LINKDOWN:
931 bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN); 1294 bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
932 break; 1295 break;
933 case BFA_PPORT_TRUNK_LINKDOWN: 1296 case BFA_PPORT_TRUNK_LINKDOWN:
934 /** todo: event notification */ 1297 /** todo: event notification */
@@ -936,42 +1299,40 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
936 } 1299 }
937 break; 1300 break;
938 1301
939 case BFI_PPORT_I2H_GET_STATS_RSP: 1302 case BFI_FCPORT_I2H_STATS_GET_RSP:
940 case BFI_PPORT_I2H_GET_QOS_STATS_RSP:
941 /* 1303 /*
942 * check for timer pop before processing the rsp 1304 * check for timer pop before processing the rsp
943 */ 1305 */
944 if (pport->stats_busy == BFA_FALSE 1306 if (fcport->stats_busy == BFA_FALSE ||
945 || pport->stats_status == BFA_STATUS_ETIMER) 1307 fcport->stats_status == BFA_STATUS_ETIMER)
946 break; 1308 break;
947 1309
948 bfa_timer_stop(&pport->timer); 1310 bfa_timer_stop(&fcport->timer);
949 pport->stats_status = i2hmsg.getstats_rsp->status; 1311 fcport->stats_status = i2hmsg.pstatsget_rsp->status;
950 bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats, 1312 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
951 pport); 1313 __bfa_cb_fcport_stats_get, fcport);
952 break; 1314 break;
953 case BFI_PPORT_I2H_CLEAR_STATS_RSP: 1315
954 case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP: 1316 case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
955 /* 1317 /*
956 * check for timer pop before processing the rsp 1318 * check for timer pop before processing the rsp
957 */ 1319 */
958 if (pport->stats_busy == BFA_FALSE 1320 if (fcport->stats_busy == BFA_FALSE ||
959 || pport->stats_status == BFA_STATUS_ETIMER) 1321 fcport->stats_status == BFA_STATUS_ETIMER)
960 break; 1322 break;
961 1323
962 bfa_timer_stop(&pport->timer); 1324 bfa_timer_stop(&fcport->timer);
963 pport->stats_status = BFA_STATUS_OK; 1325 fcport->stats_status = BFA_STATUS_OK;
964 bfa_cb_queue(pport->bfa, &pport->hcb_qe, 1326 bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
965 __bfa_cb_port_stats_clr, pport); 1327 __bfa_cb_fcport_stats_clr, fcport);
966 break; 1328 break;
967 1329
968 default: 1330 default:
969 bfa_assert(0); 1331 bfa_assert(0);
1332 break;
970 } 1333 }
971} 1334}
972 1335
973
974
975/** 1336/**
976 * bfa_pport_api 1337 * bfa_pport_api
977 */ 1338 */
@@ -980,35 +1341,35 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
980 * Registered callback for port events. 1341 * Registered callback for port events.
981 */ 1342 */
982void 1343void
983bfa_pport_event_register(struct bfa_s *bfa, 1344bfa_fcport_event_register(struct bfa_s *bfa,
984 void (*cbfn) (void *cbarg, bfa_pport_event_t event), 1345 void (*cbfn) (void *cbarg, bfa_pport_event_t event),
985 void *cbarg) 1346 void *cbarg)
986{ 1347{
987 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1348 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
988 1349
989 pport->event_cbfn = cbfn; 1350 fcport->event_cbfn = cbfn;
990 pport->event_cbarg = cbarg; 1351 fcport->event_cbarg = cbarg;
991} 1352}
992 1353
993bfa_status_t 1354bfa_status_t
994bfa_pport_enable(struct bfa_s *bfa) 1355bfa_fcport_enable(struct bfa_s *bfa)
995{ 1356{
996 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1357 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
997 1358
998 if (pport->diag_busy) 1359 if (fcport->diag_busy)
999 return BFA_STATUS_DIAG_BUSY; 1360 return BFA_STATUS_DIAG_BUSY;
1000 else if (bfa_sm_cmp_state 1361 else if (bfa_sm_cmp_state
1001 (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait)) 1362 (BFA_FCPORT_MOD(bfa), bfa_fcport_sm_disabling_qwait))
1002 return BFA_STATUS_DEVBUSY; 1363 return BFA_STATUS_DEVBUSY;
1003 1364
1004 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE); 1365 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE);
1005 return BFA_STATUS_OK; 1366 return BFA_STATUS_OK;
1006} 1367}
1007 1368
1008bfa_status_t 1369bfa_status_t
1009bfa_pport_disable(struct bfa_s *bfa) 1370bfa_fcport_disable(struct bfa_s *bfa)
1010{ 1371{
1011 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE); 1372 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
1012 return BFA_STATUS_OK; 1373 return BFA_STATUS_OK;
1013} 1374}
1014 1375
@@ -1016,18 +1377,18 @@ bfa_pport_disable(struct bfa_s *bfa)
1016 * Configure port speed. 1377 * Configure port speed.
1017 */ 1378 */
1018bfa_status_t 1379bfa_status_t
1019bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) 1380bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1020{ 1381{
1021 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1382 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1022 1383
1023 bfa_trc(bfa, speed); 1384 bfa_trc(bfa, speed);
1024 1385
1025 if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) { 1386 if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
1026 bfa_trc(bfa, pport->speed_sup); 1387 bfa_trc(bfa, fcport->speed_sup);
1027 return BFA_STATUS_UNSUPP_SPEED; 1388 return BFA_STATUS_UNSUPP_SPEED;
1028 } 1389 }
1029 1390
1030 pport->cfg.speed = speed; 1391 fcport->cfg.speed = speed;
1031 1392
1032 return BFA_STATUS_OK; 1393 return BFA_STATUS_OK;
1033} 1394}
@@ -1036,23 +1397,23 @@ bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1036 * Get current speed. 1397 * Get current speed.
1037 */ 1398 */
1038enum bfa_pport_speed 1399enum bfa_pport_speed
1039bfa_pport_get_speed(struct bfa_s *bfa) 1400bfa_fcport_get_speed(struct bfa_s *bfa)
1040{ 1401{
1041 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1402 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1042 1403
1043 return port->speed; 1404 return fcport->speed;
1044} 1405}
1045 1406
1046/** 1407/**
1047 * Configure port topology. 1408 * Configure port topology.
1048 */ 1409 */
1049bfa_status_t 1410bfa_status_t
1050bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) 1411bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
1051{ 1412{
1052 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1413 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1053 1414
1054 bfa_trc(bfa, topology); 1415 bfa_trc(bfa, topology);
1055 bfa_trc(bfa, pport->cfg.topology); 1416 bfa_trc(bfa, fcport->cfg.topology);
1056 1417
1057 switch (topology) { 1418 switch (topology) {
1058 case BFA_PPORT_TOPOLOGY_P2P: 1419 case BFA_PPORT_TOPOLOGY_P2P:
@@ -1064,7 +1425,7 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
1064 return BFA_STATUS_EINVAL; 1425 return BFA_STATUS_EINVAL;
1065 } 1426 }
1066 1427
1067 pport->cfg.topology = topology; 1428 fcport->cfg.topology = topology;
1068 return BFA_STATUS_OK; 1429 return BFA_STATUS_OK;
1069} 1430}
1070 1431
@@ -1072,64 +1433,64 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
1072 * Get current topology. 1433 * Get current topology.
1073 */ 1434 */
1074enum bfa_pport_topology 1435enum bfa_pport_topology
1075bfa_pport_get_topology(struct bfa_s *bfa) 1436bfa_fcport_get_topology(struct bfa_s *bfa)
1076{ 1437{
1077 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1438 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1078 1439
1079 return port->topology; 1440 return fcport->topology;
1080} 1441}
1081 1442
1082bfa_status_t 1443bfa_status_t
1083bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) 1444bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
1084{ 1445{
1085 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1446 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1086 1447
1087 bfa_trc(bfa, alpa); 1448 bfa_trc(bfa, alpa);
1088 bfa_trc(bfa, pport->cfg.cfg_hardalpa); 1449 bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
1089 bfa_trc(bfa, pport->cfg.hardalpa); 1450 bfa_trc(bfa, fcport->cfg.hardalpa);
1090 1451
1091 pport->cfg.cfg_hardalpa = BFA_TRUE; 1452 fcport->cfg.cfg_hardalpa = BFA_TRUE;
1092 pport->cfg.hardalpa = alpa; 1453 fcport->cfg.hardalpa = alpa;
1093 1454
1094 return BFA_STATUS_OK; 1455 return BFA_STATUS_OK;
1095} 1456}
1096 1457
1097bfa_status_t 1458bfa_status_t
1098bfa_pport_clr_hardalpa(struct bfa_s *bfa) 1459bfa_fcport_clr_hardalpa(struct bfa_s *bfa)
1099{ 1460{
1100 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1461 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1101 1462
1102 bfa_trc(bfa, pport->cfg.cfg_hardalpa); 1463 bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
1103 bfa_trc(bfa, pport->cfg.hardalpa); 1464 bfa_trc(bfa, fcport->cfg.hardalpa);
1104 1465
1105 pport->cfg.cfg_hardalpa = BFA_FALSE; 1466 fcport->cfg.cfg_hardalpa = BFA_FALSE;
1106 return BFA_STATUS_OK; 1467 return BFA_STATUS_OK;
1107} 1468}
1108 1469
1109bfa_boolean_t 1470bfa_boolean_t
1110bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) 1471bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
1111{ 1472{
1112 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1473 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1113 1474
1114 *alpa = port->cfg.hardalpa; 1475 *alpa = fcport->cfg.hardalpa;
1115 return port->cfg.cfg_hardalpa; 1476 return fcport->cfg.cfg_hardalpa;
1116} 1477}
1117 1478
1118u8 1479u8
1119bfa_pport_get_myalpa(struct bfa_s *bfa) 1480bfa_fcport_get_myalpa(struct bfa_s *bfa)
1120{ 1481{
1121 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1482 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1122 1483
1123 return port->myalpa; 1484 return fcport->myalpa;
1124} 1485}
1125 1486
1126bfa_status_t 1487bfa_status_t
1127bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) 1488bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
1128{ 1489{
1129 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1490 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1130 1491
1131 bfa_trc(bfa, maxfrsize); 1492 bfa_trc(bfa, maxfrsize);
1132 bfa_trc(bfa, pport->cfg.maxfrsize); 1493 bfa_trc(bfa, fcport->cfg.maxfrsize);
1133 1494
1134 /* 1495 /*
1135 * with in range 1496 * with in range
@@ -1143,41 +1504,41 @@ bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
1143 if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1))) 1504 if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
1144 return BFA_STATUS_INVLD_DFSZ; 1505 return BFA_STATUS_INVLD_DFSZ;
1145 1506
1146 pport->cfg.maxfrsize = maxfrsize; 1507 fcport->cfg.maxfrsize = maxfrsize;
1147 return BFA_STATUS_OK; 1508 return BFA_STATUS_OK;
1148} 1509}
1149 1510
1150u16 1511u16
1151bfa_pport_get_maxfrsize(struct bfa_s *bfa) 1512bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
1152{ 1513{
1153 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1514 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1154 1515
1155 return port->cfg.maxfrsize; 1516 return fcport->cfg.maxfrsize;
1156} 1517}
1157 1518
1158u32 1519u32
1159bfa_pport_mypid(struct bfa_s *bfa) 1520bfa_fcport_mypid(struct bfa_s *bfa)
1160{ 1521{
1161 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1522 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1162 1523
1163 return port->mypid; 1524 return fcport->mypid;
1164} 1525}
1165 1526
1166u8 1527u8
1167bfa_pport_get_rx_bbcredit(struct bfa_s *bfa) 1528bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
1168{ 1529{
1169 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1530 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1170 1531
1171 return port->cfg.rx_bbcredit; 1532 return fcport->cfg.rx_bbcredit;
1172} 1533}
1173 1534
1174void 1535void
1175bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) 1536bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
1176{ 1537{
1177 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1538 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1178 1539
1179 port->cfg.tx_bbcredit = (u8) tx_bbcredit; 1540 fcport->cfg.tx_bbcredit = (u8) tx_bbcredit;
1180 bfa_port_send_txcredit(port); 1541 bfa_fcport_send_txcredit(fcport);
1181} 1542}
1182 1543
1183/** 1544/**
@@ -1185,302 +1546,192 @@ bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
1185 */ 1546 */
1186 1547
1187wwn_t 1548wwn_t
1188bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) 1549bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
1189{ 1550{
1190 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1551 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1191 if (node) 1552 if (node)
1192 return pport->nwwn; 1553 return fcport->nwwn;
1193 else 1554 else
1194 return pport->pwwn; 1555 return fcport->pwwn;
1195} 1556}
1196 1557
1197void 1558void
1198bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr) 1559bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
1199{ 1560{
1200 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1561 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1201 1562
1202 bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s)); 1563 bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
1203 1564
1204 attr->nwwn = pport->nwwn; 1565 attr->nwwn = fcport->nwwn;
1205 attr->pwwn = pport->pwwn; 1566 attr->pwwn = fcport->pwwn;
1206 1567
1207 bfa_os_memcpy(&attr->pport_cfg, &pport->cfg, 1568 bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
1208 sizeof(struct bfa_pport_cfg_s)); 1569 sizeof(struct bfa_pport_cfg_s));
1209 /* 1570 /*
1210 * speed attributes 1571 * speed attributes
1211 */ 1572 */
1212 attr->pport_cfg.speed = pport->cfg.speed; 1573 attr->pport_cfg.speed = fcport->cfg.speed;
1213 attr->speed_supported = pport->speed_sup; 1574 attr->speed_supported = fcport->speed_sup;
1214 attr->speed = pport->speed; 1575 attr->speed = fcport->speed;
1215 attr->cos_supported = FC_CLASS_3; 1576 attr->cos_supported = FC_CLASS_3;
1216 1577
1217 /* 1578 /*
1218 * topology attributes 1579 * topology attributes
1219 */ 1580 */
1220 attr->pport_cfg.topology = pport->cfg.topology; 1581 attr->pport_cfg.topology = fcport->cfg.topology;
1221 attr->topology = pport->topology; 1582 attr->topology = fcport->topology;
1222 1583
1223 /* 1584 /*
1224 * beacon attributes 1585 * beacon attributes
1225 */ 1586 */
1226 attr->beacon = pport->beacon; 1587 attr->beacon = fcport->beacon;
1227 attr->link_e2e_beacon = pport->link_e2e_beacon; 1588 attr->link_e2e_beacon = fcport->link_e2e_beacon;
1228 attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog); 1589 attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog);
1229 1590
1230 attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); 1591 attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
1231 attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); 1592 attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
1232 attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm); 1593 attr->port_state = bfa_sm_to_state(hal_pport_sm_table, fcport->sm);
1233 if (bfa_ioc_is_disabled(&pport->bfa->ioc)) 1594 if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
1234 attr->port_state = BFA_PPORT_ST_IOCDIS; 1595 attr->port_state = BFA_PPORT_ST_IOCDIS;
1235 else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc)) 1596 else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
1236 attr->port_state = BFA_PPORT_ST_FWMISMATCH; 1597 attr->port_state = BFA_PPORT_ST_FWMISMATCH;
1237} 1598}
1238 1599
1239static void 1600#define BFA_FCPORT_STATS_TOV 1000
1240bfa_port_stats_query(void *cbarg)
1241{
1242 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1243 bfi_pport_get_stats_req_t *msg;
1244
1245 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1246
1247 if (!msg) {
1248 port->stats_qfull = BFA_TRUE;
1249 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query,
1250 port);
1251 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1252 return;
1253 }
1254 port->stats_qfull = BFA_FALSE;
1255
1256 bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t));
1257 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ,
1258 bfa_lpuid(port->bfa));
1259 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1260
1261 return;
1262}
1263
1264static void
1265bfa_port_stats_clear(void *cbarg)
1266{
1267 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1268 bfi_pport_clear_stats_req_t *msg;
1269
1270 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1271 1601
1272 if (!msg) { 1602/**
1273 port->stats_qfull = BFA_TRUE; 1603 * Fetch port attributes (FCQoS or FCoE).
1274 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear, 1604 */
1275 port); 1605bfa_status_t
1276 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); 1606bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
1277 return; 1607 bfa_cb_pport_t cbfn, void *cbarg)
1278 }
1279 port->stats_qfull = BFA_FALSE;
1280
1281 bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t));
1282 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ,
1283 bfa_lpuid(port->bfa));
1284 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1285 return;
1286}
1287
1288static void
1289bfa_port_qos_stats_clear(void *cbarg)
1290{ 1608{
1291 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; 1609 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1292 bfi_pport_clear_qos_stats_req_t *msg;
1293
1294 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1295 1610
1296 if (!msg) { 1611 if (fcport->stats_busy) {
1297 port->stats_qfull = BFA_TRUE; 1612 bfa_trc(bfa, fcport->stats_busy);
1298 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear, 1613 return BFA_STATUS_DEVBUSY;
1299 port);
1300 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1301 return;
1302 } 1614 }
1303 port->stats_qfull = BFA_FALSE;
1304 1615
1305 bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t)); 1616 fcport->stats_busy = BFA_TRUE;
1306 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ, 1617 fcport->stats_ret = stats;
1307 bfa_lpuid(port->bfa)); 1618 fcport->stats_cbfn = cbfn;
1308 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); 1619 fcport->stats_cbarg = cbarg;
1309 return;
1310}
1311
1312static void
1313bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s)
1314{
1315 u32 *dip = (u32 *) d;
1316 u32 *sip = (u32 *) s;
1317 int i;
1318 1620
1319 /* 1621 bfa_fcport_send_stats_get(fcport);
1320 * Do 64 bit fields swap first
1321 */
1322 for (i = 0;
1323 i <
1324 ((sizeof(union bfa_pport_stats_u) -
1325 sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) {
1326#ifdef __BIGENDIAN
1327 dip[i] = bfa_os_ntohl(sip[i]);
1328 dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
1329#else
1330 dip[i] = bfa_os_ntohl(sip[i + 1]);
1331 dip[i + 1] = bfa_os_ntohl(sip[i]);
1332#endif
1333 }
1334 1622
1335 /* 1623 bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
1336 * Now swap the 32 bit fields 1624 fcport, BFA_FCPORT_STATS_TOV);
1337 */ 1625 return BFA_STATUS_OK;
1338 for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i)
1339 dip[i] = bfa_os_ntohl(sip[i]);
1340} 1626}
1341 1627
1342static void 1628/**
1343__bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete) 1629 * Reset port statistics (FCQoS or FCoE).
1630 */
1631bfa_status_t
1632bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1344{ 1633{
1345 struct bfa_pport_s *port = cbarg; 1634 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1346 1635
1347 if (complete) { 1636 if (fcport->stats_busy) {
1348 port->stats_cbfn(port->stats_cbarg, port->stats_status); 1637 bfa_trc(bfa, fcport->stats_busy);
1349 } else { 1638 return BFA_STATUS_DEVBUSY;
1350 port->stats_busy = BFA_FALSE;
1351 port->stats_status = BFA_STATUS_OK;
1352 } 1639 }
1353}
1354
1355static void
1356bfa_port_stats_clr_timeout(void *cbarg)
1357{
1358 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1359 1640
1360 bfa_trc(port->bfa, port->stats_qfull); 1641 fcport->stats_busy = BFA_TRUE;
1642 fcport->stats_cbfn = cbfn;
1643 fcport->stats_cbarg = cbarg;
1361 1644
1362 if (port->stats_qfull) { 1645 bfa_fcport_send_stats_clear(fcport);
1363 bfa_reqq_wcancel(&port->stats_reqq_wait);
1364 port->stats_qfull = BFA_FALSE;
1365 }
1366 1646
1367 port->stats_status = BFA_STATUS_ETIMER; 1647 bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
1368 bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port); 1648 fcport, BFA_FCPORT_STATS_TOV);
1649 return BFA_STATUS_OK;
1369} 1650}
1370 1651
1371static void 1652/**
1372__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete) 1653 * Fetch FCQoS port statistics
1654 */
1655bfa_status_t
1656bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
1657 bfa_cb_pport_t cbfn, void *cbarg)
1373{ 1658{
1374 struct bfa_pport_s *port = cbarg; 1659 /* Meaningful only for FC mode */
1660 bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
1375 1661
1376 if (complete) { 1662 return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
1377 if (port->stats_status == BFA_STATUS_OK)
1378 bfa_pport_stats_swap(port->stats_ret, port->stats);
1379 port->stats_cbfn(port->stats_cbarg, port->stats_status);
1380 } else {
1381 port->stats_busy = BFA_FALSE;
1382 port->stats_status = BFA_STATUS_OK;
1383 }
1384} 1663}
1385 1664
1386static void 1665/**
1387bfa_port_stats_timeout(void *cbarg) 1666 * Reset FCoE port statistics
1667 */
1668bfa_status_t
1669bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1388{ 1670{
1389 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; 1671 /* Meaningful only for FC mode */
1390 1672 bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
1391 bfa_trc(port->bfa, port->stats_qfull);
1392 1673
1393 if (port->stats_qfull) { 1674 return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
1394 bfa_reqq_wcancel(&port->stats_reqq_wait);
1395 port->stats_qfull = BFA_FALSE;
1396 }
1397
1398 port->stats_status = BFA_STATUS_ETIMER;
1399 bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port);
1400} 1675}
1401 1676
1402#define BFA_PORT_STATS_TOV 1000
1403
1404/** 1677/**
1405 * Fetch port attributes. 1678 * Fetch FCQoS port statistics
1406 */ 1679 */
1407bfa_status_t 1680bfa_status_t
1408bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, 1681bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
1409 bfa_cb_pport_t cbfn, void *cbarg) 1682 bfa_cb_pport_t cbfn, void *cbarg)
1410{ 1683{
1411 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1684 /* Meaningful only for FCoE mode */
1412 1685 bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
1413 if (port->stats_busy) {
1414 bfa_trc(bfa, port->stats_busy);
1415 return BFA_STATUS_DEVBUSY;
1416 }
1417
1418 port->stats_busy = BFA_TRUE;
1419 port->stats_ret = stats;
1420 port->stats_cbfn = cbfn;
1421 port->stats_cbarg = cbarg;
1422
1423 bfa_port_stats_query(port);
1424 1686
1425 bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port, 1687 return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
1426 BFA_PORT_STATS_TOV);
1427 return BFA_STATUS_OK;
1428} 1688}
1429 1689
1690/**
1691 * Reset FCoE port statistics
1692 */
1430bfa_status_t 1693bfa_status_t
1431bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) 1694bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1432{ 1695{
1433 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1696 /* Meaningful only for FCoE mode */
1434 1697 bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
1435 if (port->stats_busy) {
1436 bfa_trc(bfa, port->stats_busy);
1437 return BFA_STATUS_DEVBUSY;
1438 }
1439
1440 port->stats_busy = BFA_TRUE;
1441 port->stats_cbfn = cbfn;
1442 port->stats_cbarg = cbarg;
1443
1444 bfa_port_stats_clear(port);
1445 1698
1446 bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port, 1699 return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
1447 BFA_PORT_STATS_TOV);
1448 return BFA_STATUS_OK;
1449} 1700}
1450 1701
1451bfa_status_t 1702bfa_status_t
1452bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap) 1703bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
1453{ 1704{
1454 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1705 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1455 1706
1456 bfa_trc(bfa, bitmap); 1707 bfa_trc(bfa, bitmap);
1457 bfa_trc(bfa, pport->cfg.trunked); 1708 bfa_trc(bfa, fcport->cfg.trunked);
1458 bfa_trc(bfa, pport->cfg.trunk_ports); 1709 bfa_trc(bfa, fcport->cfg.trunk_ports);
1459 1710
1460 if (!bitmap || (bitmap & (bitmap - 1))) 1711 if (!bitmap || (bitmap & (bitmap - 1)))
1461 return BFA_STATUS_EINVAL; 1712 return BFA_STATUS_EINVAL;
1462 1713
1463 pport->cfg.trunked = BFA_TRUE; 1714 fcport->cfg.trunked = BFA_TRUE;
1464 pport->cfg.trunk_ports = bitmap; 1715 fcport->cfg.trunk_ports = bitmap;
1465 1716
1466 return BFA_STATUS_OK; 1717 return BFA_STATUS_OK;
1467} 1718}
1468 1719
1469void 1720void
1470bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr) 1721bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
1471{ 1722{
1472 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1723 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1473 1724
1474 qos_attr->state = bfa_os_ntohl(pport->qos_attr.state); 1725 qos_attr->state = bfa_os_ntohl(fcport->qos_attr.state);
1475 qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr); 1726 qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr);
1476} 1727}
1477 1728
1478void 1729void
1479bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, 1730bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
1480 struct bfa_qos_vc_attr_s *qos_vc_attr) 1731 struct bfa_qos_vc_attr_s *qos_vc_attr)
1481{ 1732{
1482 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1733 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1483 struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr; 1734 struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
1484 u32 i = 0; 1735 u32 i = 0;
1485 1736
1486 qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count); 1737 qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
@@ -1503,119 +1754,89 @@ bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
1503} 1754}
1504 1755
1505/** 1756/**
1506 * Fetch QoS Stats.
1507 */
1508bfa_status_t
1509bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
1510 bfa_cb_pport_t cbfn, void *cbarg)
1511{
1512 /*
1513 * QoS stats is embedded in port stats
1514 */
1515 return bfa_pport_get_stats(bfa, stats, cbfn, cbarg);
1516}
1517
1518bfa_status_t
1519bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1520{
1521 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1522
1523 if (port->stats_busy) {
1524 bfa_trc(bfa, port->stats_busy);
1525 return BFA_STATUS_DEVBUSY;
1526 }
1527
1528 port->stats_busy = BFA_TRUE;
1529 port->stats_cbfn = cbfn;
1530 port->stats_cbarg = cbarg;
1531
1532 bfa_port_qos_stats_clear(port);
1533
1534 bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
1535 BFA_PORT_STATS_TOV);
1536 return BFA_STATUS_OK;
1537}
1538
1539/**
1540 * Fetch port attributes. 1757 * Fetch port attributes.
1541 */ 1758 */
1542bfa_status_t 1759bfa_status_t
1543bfa_pport_trunk_disable(struct bfa_s *bfa) 1760bfa_fcport_trunk_disable(struct bfa_s *bfa)
1544{ 1761{
1545 return BFA_STATUS_OK; 1762 return BFA_STATUS_OK;
1546} 1763}
1547 1764
1548bfa_boolean_t 1765bfa_boolean_t
1549bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap) 1766bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
1550{ 1767{
1551 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1768 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1552 1769
1553 *bitmap = port->cfg.trunk_ports; 1770 *bitmap = fcport->cfg.trunk_ports;
1554 return port->cfg.trunked; 1771 return fcport->cfg.trunked;
1555} 1772}
1556 1773
1557bfa_boolean_t 1774bfa_boolean_t
1558bfa_pport_is_disabled(struct bfa_s *bfa) 1775bfa_fcport_is_disabled(struct bfa_s *bfa)
1559{ 1776{
1560 struct bfa_pport_s *port = BFA_PORT_MOD(bfa); 1777 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1561 1778
1562 return bfa_sm_to_state(hal_pport_sm_table, port->sm) == 1779 return bfa_sm_to_state(hal_pport_sm_table, fcport->sm) ==
1563 BFA_PPORT_ST_DISABLED; 1780 BFA_PPORT_ST_DISABLED;
1564 1781
1565} 1782}
1566 1783
1567bfa_boolean_t 1784bfa_boolean_t
1568bfa_pport_is_ratelim(struct bfa_s *bfa) 1785bfa_fcport_is_ratelim(struct bfa_s *bfa)
1569{ 1786{
1570 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1787 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1571 1788
1572 return pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE; 1789 return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
1573 1790
1574} 1791}
1575 1792
1576void 1793void
1577bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off) 1794bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
1578{ 1795{
1579 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1796 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1797 enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
1580 1798
1581 bfa_trc(bfa, on_off); 1799 bfa_trc(bfa, on_off);
1582 bfa_trc(bfa, pport->cfg.qos_enabled); 1800 bfa_trc(bfa, fcport->cfg.qos_enabled);
1801
1802 bfa_trc(bfa, ioc_type);
1583 1803
1584 pport->cfg.qos_enabled = on_off; 1804 if (ioc_type == BFA_IOC_TYPE_FC)
1805 fcport->cfg.qos_enabled = on_off;
1585} 1806}
1586 1807
1587void 1808void
1588bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off) 1809bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
1589{ 1810{
1590 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1811 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1591 1812
1592 bfa_trc(bfa, on_off); 1813 bfa_trc(bfa, on_off);
1593 bfa_trc(bfa, pport->cfg.ratelimit); 1814 bfa_trc(bfa, fcport->cfg.ratelimit);
1594 1815
1595 pport->cfg.ratelimit = on_off; 1816 fcport->cfg.ratelimit = on_off;
1596 if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN) 1817 if (fcport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
1597 pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS; 1818 fcport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
1598} 1819}
1599 1820
1600/** 1821/**
1601 * Configure default minimum ratelim speed 1822 * Configure default minimum ratelim speed
1602 */ 1823 */
1603bfa_status_t 1824bfa_status_t
1604bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) 1825bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1605{ 1826{
1606 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1827 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1607 1828
1608 bfa_trc(bfa, speed); 1829 bfa_trc(bfa, speed);
1609 1830
1610 /* 1831 /*
1611 * Auto and speeds greater than the supported speed, are invalid 1832 * Auto and speeds greater than the supported speed, are invalid
1612 */ 1833 */
1613 if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) { 1834 if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > fcport->speed_sup)) {
1614 bfa_trc(bfa, pport->speed_sup); 1835 bfa_trc(bfa, fcport->speed_sup);
1615 return BFA_STATUS_UNSUPP_SPEED; 1836 return BFA_STATUS_UNSUPP_SPEED;
1616 } 1837 }
1617 1838
1618 pport->cfg.trl_def_speed = speed; 1839 fcport->cfg.trl_def_speed = speed;
1619 1840
1620 return BFA_STATUS_OK; 1841 return BFA_STATUS_OK;
1621} 1842}
@@ -1624,45 +1845,45 @@ bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1624 * Get default minimum ratelim speed 1845 * Get default minimum ratelim speed
1625 */ 1846 */
1626enum bfa_pport_speed 1847enum bfa_pport_speed
1627bfa_pport_get_ratelim_speed(struct bfa_s *bfa) 1848bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
1628{ 1849{
1629 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1850 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1630 1851
1631 bfa_trc(bfa, pport->cfg.trl_def_speed); 1852 bfa_trc(bfa, fcport->cfg.trl_def_speed);
1632 return pport->cfg.trl_def_speed; 1853 return fcport->cfg.trl_def_speed;
1633 1854
1634} 1855}
1635 1856
1636void 1857void
1637bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status) 1858bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status)
1638{ 1859{
1639 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1860 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1640 1861
1641 bfa_trc(bfa, status); 1862 bfa_trc(bfa, status);
1642 bfa_trc(bfa, pport->diag_busy); 1863 bfa_trc(bfa, fcport->diag_busy);
1643 1864
1644 pport->diag_busy = status; 1865 fcport->diag_busy = status;
1645} 1866}
1646 1867
1647void 1868void
1648bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, 1869bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
1649 bfa_boolean_t link_e2e_beacon) 1870 bfa_boolean_t link_e2e_beacon)
1650{ 1871{
1651 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 1872 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1652 1873
1653 bfa_trc(bfa, beacon); 1874 bfa_trc(bfa, beacon);
1654 bfa_trc(bfa, link_e2e_beacon); 1875 bfa_trc(bfa, link_e2e_beacon);
1655 bfa_trc(bfa, pport->beacon); 1876 bfa_trc(bfa, fcport->beacon);
1656 bfa_trc(bfa, pport->link_e2e_beacon); 1877 bfa_trc(bfa, fcport->link_e2e_beacon);
1657 1878
1658 pport->beacon = beacon; 1879 fcport->beacon = beacon;
1659 pport->link_e2e_beacon = link_e2e_beacon; 1880 fcport->link_e2e_beacon = link_e2e_beacon;
1660} 1881}
1661 1882
1662bfa_boolean_t 1883bfa_boolean_t
1663bfa_pport_is_linkup(struct bfa_s *bfa) 1884bfa_fcport_is_linkup(struct bfa_s *bfa)
1664{ 1885{
1665 return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup); 1886 return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup);
1666} 1887}
1667 1888
1668 1889
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index 7cb39a306ea9..3516172c597c 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -36,6 +36,7 @@
36 * FCS sub-modules 36 * FCS sub-modules
37 */ 37 */
38struct bfa_fcs_mod_s { 38struct bfa_fcs_mod_s {
39 void (*attach) (struct bfa_fcs_s *fcs);
39 void (*modinit) (struct bfa_fcs_s *fcs); 40 void (*modinit) (struct bfa_fcs_s *fcs);
40 void (*modexit) (struct bfa_fcs_s *fcs); 41 void (*modexit) (struct bfa_fcs_s *fcs);
41}; 42};
@@ -43,12 +44,10 @@ struct bfa_fcs_mod_s {
43#define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit } 44#define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
44 45
45static struct bfa_fcs_mod_s fcs_modules[] = { 46static struct bfa_fcs_mod_s fcs_modules[] = {
46 BFA_FCS_MODULE(bfa_fcs_pport), 47 { bfa_fcs_pport_attach, NULL, NULL },
47 BFA_FCS_MODULE(bfa_fcs_uf), 48 { bfa_fcs_uf_attach, NULL, NULL },
48 BFA_FCS_MODULE(bfa_fcs_fabric), 49 { bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
49 BFA_FCS_MODULE(bfa_fcs_vport), 50 bfa_fcs_fabric_modexit },
50 BFA_FCS_MODULE(bfa_fcs_rport),
51 BFA_FCS_MODULE(bfa_fcs_fcpim),
52}; 51};
53 52
54/** 53/**
@@ -71,16 +70,10 @@ bfa_fcs_exit_comp(void *fcs_cbarg)
71 */ 70 */
72 71
73/** 72/**
74 * FCS instance initialization. 73 * fcs attach -- called once to initialize data structures at driver attach time
75 *
76 * param[in] fcs FCS instance
77 * param[in] bfa BFA instance
78 * param[in] bfad BFA driver instance
79 *
80 * return None
81 */ 74 */
82void 75void
83bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, 76bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
84 bfa_boolean_t min_cfg) 77 bfa_boolean_t min_cfg)
85{ 78{
86 int i; 79 int i;
@@ -95,7 +88,24 @@ bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
95 88
96 for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) { 89 for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
97 mod = &fcs_modules[i]; 90 mod = &fcs_modules[i];
98 mod->modinit(fcs); 91 if (mod->attach)
92 mod->attach(fcs);
93 }
94}
95
96/**
97 * fcs initialization, called once after bfa initialization is complete
98 */
99void
100bfa_fcs_init(struct bfa_fcs_s *fcs)
101{
102 int i;
103 struct bfa_fcs_mod_s *mod;
104
105 for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
106 mod = &fcs_modules[i];
107 if (mod->modinit)
108 mod->modinit(fcs);
99 } 109 }
100} 110}
101 111
@@ -127,6 +137,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
127} 137}
128 138
129/** 139/**
140 * @brief
141 * FCS FDMI Driver Parameter Initialization
142 *
143 * @param[in] fcs FCS instance
144 * @param[in] fdmi_enable TRUE/FALSE
145 *
146 * @return None
147 */
148void
149bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable)
150{
151
152 fcs->fdmi_enabled = fdmi_enable;
153
154}
155
156/**
130 * FCS instance cleanup and exit. 157 * FCS instance cleanup and exit.
131 * 158 *
132 * param[in] fcs FCS instance 159 * param[in] fcs FCS instance
@@ -143,10 +170,12 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
143 nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]); 170 nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
144 171
145 for (i = 0; i < nmods; i++) { 172 for (i = 0; i < nmods; i++) {
146 bfa_wc_up(&fcs->wc);
147 173
148 mod = &fcs_modules[i]; 174 mod = &fcs_modules[i];
149 mod->modexit(fcs); 175 if (mod->modexit) {
176 bfa_wc_up(&fcs->wc);
177 mod->modexit(fcs);
178 }
150 } 179 }
151 180
152 bfa_wc_wait(&fcs->wc); 181 bfa_wc_wait(&fcs->wc);
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index c7ab257f10a7..7c1251c682d8 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -114,7 +114,7 @@ bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
114 break; 114 break;
115 115
116 default: 116 default:
117 bfa_assert(0); 117 bfa_sm_fault(port->fcs, event);
118 } 118 }
119} 119}
120 120
@@ -136,7 +136,7 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
136 break; 136 break;
137 137
138 default: 138 default:
139 bfa_assert(0); 139 bfa_sm_fault(port->fcs, event);
140 } 140 }
141} 141}
142 142
@@ -176,7 +176,7 @@ bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
176 break; 176 break;
177 177
178 default: 178 default:
179 bfa_assert(0); 179 bfa_sm_fault(port->fcs, event);
180 } 180 }
181} 181}
182 182
@@ -214,7 +214,7 @@ bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
214 break; 214 break;
215 215
216 default: 216 default:
217 bfa_assert(0); 217 bfa_sm_fault(port->fcs, event);
218 } 218 }
219} 219}
220 220
@@ -234,7 +234,7 @@ bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
234 break; 234 break;
235 235
236 default: 236 default:
237 bfa_assert(0); 237 bfa_sm_fault(port->fcs, event);
238 } 238 }
239} 239}
240 240
@@ -263,30 +263,8 @@ bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
263 263
264 bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); 264 bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
265 265
266 switch (event) { 266 bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
267 case BFA_LPORT_AEN_ONLINE: 267 role_str[role/2]);
268 bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr,
269 role_str[role / 2]);
270 break;
271 case BFA_LPORT_AEN_OFFLINE:
272 bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr,
273 role_str[role / 2]);
274 break;
275 case BFA_LPORT_AEN_NEW:
276 bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr,
277 role_str[role / 2]);
278 break;
279 case BFA_LPORT_AEN_DELETE:
280 bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr,
281 role_str[role / 2]);
282 break;
283 case BFA_LPORT_AEN_DISCONNECT:
284 bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr,
285 role_str[role / 2]);
286 break;
287 default:
288 break;
289 }
290 268
291 aen_data.lport.vf_id = port->fabric->vf_id; 269 aen_data.lport.vf_id = port->fabric->vf_id;
292 aen_data.lport.roles = role; 270 aen_data.lport.roles = role;
@@ -873,36 +851,46 @@ bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
873} 851}
874 852
875/** 853/**
876 * Logical port initialization of base or virtual port. 854 * Attach time initialization of logical ports.
877 * Called by fabric for base port or by vport for virtual ports.
878 */ 855 */
879void 856void
880bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, 857bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
881 u16 vf_id, struct bfa_port_cfg_s *port_cfg, 858 uint16_t vf_id, struct bfa_fcs_vport_s *vport)
882 struct bfa_fcs_vport_s *vport)
883{ 859{
884 lport->fcs = fcs; 860 lport->fcs = fcs;
885 lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); 861 lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
886 bfa_os_assign(lport->port_cfg, *port_cfg);
887 lport->vport = vport; 862 lport->vport = vport;
888 lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) : 863 lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
889 bfa_lps_get_tag(lport->fabric->lps); 864 bfa_lps_get_tag(lport->fabric->lps);
890 865
891 INIT_LIST_HEAD(&lport->rport_q); 866 INIT_LIST_HEAD(&lport->rport_q);
892 lport->num_rports = 0; 867 lport->num_rports = 0;
868}
869
870/**
871 * Logical port initialization of base or virtual port.
872 * Called by fabric for base port or by vport for virtual ports.
873 */
893 874
894 lport->bfad_port = 875void
895 bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles, 876bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
877 struct bfa_port_cfg_s *port_cfg)
878{
879 struct bfa_fcs_vport_s *vport = lport->vport;
880
881 bfa_os_assign(lport->port_cfg, *port_cfg);
882
883 lport->bfad_port = bfa_fcb_port_new(lport->fcs->bfad, lport,
884 lport->port_cfg.roles,
896 lport->fabric->vf_drv, 885 lport->fabric->vf_drv,
897 vport ? vport->vport_drv : NULL); 886 vport ? vport->vport_drv : NULL);
887
898 bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW); 888 bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
899 889
900 bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit); 890 bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
901 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); 891 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
902} 892}
903 893
904
905
906/** 894/**
907 * fcs_lport_api 895 * fcs_lport_api
908 */ 896 */
@@ -921,13 +909,20 @@ bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
921 if (port->fabric) { 909 if (port->fabric) {
922 port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric); 910 port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
923 port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric); 911 port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
912 port_attr->authfail =
913 bfa_fcs_fabric_is_auth_failed(port->fabric);
924 port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port); 914 port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
925 memcpy(port_attr->fabric_ip_addr, 915 memcpy(port_attr->fabric_ip_addr,
926 bfa_fcs_port_get_fabric_ipaddr(port), 916 bfa_fcs_port_get_fabric_ipaddr(port),
927 BFA_FCS_FABRIC_IPADDR_SZ); 917 BFA_FCS_FABRIC_IPADDR_SZ);
928 918
929 if (port->vport != NULL) 919 if (port->vport != NULL) {
930 port_attr->port_type = BFA_PPORT_TYPE_VPORT; 920 port_attr->port_type = BFA_PPORT_TYPE_VPORT;
921 port_attr->fpma_mac =
922 bfa_lps_get_lp_mac(port->vport->lps);
923 } else
924 port_attr->fpma_mac =
925 bfa_lps_get_lp_mac(port->fabric->lps);
931 926
932 } else { 927 } else {
933 port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN; 928 port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
diff --git a/drivers/scsi/bfa/bfa_fcs_port.c b/drivers/scsi/bfa/bfa_fcs_port.c
index 9c4b24e62de1..3c27788cd527 100644
--- a/drivers/scsi/bfa/bfa_fcs_port.c
+++ b/drivers/scsi/bfa/bfa_fcs_port.c
@@ -55,14 +55,7 @@ bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event)
55} 55}
56 56
57void 57void
58bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs) 58bfa_fcs_pport_attach(struct bfa_fcs_s *fcs)
59{ 59{
60 bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, 60 bfa_fcport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs);
61 fcs);
62}
63
64void
65bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs)
66{
67 bfa_fcs_modexit_comp(fcs);
68} 61}
diff --git a/drivers/scsi/bfa/bfa_fcs_uf.c b/drivers/scsi/bfa/bfa_fcs_uf.c
index ad01db6444b2..3d57d48bbae4 100644
--- a/drivers/scsi/bfa/bfa_fcs_uf.c
+++ b/drivers/scsi/bfa/bfa_fcs_uf.c
@@ -93,13 +93,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
93} 93}
94 94
95void 95void
96bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs) 96bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
97{ 97{
98 bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs); 98 bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
99} 99}
100
101void
102bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs)
103{
104 bfa_fcs_modexit_comp(fcs);
105}
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
index ede1438619e2..871a4e28575c 100644
--- a/drivers/scsi/bfa/bfa_hw_cb.c
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -53,6 +53,18 @@ bfa_hwcb_reginit(struct bfa_s *bfa)
53} 53}
54 54
55void 55void
56bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq)
57{
58}
59
60static void
61bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
62{
63 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
64 __HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq));
65}
66
67void
56bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq) 68bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
57{ 69{
58} 70}
@@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
136void 148void
137bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) 149bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
138{ 150{
151 bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
139 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix; 152 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
140} 153}
141 154
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c
index 51ae5740e6e9..76ceb9a4bf2f 100644
--- a/drivers/scsi/bfa/bfa_hw_ct.c
+++ b/drivers/scsi/bfa/bfa_hw_ct.c
@@ -85,6 +85,15 @@ bfa_hwct_reginit(struct bfa_s *bfa)
85} 85}
86 86
87void 87void
88bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
89{
90 u32 r32;
91
92 r32 = bfa_reg_read(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
93 bfa_reg_write(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq], r32);
94}
95
96void
88bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) 97bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
89{ 98{
90 u32 r32; 99 u32 r32;
diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c
index b36540e4ed76..0eba3f930d5b 100644
--- a/drivers/scsi/bfa/bfa_intr.c
+++ b/drivers/scsi/bfa/bfa_intr.c
@@ -15,7 +15,7 @@
15 * General Public License for more details. 15 * General Public License for more details.
16 */ 16 */
17#include <bfa.h> 17#include <bfa.h>
18#include <bfi/bfi_cbreg.h> 18#include <bfi/bfi_ctreg.h>
19#include <bfa_port_priv.h> 19#include <bfa_port_priv.h>
20#include <bfa_intr_priv.h> 20#include <bfa_intr_priv.h>
21#include <cs/bfa_debug.h> 21#include <cs/bfa_debug.h>
@@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa)
34 bfa_ioc_mbox_isr(&bfa->ioc); 34 bfa_ioc_mbox_isr(&bfa->ioc);
35} 35}
36 36
37static void
38bfa_reqq_resume(struct bfa_s *bfa, int qid)
39{
40 struct list_head *waitq, *qe, *qen;
41 struct bfa_reqq_wait_s *wqe;
42
43 waitq = bfa_reqq(bfa, qid);
44 list_for_each_safe(qe, qen, waitq) {
45 /**
46 * Callback only as long as there is room in request queue
47 */
48 if (bfa_reqq_full(bfa, qid))
49 break;
50
51 list_del(qe);
52 wqe = (struct bfa_reqq_wait_s *) qe;
53 wqe->qresume(wqe->cbarg);
54 }
55}
56
37void 57void
38bfa_msix_all(struct bfa_s *bfa, int vec) 58bfa_msix_all(struct bfa_s *bfa, int vec)
39{ 59{
@@ -96,7 +116,8 @@ bfa_isr_enable(struct bfa_s *bfa)
96 116
97 bfa_msix_install(bfa); 117 bfa_msix_install(bfa);
98 intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | 118 intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
99 __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS); 119 __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS |
120 __HFN_INT_LL_HALT);
100 121
101 if (pci_func == 0) 122 if (pci_func == 0)
102 intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 | 123 intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
@@ -127,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa)
127void 148void
128bfa_msix_reqq(struct bfa_s *bfa, int qid) 149bfa_msix_reqq(struct bfa_s *bfa, int qid)
129{ 150{
130 struct list_head *waitq, *qe, *qen; 151 struct list_head *waitq;
131 struct bfa_reqq_wait_s *wqe;
132 152
133 qid &= (BFI_IOC_MAX_CQS - 1); 153 qid &= (BFI_IOC_MAX_CQS - 1);
134 154
135 waitq = bfa_reqq(bfa, qid); 155 bfa->iocfc.hwif.hw_reqq_ack(bfa, qid);
136 list_for_each_safe(qe, qen, waitq) {
137 /**
138 * Callback only as long as there is room in request queue
139 */
140 if (bfa_reqq_full(bfa, qid))
141 break;
142 156
143 list_del(qe); 157 /**
144 wqe = (struct bfa_reqq_wait_s *) qe; 158 * Resume any pending requests in the corresponding reqq.
145 wqe->qresume(wqe->cbarg); 159 */
146 } 160 waitq = bfa_reqq(bfa, qid);
161 if (!list_empty(waitq))
162 bfa_reqq_resume(bfa, qid);
147} 163}
148 164
149void 165void
@@ -157,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
157} 173}
158 174
159void 175void
160bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid) 176bfa_msix_rspq(struct bfa_s *bfa, int qid)
161{ 177{
162 struct bfi_msg_s *m; 178 struct bfi_msg_s *m;
163 u32 pi, ci; 179 u32 pi, ci;
180 struct list_head *waitq;
164 181
165 bfa_trc_fp(bfa, rsp_qid); 182 bfa_trc_fp(bfa, qid);
166 183
167 rsp_qid &= (BFI_IOC_MAX_CQS - 1); 184 qid &= (BFI_IOC_MAX_CQS - 1);
168 185
169 bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid); 186 bfa->iocfc.hwif.hw_rspq_ack(bfa, qid);
170 187
171 ci = bfa_rspq_ci(bfa, rsp_qid); 188 ci = bfa_rspq_ci(bfa, qid);
172 pi = bfa_rspq_pi(bfa, rsp_qid); 189 pi = bfa_rspq_pi(bfa, qid);
173 190
174 bfa_trc_fp(bfa, ci); 191 bfa_trc_fp(bfa, ci);
175 bfa_trc_fp(bfa, pi); 192 bfa_trc_fp(bfa, pi);
176 193
177 if (bfa->rme_process) { 194 if (bfa->rme_process) {
178 while (ci != pi) { 195 while (ci != pi) {
179 m = bfa_rspq_elem(bfa, rsp_qid, ci); 196 m = bfa_rspq_elem(bfa, qid, ci);
180 bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX); 197 bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
181 198
182 bfa_isrs[m->mhdr.msg_class] (bfa, m); 199 bfa_isrs[m->mhdr.msg_class] (bfa, m);
@@ -188,25 +205,59 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
188 /** 205 /**
189 * update CI 206 * update CI
190 */ 207 */
191 bfa_rspq_ci(bfa, rsp_qid) = pi; 208 bfa_rspq_ci(bfa, qid) = pi;
192 bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi); 209 bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi);
193 bfa_os_mmiowb(); 210 bfa_os_mmiowb();
211
212 /**
213 * Resume any pending requests in the corresponding reqq.
214 */
215 waitq = bfa_reqq(bfa, qid);
216 if (!list_empty(waitq))
217 bfa_reqq_resume(bfa, qid);
194} 218}
195 219
196void 220void
197bfa_msix_lpu_err(struct bfa_s *bfa, int vec) 221bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
198{ 222{
199 u32 intr; 223 u32 intr, curr_value;
200 224
201 intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status); 225 intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
202 226
203 if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1)) 227 if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
204 bfa_msix_lpu(bfa); 228 bfa_msix_lpu(bfa);
205 229
206 if (intr & (__HFN_INT_ERR_EMC | 230 intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
207 __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 | 231 __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT);
208 __HFN_INT_ERR_PSS)) 232
233 if (intr) {
234 if (intr & __HFN_INT_LL_HALT) {
235 /**
236 * If LL_HALT bit is set then FW Init Halt LL Port
237 * Register needs to be cleared as well so Interrupt
238 * Status Register will be cleared.
239 */
240 curr_value = bfa_reg_read(bfa->ioc.ioc_regs.ll_halt);
241 curr_value &= ~__FW_INIT_HALT_P;
242 bfa_reg_write(bfa->ioc.ioc_regs.ll_halt, curr_value);
243 }
244
245 if (intr & __HFN_INT_ERR_PSS) {
246 /**
247 * ERR_PSS bit needs to be cleared as well in case
248 * interrups are shared so driver's interrupt handler is
249 * still called eventhough it is already masked out.
250 */
251 curr_value = bfa_reg_read(
252 bfa->ioc.ioc_regs.pss_err_status_reg);
253 curr_value &= __PSS_ERR_STATUS_SET;
254 bfa_reg_write(bfa->ioc.ioc_regs.pss_err_status_reg,
255 curr_value);
256 }
257
258 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr);
209 bfa_msix_errint(bfa, intr); 259 bfa_msix_errint(bfa, intr);
260 }
210} 261}
211 262
212void 263void
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index 397d7e9eade5..e038bc9769f6 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -18,7 +18,7 @@
18#include <bfa.h> 18#include <bfa.h>
19#include <bfa_ioc.h> 19#include <bfa_ioc.h>
20#include <bfa_fwimg_priv.h> 20#include <bfa_fwimg_priv.h>
21#include <bfa_trcmod_priv.h> 21#include <cna/bfa_cna_trcmod.h>
22#include <cs/bfa_debug.h> 22#include <cs/bfa_debug.h>
23#include <bfi/bfi_ioc.h> 23#include <bfi/bfi_ioc.h>
24#include <bfi/bfi_ctreg.h> 24#include <bfi/bfi_ctreg.h>
@@ -27,18 +27,17 @@
27#include <log/bfa_log_hal.h> 27#include <log/bfa_log_hal.h>
28#include <defs/bfa_defs_pci.h> 28#include <defs/bfa_defs_pci.h>
29 29
30BFA_TRC_FILE(HAL, IOC); 30BFA_TRC_FILE(CNA, IOC);
31 31
32/** 32/**
33 * IOC local definitions 33 * IOC local definitions
34 */ 34 */
35#define BFA_IOC_TOV 2000 /* msecs */ 35#define BFA_IOC_TOV 2000 /* msecs */
36#define BFA_IOC_HB_TOV 1000 /* msecs */ 36#define BFA_IOC_HWSEM_TOV 500 /* msecs */
37#define BFA_IOC_HB_FAIL_MAX 4 37#define BFA_IOC_HB_TOV 500 /* msecs */
38#define BFA_IOC_HWINIT_MAX 2 38#define BFA_IOC_HWINIT_MAX 2
39#define BFA_IOC_FWIMG_MINSZ (16 * 1024) 39#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
40#define BFA_IOC_TOV_RECOVER (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \ 40#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV
41 + BFA_IOC_TOV)
42 41
43#define bfa_ioc_timer_start(__ioc) \ 42#define bfa_ioc_timer_start(__ioc) \
44 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ 43 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \
@@ -51,12 +50,25 @@ BFA_TRC_FILE(HAL, IOC);
51 (sizeof(struct bfa_trc_mod_s) - \ 50 (sizeof(struct bfa_trc_mod_s) - \
52 BFA_TRC_MAX * sizeof(struct bfa_trc_s))) 51 BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
53#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn)) 52#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
54#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
55 53
56#define BFA_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS) 54/**
57#define BFA_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS) 55 * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
58#define BFA_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS) 56 */
59bfa_boolean_t bfa_auto_recover = BFA_FALSE; 57
58#define bfa_ioc_firmware_lock(__ioc) \
59 ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
60#define bfa_ioc_firmware_unlock(__ioc) \
61 ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
62#define bfa_ioc_fwimg_get_chunk(__ioc, __off) \
63 ((__ioc)->ioc_hwif->ioc_fwimg_get_chunk(__ioc, __off))
64#define bfa_ioc_fwimg_get_size(__ioc) \
65 ((__ioc)->ioc_hwif->ioc_fwimg_get_size(__ioc))
66#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
67#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
68#define bfa_ioc_notify_hbfail(__ioc) \
69 ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
70
71bfa_boolean_t bfa_auto_recover = BFA_TRUE;
60 72
61/* 73/*
62 * forward declarations 74 * forward declarations
@@ -64,7 +76,6 @@ bfa_boolean_t bfa_auto_recover = BFA_FALSE;
64static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa, 76static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
65 enum bfa_ioc_aen_event event); 77 enum bfa_ioc_aen_event event);
66static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc); 78static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
67static void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
68static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc); 79static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
69static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force); 80static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
70static void bfa_ioc_timeout(void *ioc); 81static void bfa_ioc_timeout(void *ioc);
@@ -77,8 +88,6 @@ static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
77static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc); 88static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
78static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc); 89static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
79static void bfa_ioc_recover(struct bfa_ioc_s *ioc); 90static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
80static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc);
81static void bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc);
82static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); 91static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
83static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); 92static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
84 93
@@ -508,14 +517,19 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
508 bfa_trc(ioc, event); 517 bfa_trc(ioc, event);
509 518
510 switch (event) { 519 switch (event) {
511 case IOC_E_HWERROR:
512 case IOC_E_FWRSP_DISABLE: 520 case IOC_E_FWRSP_DISABLE:
513 bfa_ioc_timer_stop(ioc); 521 bfa_ioc_timer_stop(ioc);
522 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
523 break;
524
525 case IOC_E_HWERROR:
526 bfa_ioc_timer_stop(ioc);
514 /* 527 /*
515 * !!! fall through !!! 528 * !!! fall through !!!
516 */ 529 */
517 530
518 case IOC_E_TIMEOUT: 531 case IOC_E_TIMEOUT:
532 bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
519 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); 533 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
520 break; 534 break;
521 535
@@ -608,15 +622,12 @@ bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc)
608 * Mark IOC as failed in hardware and stop firmware. 622 * Mark IOC as failed in hardware and stop firmware.
609 */ 623 */
610 bfa_ioc_lpu_stop(ioc); 624 bfa_ioc_lpu_stop(ioc);
611 bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL); 625 bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
612 626
613 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { 627 /**
614 bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); 628 * Notify other functions on HB failure.
615 /* 629 */
616 * Wait for halt to take effect 630 bfa_ioc_notify_hbfail(ioc);
617 */
618 bfa_reg_read(ioc->ioc_regs.ll_halt);
619 }
620 631
621 /** 632 /**
622 * Notify driver and common modules registered for notification. 633 * Notify driver and common modules registered for notification.
@@ -672,6 +683,12 @@ bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event)
672 */ 683 */
673 break; 684 break;
674 685
686 case IOC_E_HWERROR:
687 /*
688 * HB failure notification, ignore.
689 */
690 break;
691
675 default: 692 default:
676 bfa_sm_fault(ioc, event); 693 bfa_sm_fault(ioc, event);
677 } 694 }
@@ -700,7 +717,7 @@ bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
700 } 717 }
701} 718}
702 719
703static void 720void
704bfa_ioc_sem_timeout(void *ioc_arg) 721bfa_ioc_sem_timeout(void *ioc_arg)
705{ 722{
706 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg; 723 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
@@ -708,26 +725,32 @@ bfa_ioc_sem_timeout(void *ioc_arg)
708 bfa_ioc_hw_sem_get(ioc); 725 bfa_ioc_hw_sem_get(ioc);
709} 726}
710 727
711static void 728bfa_boolean_t
712bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc) 729bfa_ioc_sem_get(bfa_os_addr_t sem_reg)
713{ 730{
714 u32 r32; 731 u32 r32;
715 int cnt = 0; 732 int cnt = 0;
716#define BFA_SEM_SPINCNT 1000 733#define BFA_SEM_SPINCNT 3000
717 734
718 do { 735 r32 = bfa_reg_read(sem_reg);
719 r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg); 736
737 while (r32 && (cnt < BFA_SEM_SPINCNT)) {
720 cnt++; 738 cnt++;
721 if (cnt > BFA_SEM_SPINCNT) 739 bfa_os_udelay(2);
722 break; 740 r32 = bfa_reg_read(sem_reg);
723 } while (r32 != 0); 741 }
742
743 if (r32 == 0)
744 return BFA_TRUE;
745
724 bfa_assert(cnt < BFA_SEM_SPINCNT); 746 bfa_assert(cnt < BFA_SEM_SPINCNT);
747 return BFA_FALSE;
725} 748}
726 749
727static void 750void
728bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc) 751bfa_ioc_sem_release(bfa_os_addr_t sem_reg)
729{ 752{
730 bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1); 753 bfa_reg_write(sem_reg, 1);
731} 754}
732 755
733static void 756static void
@@ -737,7 +760,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
737 760
738 /** 761 /**
739 * First read to the semaphore register will return 0, subsequent reads 762 * First read to the semaphore register will return 0, subsequent reads
740 * will return 1. Semaphore is released by writing 0 to the register 763 * will return 1. Semaphore is released by writing 1 to the register
741 */ 764 */
742 r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); 765 r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
743 if (r32 == 0) { 766 if (r32 == 0) {
@@ -746,10 +769,10 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
746 } 769 }
747 770
748 bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout, 771 bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout,
749 ioc, BFA_IOC_TOV); 772 ioc, BFA_IOC_HWSEM_TOV);
750} 773}
751 774
752static void 775void
753bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc) 776bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
754{ 777{
755 bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1); 778 bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
@@ -828,7 +851,7 @@ bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
828/** 851/**
829 * Get driver and firmware versions. 852 * Get driver and firmware versions.
830 */ 853 */
831static void 854void
832bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) 855bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
833{ 856{
834 u32 pgnum, pgoff; 857 u32 pgnum, pgoff;
@@ -847,24 +870,10 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
847 } 870 }
848} 871}
849 872
850static u32 *
851bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
852{
853 if (ioc->ctdev)
854 return bfi_image_ct_get_chunk(off);
855 return bfi_image_cb_get_chunk(off);
856}
857
858static u32
859bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc)
860{
861return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size;
862}
863
864/** 873/**
865 * Returns TRUE if same. 874 * Returns TRUE if same.
866 */ 875 */
867static bfa_boolean_t 876bfa_boolean_t
868bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) 877bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
869{ 878{
870 struct bfi_ioc_image_hdr_s *drv_fwhdr; 879 struct bfi_ioc_image_hdr_s *drv_fwhdr;
@@ -921,95 +930,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
921} 930}
922 931
923/** 932/**
924 * Return true if firmware of current driver matches the running firmware.
925 */
926static bfa_boolean_t
927bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc)
928{
929 enum bfi_ioc_state ioc_fwstate;
930 u32 usecnt;
931 struct bfi_ioc_image_hdr_s fwhdr;
932
933 /**
934 * Firmware match check is relevant only for CNA.
935 */
936 if (!ioc->cna)
937 return BFA_TRUE;
938
939 /**
940 * If bios boot (flash based) -- do not increment usage count
941 */
942 if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
943 return BFA_TRUE;
944
945 bfa_ioc_usage_sem_get(ioc);
946 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
947
948 /**
949 * If usage count is 0, always return TRUE.
950 */
951 if (usecnt == 0) {
952 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
953 bfa_ioc_usage_sem_release(ioc);
954 bfa_trc(ioc, usecnt);
955 return BFA_TRUE;
956 }
957
958 ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
959 bfa_trc(ioc, ioc_fwstate);
960
961 /**
962 * Use count cannot be non-zero and chip in uninitialized state.
963 */
964 bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
965
966 /**
967 * Check if another driver with a different firmware is active
968 */
969 bfa_ioc_fwver_get(ioc, &fwhdr);
970 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
971 bfa_ioc_usage_sem_release(ioc);
972 bfa_trc(ioc, usecnt);
973 return BFA_FALSE;
974 }
975
976 /**
977 * Same firmware version. Increment the reference count.
978 */
979 usecnt++;
980 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
981 bfa_ioc_usage_sem_release(ioc);
982 bfa_trc(ioc, usecnt);
983 return BFA_TRUE;
984}
985
986static void
987bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc)
988{
989 u32 usecnt;
990
991 /**
992 * Firmware lock is relevant only for CNA.
993 * If bios boot (flash based) -- do not decrement usage count
994 */
995 if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ))
996 return;
997
998 /**
999 * decrement usage count
1000 */
1001 bfa_ioc_usage_sem_get(ioc);
1002 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
1003 bfa_assert(usecnt > 0);
1004
1005 usecnt--;
1006 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
1007 bfa_trc(ioc, usecnt);
1008
1009 bfa_ioc_usage_sem_release(ioc);
1010}
1011
1012/**
1013 * Conditionally flush any pending message from firmware at start. 933 * Conditionally flush any pending message from firmware at start.
1014 */ 934 */
1015static void 935static void
@@ -1152,33 +1072,27 @@ bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
1152static void 1072static void
1153bfa_ioc_hb_check(void *cbarg) 1073bfa_ioc_hb_check(void *cbarg)
1154{ 1074{
1155 struct bfa_ioc_s *ioc = cbarg; 1075 struct bfa_ioc_s *ioc = cbarg;
1156 u32 hb_count; 1076 u32 hb_count;
1157 1077
1158 hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); 1078 hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
1159 if (ioc->hb_count == hb_count) { 1079 if (ioc->hb_count == hb_count) {
1160 ioc->hb_fail++; 1080 bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE,
1161 } else { 1081 hb_count);
1162 ioc->hb_count = hb_count;
1163 ioc->hb_fail = 0;
1164 }
1165
1166 if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) {
1167 bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count);
1168 ioc->hb_fail = 0;
1169 bfa_ioc_recover(ioc); 1082 bfa_ioc_recover(ioc);
1170 return; 1083 return;
1084 } else {
1085 ioc->hb_count = hb_count;
1171 } 1086 }
1172 1087
1173 bfa_ioc_mbox_poll(ioc); 1088 bfa_ioc_mbox_poll(ioc);
1174 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, 1089 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check,
1175 BFA_IOC_HB_TOV); 1090 ioc, BFA_IOC_HB_TOV);
1176} 1091}
1177 1092
1178static void 1093static void
1179bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc) 1094bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
1180{ 1095{
1181 ioc->hb_fail = 0;
1182 ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); 1096 ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
1183 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, 1097 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
1184 BFA_IOC_HB_TOV); 1098 BFA_IOC_HB_TOV);
@@ -1191,112 +1105,6 @@ bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
1191} 1105}
1192 1106
1193/** 1107/**
1194 * Host to LPU mailbox message addresses
1195 */
1196static struct {
1197 u32 hfn_mbox, lpu_mbox, hfn_pgn;
1198} iocreg_fnreg[] = {
1199 {
1200 HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, {
1201 HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, {
1202 HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, {
1203 HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3}
1204};
1205
1206/**
1207 * Host <-> LPU mailbox command/status registers - port 0
1208 */
1209static struct {
1210 u32 hfn, lpu;
1211} iocreg_mbcmd_p0[] = {
1212 {
1213 HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, {
1214 HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, {
1215 HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, {
1216 HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT}
1217};
1218
1219/**
1220 * Host <-> LPU mailbox command/status registers - port 1
1221 */
1222static struct {
1223 u32 hfn, lpu;
1224} iocreg_mbcmd_p1[] = {
1225 {
1226 HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, {
1227 HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, {
1228 HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, {
1229 HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT}
1230};
1231
1232/**
1233 * Shared IRQ handling in INTX mode
1234 */
1235static struct {
1236 u32 isr, msk;
1237} iocreg_shirq_next[] = {
1238 {
1239 HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, {
1240 HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, {
1241 HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, {
1242HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},};
1243
1244static void
1245bfa_ioc_reg_init(struct bfa_ioc_s *ioc)
1246{
1247 bfa_os_addr_t rb;
1248 int pcifn = bfa_ioc_pcifn(ioc);
1249
1250 rb = bfa_ioc_bar0(ioc);
1251
1252 ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
1253 ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
1254 ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
1255
1256 if (ioc->port_id == 0) {
1257 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
1258 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
1259 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
1260 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
1261 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
1262 } else {
1263 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
1264 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
1265 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
1266 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
1267 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
1268 }
1269
1270 /**
1271 * Shared IRQ handling in INTX mode
1272 */
1273 ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr;
1274 ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk;
1275
1276 /*
1277 * PSS control registers
1278 */
1279 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
1280 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
1281 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
1282
1283 /*
1284 * IOC semaphore registers and serialization
1285 */
1286 ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
1287 ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
1288 ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
1289
1290 /**
1291 * sram memory access
1292 */
1293 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
1294 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
1295 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT)
1296 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
1297}
1298
1299/**
1300 * Initiate a full firmware download. 1108 * Initiate a full firmware download.
1301 */ 1109 */
1302static void 1110static void
@@ -1321,9 +1129,6 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1321 if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) 1129 if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
1322 boot_type = BFI_BOOT_TYPE_FLASH; 1130 boot_type = BFI_BOOT_TYPE_FLASH;
1323 fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno); 1131 fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
1324 fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type);
1325 fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] =
1326 bfa_os_swap32(boot_param);
1327 1132
1328 pgnum = bfa_ioc_smem_pgnum(ioc, loff); 1133 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
1329 pgoff = bfa_ioc_smem_pgoff(ioc, loff); 1134 pgoff = bfa_ioc_smem_pgoff(ioc, loff);
@@ -1332,17 +1137,17 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1332 1137
1333 for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) { 1138 for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
1334 1139
1335 if (BFA_FLASH_CHUNK_NO(i) != chunkno) { 1140 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
1336 chunkno = BFA_FLASH_CHUNK_NO(i); 1141 chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
1337 fwimg = bfa_ioc_fwimg_get_chunk(ioc, 1142 fwimg = bfa_ioc_fwimg_get_chunk(ioc,
1338 BFA_FLASH_CHUNK_ADDR(chunkno)); 1143 BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1339 } 1144 }
1340 1145
1341 /** 1146 /**
1342 * write smem 1147 * write smem
1343 */ 1148 */
1344 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 1149 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
1345 fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]); 1150 fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
1346 1151
1347 loff += sizeof(u32); 1152 loff += sizeof(u32);
1348 1153
@@ -1358,6 +1163,14 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1358 1163
1359 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, 1164 bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
1360 bfa_ioc_smem_pgnum(ioc, 0)); 1165 bfa_ioc_smem_pgnum(ioc, 0));
1166
1167 /*
1168 * Set boot type and boot param at the end.
1169 */
1170 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF,
1171 bfa_os_swap32(boot_type));
1172 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_PARAM_OFF,
1173 bfa_os_swap32(boot_param));
1361} 1174}
1362 1175
1363static void 1176static void
@@ -1440,168 +1253,10 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
1440} 1253}
1441 1254
1442/** 1255/**
1443 * Initialize IOC to port mapping.
1444 */
1445
1446#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
1447static void
1448bfa_ioc_map_port(struct bfa_ioc_s *ioc)
1449{
1450 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1451 u32 r32;
1452
1453 /**
1454 * For crossbow, port id is same as pci function.
1455 */
1456 if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) {
1457 ioc->port_id = bfa_ioc_pcifn(ioc);
1458 return;
1459 }
1460
1461 /**
1462 * For catapult, base port id on personality register and IOC type
1463 */
1464 r32 = bfa_reg_read(rb + FNC_PERS_REG);
1465 r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
1466 ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
1467
1468 bfa_trc(ioc, bfa_ioc_pcifn(ioc));
1469 bfa_trc(ioc, ioc->port_id);
1470}
1471
1472
1473
1474/**
1475 * bfa_ioc_public 1256 * bfa_ioc_public
1476 */ 1257 */
1477 1258
1478/** 1259/**
1479* Set interrupt mode for a function: INTX or MSIX
1480 */
1481void
1482bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
1483{
1484 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1485 u32 r32, mode;
1486
1487 r32 = bfa_reg_read(rb + FNC_PERS_REG);
1488 bfa_trc(ioc, r32);
1489
1490 mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
1491 __F0_INTX_STATUS;
1492
1493 /**
1494 * If already in desired mode, do not change anything
1495 */
1496 if (!msix && mode)
1497 return;
1498
1499 if (msix)
1500 mode = __F0_INTX_STATUS_MSIX;
1501 else
1502 mode = __F0_INTX_STATUS_INTA;
1503
1504 r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
1505 r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
1506 bfa_trc(ioc, r32);
1507
1508 bfa_reg_write(rb + FNC_PERS_REG, r32);
1509}
1510
1511bfa_status_t
1512bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
1513{
1514 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1515 u32 pll_sclk, pll_fclk, r32;
1516
1517 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
1518 pll_sclk =
1519 __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
1520 __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
1521 __APP_PLL_312_JITLMT0_1(3U) |
1522 __APP_PLL_312_CNTLMT0_1(1U);
1523 pll_fclk =
1524 __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
1525 __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
1526 __APP_PLL_425_JITLMT0_1(3U) |
1527 __APP_PLL_425_CNTLMT0_1(1U);
1528
1529 /**
1530 * For catapult, choose operational mode FC/FCoE
1531 */
1532 if (ioc->fcmode) {
1533 bfa_reg_write((rb + OP_MODE), 0);
1534 bfa_reg_write((rb + ETH_MAC_SER_REG),
1535 __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2
1536 | __APP_EMS_CHANNEL_SEL);
1537 } else {
1538 ioc->pllinit = BFA_TRUE;
1539 bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
1540 bfa_reg_write((rb + ETH_MAC_SER_REG),
1541 __APP_EMS_REFCKBUFEN1);
1542 }
1543 } else {
1544 pll_sclk =
1545 __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
1546 __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) |
1547 __APP_PLL_312_CNTLMT0_1(3U);
1548 pll_fclk =
1549 __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
1550 __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
1551 __APP_PLL_425_JITLMT0_1(3U) |
1552 __APP_PLL_425_CNTLMT0_1(3U);
1553 }
1554
1555 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
1556 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
1557
1558 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
1559 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
1560 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
1561 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
1562 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
1563 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
1564
1565 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1566 __APP_PLL_312_LOGIC_SOFT_RESET);
1567 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1568 __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET);
1569 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1570 __APP_PLL_425_LOGIC_SOFT_RESET);
1571 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1572 __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET);
1573 bfa_os_udelay(2);
1574 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1575 __APP_PLL_312_LOGIC_SOFT_RESET);
1576 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1577 __APP_PLL_425_LOGIC_SOFT_RESET);
1578
1579 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1580 pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
1581 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1582 pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
1583
1584 /**
1585 * Wait for PLLs to lock.
1586 */
1587 bfa_os_udelay(2000);
1588 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
1589 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
1590
1591 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
1592 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
1593
1594 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
1595 bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
1596 bfa_os_udelay(1000);
1597 r32 = bfa_reg_read((rb + MBIST_STAT_REG));
1598 bfa_trc(ioc, r32);
1599 }
1600
1601 return BFA_STATUS_OK;
1602}
1603
1604/**
1605 * Interface used by diag module to do firmware boot with memory test 1260 * Interface used by diag module to do firmware boot with memory test
1606 * as the entry vector. 1261 * as the entry vector.
1607 */ 1262 */
@@ -1642,7 +1297,7 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param)
1642void 1297void
1643bfa_ioc_auto_recover(bfa_boolean_t auto_recover) 1298bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
1644{ 1299{
1645 bfa_auto_recover = BFA_FALSE; 1300 bfa_auto_recover = auto_recover;
1646} 1301}
1647 1302
1648 1303
@@ -1764,6 +1419,14 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
1764 ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT); 1419 ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
1765 ioc->cna = ioc->ctdev && !ioc->fcmode; 1420 ioc->cna = ioc->ctdev && !ioc->fcmode;
1766 1421
1422 /**
1423 * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
1424 */
1425 if (ioc->ctdev)
1426 bfa_ioc_set_ct_hwif(ioc);
1427 else
1428 bfa_ioc_set_cb_hwif(ioc);
1429
1767 bfa_ioc_map_port(ioc); 1430 bfa_ioc_map_port(ioc);
1768 bfa_ioc_reg_init(ioc); 1431 bfa_ioc_reg_init(ioc);
1769} 1432}
@@ -1830,7 +1493,6 @@ return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
1830void 1493void
1831bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave) 1494bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
1832{ 1495{
1833 bfa_assert(ioc->auto_recover);
1834 ioc->dbg_fwsave = dbg_fwsave; 1496 ioc->dbg_fwsave = dbg_fwsave;
1835 ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover); 1497 ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover);
1836} 1498}
@@ -1973,7 +1635,7 @@ bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
1973 ((__sm) == BFI_IOC_INITING) || \ 1635 ((__sm) == BFI_IOC_INITING) || \
1974 ((__sm) == BFI_IOC_HWINIT) || \ 1636 ((__sm) == BFI_IOC_HWINIT) || \
1975 ((__sm) == BFI_IOC_DISABLED) || \ 1637 ((__sm) == BFI_IOC_DISABLED) || \
1976 ((__sm) == BFI_IOC_HBFAIL) || \ 1638 ((__sm) == BFI_IOC_FAIL) || \
1977 ((__sm) == BFI_IOC_CFG_DISABLED)) 1639 ((__sm) == BFI_IOC_CFG_DISABLED))
1978 1640
1979/** 1641/**
@@ -2017,46 +1679,28 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2017 struct bfa_adapter_attr_s *ad_attr) 1679 struct bfa_adapter_attr_s *ad_attr)
2018{ 1680{
2019 struct bfi_ioc_attr_s *ioc_attr; 1681 struct bfi_ioc_attr_s *ioc_attr;
2020 char model[BFA_ADAPTER_MODEL_NAME_LEN];
2021 1682
2022 ioc_attr = ioc->attr; 1683 ioc_attr = ioc->attr;
2023 bfa_os_memcpy((void *)&ad_attr->serial_num, 1684
2024 (void *)ioc_attr->brcd_serialnum, 1685 bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
2025 BFA_ADAPTER_SERIAL_NUM_LEN); 1686 bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
2026 1687 bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
2027 bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN); 1688 bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
2028 bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version,
2029 BFA_VERSION_LEN);
2030 bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME,
2031 BFA_ADAPTER_MFG_NAME_LEN);
2032 bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd, 1689 bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd,
2033 sizeof(struct bfa_mfg_vpd_s)); 1690 sizeof(struct bfa_mfg_vpd_s));
2034 1691
2035 ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop); 1692 ad_attr->nports = bfa_ioc_get_nports(ioc);
2036 ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop); 1693 ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
2037 1694
2038 /** 1695 bfa_ioc_get_adapter_model(ioc, ad_attr->model);
2039 * model name 1696 /* For now, model descr uses same model string */
2040 */ 1697 bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
2041 if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) {
2042 strcpy(model, "BR-10?0");
2043 model[5] = '0' + ad_attr->nports;
2044 } else {
2045 strcpy(model, "Brocade-??5");
2046 model[8] =
2047 '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
2048 model[9] = '0' + ad_attr->nports;
2049 }
2050 1698
2051 if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) 1699 if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
2052 ad_attr->prototype = 1; 1700 ad_attr->prototype = 1;
2053 else 1701 else
2054 ad_attr->prototype = 0; 1702 ad_attr->prototype = 0;
2055 1703
2056 bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN);
2057 bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model,
2058 BFA_ADAPTER_MODEL_NAME_LEN);
2059
2060 ad_attr->pwwn = bfa_ioc_get_pwwn(ioc); 1704 ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
2061 ad_attr->mac = bfa_ioc_get_mac(ioc); 1705 ad_attr->mac = bfa_ioc_get_mac(ioc);
2062 1706
@@ -2064,41 +1708,122 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2064 ad_attr->pcie_lanes = ioc_attr->pcie_lanes; 1708 ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
2065 ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; 1709 ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
2066 ad_attr->asic_rev = ioc_attr->asic_rev; 1710 ad_attr->asic_rev = ioc_attr->asic_rev;
2067 ad_attr->hw_ver[0] = 'R'; 1711
2068 ad_attr->hw_ver[1] = 'e'; 1712 bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
2069 ad_attr->hw_ver[2] = 'v';
2070 ad_attr->hw_ver[3] = '-';
2071 ad_attr->hw_ver[4] = ioc_attr->asic_rev;
2072 ad_attr->hw_ver[5] = '\0';
2073 1713
2074 ad_attr->cna_capable = ioc->cna; 1714 ad_attr->cna_capable = ioc->cna;
2075} 1715}
2076 1716
1717enum bfa_ioc_type_e
1718bfa_ioc_get_type(struct bfa_ioc_s *ioc)
1719{
1720 if (!ioc->ctdev || ioc->fcmode)
1721 return BFA_IOC_TYPE_FC;
1722 else if (ioc->ioc_mc == BFI_MC_IOCFC)
1723 return BFA_IOC_TYPE_FCoE;
1724 else if (ioc->ioc_mc == BFI_MC_LL)
1725 return BFA_IOC_TYPE_LL;
1726 else {
1727 bfa_assert(ioc->ioc_mc == BFI_MC_LL);
1728 return BFA_IOC_TYPE_LL;
1729 }
1730}
1731
1732void
1733bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
1734{
1735 bfa_os_memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
1736 bfa_os_memcpy((void *)serial_num,
1737 (void *)ioc->attr->brcd_serialnum,
1738 BFA_ADAPTER_SERIAL_NUM_LEN);
1739}
1740
1741void
1742bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
1743{
1744 bfa_os_memset((void *)fw_ver, 0, BFA_VERSION_LEN);
1745 bfa_os_memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
1746}
1747
1748void
1749bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
1750{
1751 bfa_assert(chip_rev);
1752
1753 bfa_os_memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
1754
1755 chip_rev[0] = 'R';
1756 chip_rev[1] = 'e';
1757 chip_rev[2] = 'v';
1758 chip_rev[3] = '-';
1759 chip_rev[4] = ioc->attr->asic_rev;
1760 chip_rev[5] = '\0';
1761}
1762
1763void
1764bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver)
1765{
1766 bfa_os_memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
1767 bfa_os_memcpy(optrom_ver, ioc->attr->optrom_version,
1768 BFA_VERSION_LEN);
1769}
1770
1771void
1772bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
1773{
1774 bfa_os_memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
1775 bfa_os_memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
1776}
1777
1778void
1779bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
1780{
1781 struct bfi_ioc_attr_s *ioc_attr;
1782 u8 nports;
1783 u8 max_speed;
1784
1785 bfa_assert(model);
1786 bfa_os_memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
1787
1788 ioc_attr = ioc->attr;
1789
1790 nports = bfa_ioc_get_nports(ioc);
1791 max_speed = bfa_ioc_speed_sup(ioc);
1792
1793 /**
1794 * model name
1795 */
1796 if (max_speed == 10) {
1797 strcpy(model, "BR-10?0");
1798 model[5] = '0' + nports;
1799 } else {
1800 strcpy(model, "Brocade-??5");
1801 model[8] = '0' + max_speed;
1802 model[9] = '0' + nports;
1803 }
1804}
1805
1806enum bfa_ioc_state
1807bfa_ioc_get_state(struct bfa_ioc_s *ioc)
1808{
1809 return bfa_sm_to_state(ioc_sm_table, ioc->fsm);
1810}
1811
2077void 1812void
2078bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) 1813bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
2079{ 1814{
2080 bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s)); 1815 bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
2081 1816
2082 ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm); 1817 ioc_attr->state = bfa_ioc_get_state(ioc);
2083 ioc_attr->port_id = ioc->port_id; 1818 ioc_attr->port_id = ioc->port_id;
2084 1819
2085 if (!ioc->ctdev) 1820 ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
2086 ioc_attr->ioc_type = BFA_IOC_TYPE_FC;
2087 else if (ioc->ioc_mc == BFI_MC_IOCFC)
2088 ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE;
2089 else if (ioc->ioc_mc == BFI_MC_LL)
2090 ioc_attr->ioc_type = BFA_IOC_TYPE_LL;
2091 1821
2092 bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); 1822 bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
2093 1823
2094 ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; 1824 ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
2095 ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; 1825 ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
2096 ioc_attr->pci_attr.chip_rev[0] = 'R'; 1826 bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
2097 ioc_attr->pci_attr.chip_rev[1] = 'e';
2098 ioc_attr->pci_attr.chip_rev[2] = 'v';
2099 ioc_attr->pci_attr.chip_rev[3] = '-';
2100 ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev;
2101 ioc_attr->pci_attr.chip_rev[5] = '\0';
2102} 1827}
2103 1828
2104/** 1829/**
@@ -2195,29 +1920,6 @@ bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
2195} 1920}
2196 1921
2197/** 1922/**
2198 * Return true if interrupt should be claimed.
2199 */
2200bfa_boolean_t
2201bfa_ioc_intx_claim(struct bfa_ioc_s *ioc)
2202{
2203 u32 isr, msk;
2204
2205 /**
2206 * Always claim if not catapult.
2207 */
2208 if (!ioc->ctdev)
2209 return BFA_TRUE;
2210
2211 /**
2212 * FALSE if next device is claiming interrupt.
2213 * TRUE if next device is not interrupting or not present.
2214 */
2215 msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next);
2216 isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next);
2217 return !(isr & ~msk);
2218}
2219
2220/**
2221 * Send AEN notification 1923 * Send AEN notification
2222 */ 1924 */
2223static void 1925static void
@@ -2226,32 +1928,14 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2226 union bfa_aen_data_u aen_data; 1928 union bfa_aen_data_u aen_data;
2227 struct bfa_log_mod_s *logmod = ioc->logm; 1929 struct bfa_log_mod_s *logmod = ioc->logm;
2228 s32 inst_num = 0; 1930 s32 inst_num = 0;
2229 struct bfa_ioc_attr_s ioc_attr; 1931 enum bfa_ioc_type_e ioc_type;
2230 1932
2231 switch (event) { 1933 bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, event), inst_num);
2232 case BFA_IOC_AEN_HBGOOD:
2233 bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num);
2234 break;
2235 case BFA_IOC_AEN_HBFAIL:
2236 bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num);
2237 break;
2238 case BFA_IOC_AEN_ENABLE:
2239 bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num);
2240 break;
2241 case BFA_IOC_AEN_DISABLE:
2242 bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num);
2243 break;
2244 case BFA_IOC_AEN_FWMISMATCH:
2245 bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num);
2246 break;
2247 default:
2248 break;
2249 }
2250 1934
2251 memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn)); 1935 memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn));
2252 memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac)); 1936 memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac));
2253 bfa_ioc_get_attr(ioc, &ioc_attr); 1937 ioc_type = bfa_ioc_get_type(ioc);
2254 switch (ioc_attr.ioc_type) { 1938 switch (ioc_type) {
2255 case BFA_IOC_TYPE_FC: 1939 case BFA_IOC_TYPE_FC:
2256 aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc); 1940 aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
2257 break; 1941 break;
@@ -2263,10 +1947,10 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2263 aen_data.ioc.mac = bfa_ioc_get_mac(ioc); 1947 aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2264 break; 1948 break;
2265 default: 1949 default:
2266 bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC); 1950 bfa_assert(ioc_type == BFA_IOC_TYPE_FC);
2267 break; 1951 break;
2268 } 1952 }
2269 aen_data.ioc.ioc_type = ioc_attr.ioc_type; 1953 aen_data.ioc.ioc_type = ioc_type;
2270} 1954}
2271 1955
2272/** 1956/**
@@ -2290,6 +1974,15 @@ bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2290} 1974}
2291 1975
2292/** 1976/**
1977 * Clear saved firmware trace
1978 */
1979void
1980bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc)
1981{
1982 ioc->dbg_fwsave_once = BFA_TRUE;
1983}
1984
1985/**
2293 * Retrieve saved firmware trace from a prior IOC failure. 1986 * Retrieve saved firmware trace from a prior IOC failure.
2294 */ 1987 */
2295bfa_status_t 1988bfa_status_t
@@ -2304,6 +1997,13 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2304 1997
2305 pgnum = bfa_ioc_smem_pgnum(ioc, loff); 1998 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
2306 loff = bfa_ioc_smem_pgoff(ioc, loff); 1999 loff = bfa_ioc_smem_pgoff(ioc, loff);
2000
2001 /*
2002 * Hold semaphore to serialize pll init and fwtrc.
2003 */
2004 if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg))
2005 return BFA_STATUS_FAILED;
2006
2307 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum); 2007 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
2308 2008
2309 tlen = *trclen; 2009 tlen = *trclen;
@@ -2329,6 +2029,12 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2329 } 2029 }
2330 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, 2030 bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
2331 bfa_ioc_smem_pgnum(ioc, 0)); 2031 bfa_ioc_smem_pgnum(ioc, 0));
2032
2033 /*
2034 * release semaphore.
2035 */
2036 bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
2037
2332 bfa_trc(ioc, pgnum); 2038 bfa_trc(ioc, pgnum);
2333 2039
2334 *trclen = tlen * sizeof(u32); 2040 *trclen = tlen * sizeof(u32);
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index 7c30f05ab137..d0804406ea1a 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -74,15 +74,18 @@ struct bfa_ioc_regs_s {
74 bfa_os_addr_t lpu_mbox_cmd; 74 bfa_os_addr_t lpu_mbox_cmd;
75 bfa_os_addr_t lpu_mbox; 75 bfa_os_addr_t lpu_mbox;
76 bfa_os_addr_t pss_ctl_reg; 76 bfa_os_addr_t pss_ctl_reg;
77 bfa_os_addr_t pss_err_status_reg;
77 bfa_os_addr_t app_pll_fast_ctl_reg; 78 bfa_os_addr_t app_pll_fast_ctl_reg;
78 bfa_os_addr_t app_pll_slow_ctl_reg; 79 bfa_os_addr_t app_pll_slow_ctl_reg;
79 bfa_os_addr_t ioc_sem_reg; 80 bfa_os_addr_t ioc_sem_reg;
80 bfa_os_addr_t ioc_usage_sem_reg; 81 bfa_os_addr_t ioc_usage_sem_reg;
82 bfa_os_addr_t ioc_init_sem_reg;
81 bfa_os_addr_t ioc_usage_reg; 83 bfa_os_addr_t ioc_usage_reg;
82 bfa_os_addr_t host_page_num_fn; 84 bfa_os_addr_t host_page_num_fn;
83 bfa_os_addr_t heartbeat; 85 bfa_os_addr_t heartbeat;
84 bfa_os_addr_t ioc_fwstate; 86 bfa_os_addr_t ioc_fwstate;
85 bfa_os_addr_t ll_halt; 87 bfa_os_addr_t ll_halt;
88 bfa_os_addr_t err_set;
86 bfa_os_addr_t shirq_isr_next; 89 bfa_os_addr_t shirq_isr_next;
87 bfa_os_addr_t shirq_msk_next; 90 bfa_os_addr_t shirq_msk_next;
88 bfa_os_addr_t smem_page_start; 91 bfa_os_addr_t smem_page_start;
@@ -154,7 +157,6 @@ struct bfa_ioc_s {
154 struct bfa_timer_s ioc_timer; 157 struct bfa_timer_s ioc_timer;
155 struct bfa_timer_s sem_timer; 158 struct bfa_timer_s sem_timer;
156 u32 hb_count; 159 u32 hb_count;
157 u32 hb_fail;
158 u32 retry_count; 160 u32 retry_count;
159 struct list_head hb_notify_q; 161 struct list_head hb_notify_q;
160 void *dbg_fwsave; 162 void *dbg_fwsave;
@@ -177,6 +179,22 @@ struct bfa_ioc_s {
177 struct bfi_ioc_attr_s *attr; 179 struct bfi_ioc_attr_s *attr;
178 struct bfa_ioc_cbfn_s *cbfn; 180 struct bfa_ioc_cbfn_s *cbfn;
179 struct bfa_ioc_mbox_mod_s mbox_mod; 181 struct bfa_ioc_mbox_mod_s mbox_mod;
182 struct bfa_ioc_hwif_s *ioc_hwif;
183};
184
185struct bfa_ioc_hwif_s {
186 bfa_status_t (*ioc_pll_init) (struct bfa_ioc_s *ioc);
187 bfa_boolean_t (*ioc_firmware_lock) (struct bfa_ioc_s *ioc);
188 void (*ioc_firmware_unlock) (struct bfa_ioc_s *ioc);
189 u32 * (*ioc_fwimg_get_chunk) (struct bfa_ioc_s *ioc,
190 u32 off);
191 u32 (*ioc_fwimg_get_size) (struct bfa_ioc_s *ioc);
192 void (*ioc_reg_init) (struct bfa_ioc_s *ioc);
193 void (*ioc_map_port) (struct bfa_ioc_s *ioc);
194 void (*ioc_isr_mode_set) (struct bfa_ioc_s *ioc,
195 bfa_boolean_t msix);
196 void (*ioc_notify_hbfail) (struct bfa_ioc_s *ioc);
197 void (*ioc_ownership_reset) (struct bfa_ioc_s *ioc);
180}; 198};
181 199
182#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) 200#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
@@ -191,6 +209,15 @@ struct bfa_ioc_s {
191#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit) 209#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit)
192#define bfa_ioc_speed_sup(__ioc) \ 210#define bfa_ioc_speed_sup(__ioc) \
193 BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop) 211 BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
212#define bfa_ioc_get_nports(__ioc) \
213 BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
214
215#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
216#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
217
218#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
219#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
220#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
194 221
195/** 222/**
196 * IOC mailbox interface 223 * IOC mailbox interface
@@ -207,6 +234,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
207/** 234/**
208 * IOC interfaces 235 * IOC interfaces
209 */ 236 */
237#define bfa_ioc_pll_init(__ioc) ((__ioc)->ioc_hwif->ioc_pll_init(__ioc))
238#define bfa_ioc_isr_mode_set(__ioc, __msix) \
239 ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
240#define bfa_ioc_ownership_reset(__ioc) \
241 ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
242
243void bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc);
244void bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc);
210void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, 245void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
211 struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod, 246 struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod,
212 struct bfa_trc_mod_s *trcmod, 247 struct bfa_trc_mod_s *trcmod,
@@ -223,13 +258,21 @@ bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc);
223void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param); 258void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param);
224void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg); 259void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
225void bfa_ioc_error_isr(struct bfa_ioc_s *ioc); 260void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
226void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx);
227bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc);
228bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc); 261bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
229bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc); 262bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
230bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc); 263bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
231bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc); 264bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc);
232void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc); 265void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc);
266enum bfa_ioc_type_e bfa_ioc_get_type(struct bfa_ioc_s *ioc);
267void bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num);
268void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver);
269void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver);
270void bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model);
271void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc,
272 char *manufacturer);
273void bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev);
274enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc_s *ioc);
275
233void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr); 276void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr);
234void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, 277void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
235 struct bfa_adapter_attr_s *ad_attr); 278 struct bfa_adapter_attr_s *ad_attr);
@@ -237,6 +280,7 @@ int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover);
237void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave); 280void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave);
238bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, 281bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata,
239 int *trclen); 282 int *trclen);
283void bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc);
240bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, 284bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
241 int *trclen); 285 int *trclen);
242u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr); 286u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr);
@@ -245,6 +289,13 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc);
245bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc); 289bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
246void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc, 290void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
247 struct bfa_ioc_hbfail_notify_s *notify); 291 struct bfa_ioc_hbfail_notify_s *notify);
292bfa_boolean_t bfa_ioc_sem_get(bfa_os_addr_t sem_reg);
293void bfa_ioc_sem_release(bfa_os_addr_t sem_reg);
294void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
295void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
296 struct bfi_ioc_image_hdr_s *fwhdr);
297bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
298 struct bfi_ioc_image_hdr_s *fwhdr);
248 299
249/* 300/*
250 * bfa mfg wwn API functions 301 * bfa mfg wwn API functions
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c
new file mode 100644
index 000000000000..3ce85319f739
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioc_cb.c
@@ -0,0 +1,274 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_ioc.h>
20#include <bfa_fwimg_priv.h>
21#include <cna/bfa_cna_trcmod.h>
22#include <cs/bfa_debug.h>
23#include <bfi/bfi_ioc.h>
24#include <bfi/bfi_cbreg.h>
25#include <log/bfa_log_hal.h>
26#include <defs/bfa_defs_pci.h>
27
28BFA_TRC_FILE(CNA, IOC_CB);
29
30/*
31 * forward declarations
32 */
33static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc);
34static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc);
35static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
36static u32 *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off);
37static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc);
38static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
39static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
40static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
41static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc);
42static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
43
44struct bfa_ioc_hwif_s hwif_cb = {
45 bfa_ioc_cb_pll_init,
46 bfa_ioc_cb_firmware_lock,
47 bfa_ioc_cb_firmware_unlock,
48 bfa_ioc_cb_fwimg_get_chunk,
49 bfa_ioc_cb_fwimg_get_size,
50 bfa_ioc_cb_reg_init,
51 bfa_ioc_cb_map_port,
52 bfa_ioc_cb_isr_mode_set,
53 bfa_ioc_cb_notify_hbfail,
54 bfa_ioc_cb_ownership_reset,
55};
56
57/**
58 * Called from bfa_ioc_attach() to map asic specific calls.
59 */
60void
61bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
62{
63 ioc->ioc_hwif = &hwif_cb;
64}
65
66static u32 *
67bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
68{
69 return bfi_image_cb_get_chunk(off);
70}
71
72static u32
73bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc)
74{
75 return bfi_image_cb_size;
76}
77
78/**
79 * Return true if firmware of current driver matches the running firmware.
80 */
81static bfa_boolean_t
82bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
83{
84 return BFA_TRUE;
85}
86
87static void
88bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc)
89{
90}
91
92/**
93 * Notify other functions on HB failure.
94 */
95static void
96bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc)
97{
98 bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
99 bfa_reg_read(ioc->ioc_regs.err_set);
100}
101
102/**
103 * Host to LPU mailbox message addresses
104 */
105static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
106 { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
107 { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }
108};
109
110/**
111 * Host <-> LPU mailbox command/status registers
112 */
113static struct { u32 hfn, lpu; } iocreg_mbcmd[] = {
114 { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
115 { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT }
116};
117
118static void
119bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
120{
121 bfa_os_addr_t rb;
122 int pcifn = bfa_ioc_pcifn(ioc);
123
124 rb = bfa_ioc_bar0(ioc);
125
126 ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
127 ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
128 ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
129
130 if (ioc->port_id == 0) {
131 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
132 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
133 } else {
134 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
135 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
136 }
137
138 /**
139 * Host <-> LPU mailbox command/status registers
140 */
141 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn;
142 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu;
143
144 /*
145 * PSS control registers
146 */
147 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
148 ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
149 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG);
150 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG);
151
152 /*
153 * IOC semaphore registers and serialization
154 */
155 ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
156 ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
157
158 /**
159 * sram memory access
160 */
161 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
162 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
163
164 /*
165 * err set reg : for notification of hb failure
166 */
167 ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
168}
169
170/**
171 * Initialize IOC to port mapping.
172 */
173static void
174bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc)
175{
176 /**
177 * For crossbow, port id is same as pci function.
178 */
179 ioc->port_id = bfa_ioc_pcifn(ioc);
180 bfa_trc(ioc, ioc->port_id);
181}
182
183/**
184 * Set interrupt mode for a function: INTX or MSIX
185 */
186static void
187bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
188{
189}
190
191static bfa_status_t
192bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc)
193{
194 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
195 u32 pll_sclk, pll_fclk;
196
197 /*
198 * Hold semaphore so that nobody can access the chip during init.
199 */
200 bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
201
202 pll_sclk = __APP_PLL_212_ENABLE | __APP_PLL_212_LRESETN |
203 __APP_PLL_212_P0_1(3U) |
204 __APP_PLL_212_JITLMT0_1(3U) |
205 __APP_PLL_212_CNTLMT0_1(3U);
206 pll_fclk = __APP_PLL_400_ENABLE | __APP_PLL_400_LRESETN |
207 __APP_PLL_400_RSEL200500 | __APP_PLL_400_P0_1(3U) |
208 __APP_PLL_400_JITLMT0_1(3U) |
209 __APP_PLL_400_CNTLMT0_1(3U);
210
211 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
212 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
213
214 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
215 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
216 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
217 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
218 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
219 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
220
221 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
222 __APP_PLL_212_LOGIC_SOFT_RESET);
223 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
224 __APP_PLL_212_BYPASS |
225 __APP_PLL_212_LOGIC_SOFT_RESET);
226 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
227 __APP_PLL_400_LOGIC_SOFT_RESET);
228 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
229 __APP_PLL_400_BYPASS |
230 __APP_PLL_400_LOGIC_SOFT_RESET);
231 bfa_os_udelay(2);
232 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
233 __APP_PLL_212_LOGIC_SOFT_RESET);
234 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
235 __APP_PLL_400_LOGIC_SOFT_RESET);
236
237 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
238 pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET);
239 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
240 pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET);
241
242 /**
243 * Wait for PLLs to lock.
244 */
245 bfa_os_udelay(2000);
246 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
247 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
248
249 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
250 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
251
252 /*
253 * release semaphore.
254 */
255 bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
256
257 return BFA_STATUS_OK;
258}
259
260/**
261 * Cleanup hw semaphore and usecnt registers
262 */
263static void
264bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
265{
266
267 /*
268 * Read the hw sem reg to make sure that it is locked
269 * before we clear it. If it is not locked, writing 1
270 * will lock it instead of clearing it.
271 */
272 bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
273 bfa_ioc_hw_sem_release(ioc);
274}
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
new file mode 100644
index 000000000000..20b58ad5f95c
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioc_ct.c
@@ -0,0 +1,423 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_ioc.h>
20#include <bfa_fwimg_priv.h>
21#include <cna/bfa_cna_trcmod.h>
22#include <cs/bfa_debug.h>
23#include <bfi/bfi_ioc.h>
24#include <bfi/bfi_ctreg.h>
25#include <log/bfa_log_hal.h>
26#include <defs/bfa_defs_pci.h>
27
28BFA_TRC_FILE(CNA, IOC_CT);
29
30/*
31 * forward declarations
32 */
33static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc);
34static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
35static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
36static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
37 u32 off);
38static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc);
39static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
40static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
41static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
42static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
43static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
44
45struct bfa_ioc_hwif_s hwif_ct = {
46 bfa_ioc_ct_pll_init,
47 bfa_ioc_ct_firmware_lock,
48 bfa_ioc_ct_firmware_unlock,
49 bfa_ioc_ct_fwimg_get_chunk,
50 bfa_ioc_ct_fwimg_get_size,
51 bfa_ioc_ct_reg_init,
52 bfa_ioc_ct_map_port,
53 bfa_ioc_ct_isr_mode_set,
54 bfa_ioc_ct_notify_hbfail,
55 bfa_ioc_ct_ownership_reset,
56};
57
58/**
59 * Called from bfa_ioc_attach() to map asic specific calls.
60 */
61void
62bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
63{
64 ioc->ioc_hwif = &hwif_ct;
65}
66
67static u32*
68bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
69{
70 return bfi_image_ct_get_chunk(off);
71}
72
73static u32
74bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc)
75{
76 return bfi_image_ct_size;
77}
78
79/**
80 * Return true if firmware of current driver matches the running firmware.
81 */
82static bfa_boolean_t
83bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
84{
85 enum bfi_ioc_state ioc_fwstate;
86 u32 usecnt;
87 struct bfi_ioc_image_hdr_s fwhdr;
88
89 /**
90 * Firmware match check is relevant only for CNA.
91 */
92 if (!ioc->cna)
93 return BFA_TRUE;
94
95 /**
96 * If bios boot (flash based) -- do not increment usage count
97 */
98 if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
99 return BFA_TRUE;
100
101 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
102 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
103
104 /**
105 * If usage count is 0, always return TRUE.
106 */
107 if (usecnt == 0) {
108 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
109 bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
110 bfa_trc(ioc, usecnt);
111 return BFA_TRUE;
112 }
113
114 ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
115 bfa_trc(ioc, ioc_fwstate);
116
117 /**
118 * Use count cannot be non-zero and chip in uninitialized state.
119 */
120 bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
121
122 /**
123 * Check if another driver with a different firmware is active
124 */
125 bfa_ioc_fwver_get(ioc, &fwhdr);
126 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
127 bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
128 bfa_trc(ioc, usecnt);
129 return BFA_FALSE;
130 }
131
132 /**
133 * Same firmware version. Increment the reference count.
134 */
135 usecnt++;
136 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
137 bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
138 bfa_trc(ioc, usecnt);
139 return BFA_TRUE;
140}
141
142static void
143bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
144{
145 u32 usecnt;
146
147 /**
148 * Firmware lock is relevant only for CNA.
149 * If bios boot (flash based) -- do not decrement usage count
150 */
151 if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
152 return;
153
154 /**
155 * decrement usage count
156 */
157 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
158 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
159 bfa_assert(usecnt > 0);
160
161 usecnt--;
162 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
163 bfa_trc(ioc, usecnt);
164
165 bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
166}
167
168/**
169 * Notify other functions on HB failure.
170 */
171static void
172bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc)
173{
174 if (ioc->cna) {
175 bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
176 /* Wait for halt to take effect */
177 bfa_reg_read(ioc->ioc_regs.ll_halt);
178 } else {
179 bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
180 bfa_reg_read(ioc->ioc_regs.err_set);
181 }
182}
183
184/**
185 * Host to LPU mailbox message addresses
186 */
187static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
188 { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
189 { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
190 { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
191 { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
192};
193
194/**
195 * Host <-> LPU mailbox command/status registers - port 0
196 */
197static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
198 { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
199 { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
200 { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
201 { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
202};
203
204/**
205 * Host <-> LPU mailbox command/status registers - port 1
206 */
207static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
208 { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
209 { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
210 { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
211 { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
212};
213
214static void
215bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
216{
217 bfa_os_addr_t rb;
218 int pcifn = bfa_ioc_pcifn(ioc);
219
220 rb = bfa_ioc_bar0(ioc);
221
222 ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
223 ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
224 ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
225
226 if (ioc->port_id == 0) {
227 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
228 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
229 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
230 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
231 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
232 } else {
233 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
234 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
235 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
236 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
237 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
238 }
239
240 /*
241 * PSS control registers
242 */
243 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
244 ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
245 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
246 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
247
248 /*
249 * IOC semaphore registers and serialization
250 */
251 ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
252 ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
253 ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
254 ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
255
256 /**
257 * sram memory access
258 */
259 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
260 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
261
262 /*
263 * err set reg : for notification of hb failure in fcmode
264 */
265 ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
266}
267
268/**
269 * Initialize IOC to port mapping.
270 */
271
272#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
273static void
274bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
275{
276 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
277 u32 r32;
278
279 /**
280 * For catapult, base port id on personality register and IOC type
281 */
282 r32 = bfa_reg_read(rb + FNC_PERS_REG);
283 r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
284 ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
285
286 bfa_trc(ioc, bfa_ioc_pcifn(ioc));
287 bfa_trc(ioc, ioc->port_id);
288}
289
290/**
291 * Set interrupt mode for a function: INTX or MSIX
292 */
293static void
294bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
295{
296 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
297 u32 r32, mode;
298
299 r32 = bfa_reg_read(rb + FNC_PERS_REG);
300 bfa_trc(ioc, r32);
301
302 mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
303 __F0_INTX_STATUS;
304
305 /**
306 * If already in desired mode, do not change anything
307 */
308 if (!msix && mode)
309 return;
310
311 if (msix)
312 mode = __F0_INTX_STATUS_MSIX;
313 else
314 mode = __F0_INTX_STATUS_INTA;
315
316 r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
317 r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
318 bfa_trc(ioc, r32);
319
320 bfa_reg_write(rb + FNC_PERS_REG, r32);
321}
322
323static bfa_status_t
324bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
325{
326 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
327 u32 pll_sclk, pll_fclk, r32;
328
329 /*
330 * Hold semaphore so that nobody can access the chip during init.
331 */
332 bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
333
334 pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
335 __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
336 __APP_PLL_312_JITLMT0_1(3U) |
337 __APP_PLL_312_CNTLMT0_1(1U);
338 pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
339 __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
340 __APP_PLL_425_JITLMT0_1(3U) |
341 __APP_PLL_425_CNTLMT0_1(1U);
342
343 /**
344 * For catapult, choose operational mode FC/FCoE
345 */
346 if (ioc->fcmode) {
347 bfa_reg_write((rb + OP_MODE), 0);
348 bfa_reg_write((rb + ETH_MAC_SER_REG),
349 __APP_EMS_CMLCKSEL |
350 __APP_EMS_REFCKBUFEN2 |
351 __APP_EMS_CHANNEL_SEL);
352 } else {
353 ioc->pllinit = BFA_TRUE;
354 bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
355 bfa_reg_write((rb + ETH_MAC_SER_REG),
356 __APP_EMS_REFCKBUFEN1);
357 }
358
359 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
360 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
361
362 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
363 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
364 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
365 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
366 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
367 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
368
369 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
370 __APP_PLL_312_LOGIC_SOFT_RESET);
371 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
372 __APP_PLL_425_LOGIC_SOFT_RESET);
373 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
374 __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE);
375 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
376 __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE);
377
378 /**
379 * Wait for PLLs to lock.
380 */
381 bfa_reg_read(rb + HOSTFN0_INT_MSK);
382 bfa_os_udelay(2000);
383 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
384 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
385
386 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
387 __APP_PLL_312_ENABLE);
388 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
389 __APP_PLL_425_ENABLE);
390
391 bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
392 bfa_os_udelay(1000);
393 r32 = bfa_reg_read((rb + MBIST_STAT_REG));
394 bfa_trc(ioc, r32);
395 /*
396 * release semaphore.
397 */
398 bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
399
400 return BFA_STATUS_OK;
401}
402
403/**
404 * Cleanup hw semaphore and usecnt registers
405 */
406static void
407bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
408{
409
410 if (ioc->cna) {
411 bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
412 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0);
413 bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
414 }
415
416 /*
417 * Read the hw sem reg to make sure that it is locked
418 * before we clear it. If it is not locked, writing 1
419 * will lock it instead of clearing it.
420 */
421 bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
422 bfa_ioc_hw_sem_release(ioc);
423}
diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c
index d7ab792a9e54..a76de2669bfc 100644
--- a/drivers/scsi/bfa/bfa_iocfc.c
+++ b/drivers/scsi/bfa/bfa_iocfc.c
@@ -172,6 +172,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
172 */ 172 */
173 if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) { 173 if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
174 iocfc->hwif.hw_reginit = bfa_hwct_reginit; 174 iocfc->hwif.hw_reginit = bfa_hwct_reginit;
175 iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
175 iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack; 176 iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
176 iocfc->hwif.hw_msix_init = bfa_hwct_msix_init; 177 iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
177 iocfc->hwif.hw_msix_install = bfa_hwct_msix_install; 178 iocfc->hwif.hw_msix_install = bfa_hwct_msix_install;
@@ -180,6 +181,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
180 iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs; 181 iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
181 } else { 182 } else {
182 iocfc->hwif.hw_reginit = bfa_hwcb_reginit; 183 iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
184 iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
183 iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack; 185 iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
184 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; 186 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
185 iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install; 187 iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
@@ -336,8 +338,10 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
336 bfa_cb_init(bfa->bfad, BFA_STATUS_OK); 338 bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
337 else 339 else
338 bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED); 340 bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
339 } else 341 } else {
340 bfa->iocfc.action = BFA_IOCFC_ACT_NONE; 342 if (bfa->iocfc.cfgdone)
343 bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
344 }
341} 345}
342 346
343static void 347static void
@@ -619,8 +623,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
619 623
620 bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod, 624 bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod,
621 bfa->trcmod, bfa->aen, bfa->logm); 625 bfa->trcmod, bfa->aen, bfa->logm);
622 bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
623 bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
624 626
625 /** 627 /**
626 * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode. 628 * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
@@ -628,6 +630,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
628 if (0) 630 if (0)
629 bfa_ioc_set_fcmode(&bfa->ioc); 631 bfa_ioc_set_fcmode(&bfa->ioc);
630 632
633 bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
634 bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
635
631 bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev); 636 bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
632 bfa_iocfc_mem_claim(bfa, cfg, meminfo); 637 bfa_iocfc_mem_claim(bfa, cfg, meminfo);
633 bfa_timer_init(&bfa->timer_mod); 638 bfa_timer_init(&bfa->timer_mod);
@@ -654,7 +659,6 @@ bfa_iocfc_init(struct bfa_s *bfa)
654{ 659{
655 bfa->iocfc.action = BFA_IOCFC_ACT_INIT; 660 bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
656 bfa_ioc_enable(&bfa->ioc); 661 bfa_ioc_enable(&bfa->ioc);
657 bfa_msix_install(bfa);
658} 662}
659 663
660/** 664/**
@@ -797,6 +801,11 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats,
797 return BFA_STATUS_DEVBUSY; 801 return BFA_STATUS_DEVBUSY;
798 } 802 }
799 803
804 if (!bfa_iocfc_is_operational(bfa)) {
805 bfa_trc(bfa, 0);
806 return BFA_STATUS_IOC_NON_OP;
807 }
808
800 iocfc->stats_busy = BFA_TRUE; 809 iocfc->stats_busy = BFA_TRUE;
801 iocfc->stats_ret = stats; 810 iocfc->stats_ret = stats;
802 iocfc->stats_cbfn = cbfn; 811 iocfc->stats_cbfn = cbfn;
@@ -817,6 +826,11 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg)
817 return BFA_STATUS_DEVBUSY; 826 return BFA_STATUS_DEVBUSY;
818 } 827 }
819 828
829 if (!bfa_iocfc_is_operational(bfa)) {
830 bfa_trc(bfa, 0);
831 return BFA_STATUS_IOC_NON_OP;
832 }
833
820 iocfc->stats_busy = BFA_TRUE; 834 iocfc->stats_busy = BFA_TRUE;
821 iocfc->stats_cbfn = cbfn; 835 iocfc->stats_cbfn = cbfn;
822 iocfc->stats_cbarg = cbarg; 836 iocfc->stats_cbarg = cbarg;
diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h
index ce9a830a4207..fbb4bdc9d600 100644
--- a/drivers/scsi/bfa/bfa_iocfc.h
+++ b/drivers/scsi/bfa/bfa_iocfc.h
@@ -54,6 +54,7 @@ struct bfa_msix_s {
54 */ 54 */
55struct bfa_hwif_s { 55struct bfa_hwif_s {
56 void (*hw_reginit)(struct bfa_s *bfa); 56 void (*hw_reginit)(struct bfa_s *bfa);
57 void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
57 void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq); 58 void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
58 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs); 59 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
59 void (*hw_msix_install)(struct bfa_s *bfa); 60 void (*hw_msix_install)(struct bfa_s *bfa);
@@ -143,6 +144,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec);
143void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); 144void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
144 145
145void bfa_hwcb_reginit(struct bfa_s *bfa); 146void bfa_hwcb_reginit(struct bfa_s *bfa);
147void bfa_hwcb_reqq_ack(struct bfa_s *bfa, int rspq);
146void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); 148void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
147void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); 149void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
148void bfa_hwcb_msix_install(struct bfa_s *bfa); 150void bfa_hwcb_msix_install(struct bfa_s *bfa);
@@ -151,6 +153,7 @@ void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
151void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, 153void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
152 u32 *nvecs, u32 *maxvec); 154 u32 *nvecs, u32 *maxvec);
153void bfa_hwct_reginit(struct bfa_s *bfa); 155void bfa_hwct_reginit(struct bfa_s *bfa);
156void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
154void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); 157void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
155void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); 158void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
156void bfa_hwct_msix_install(struct bfa_s *bfa); 159void bfa_hwct_msix_install(struct bfa_s *bfa);
diff --git a/drivers/scsi/bfa/bfa_ioim.c b/drivers/scsi/bfa/bfa_ioim.c
index f81d359b7089..5b107abe46e5 100644
--- a/drivers/scsi/bfa/bfa_ioim.c
+++ b/drivers/scsi/bfa/bfa_ioim.c
@@ -149,7 +149,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
149 break; 149 break;
150 150
151 default: 151 default:
152 bfa_assert(0); 152 bfa_sm_fault(ioim->bfa, event);
153 } 153 }
154} 154}
155 155
@@ -194,7 +194,7 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
194 break; 194 break;
195 195
196 default: 196 default:
197 bfa_assert(0); 197 bfa_sm_fault(ioim->bfa, event);
198 } 198 }
199} 199}
200 200
@@ -259,7 +259,7 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
259 break; 259 break;
260 260
261 default: 261 default:
262 bfa_assert(0); 262 bfa_sm_fault(ioim->bfa, event);
263 } 263 }
264} 264}
265 265
@@ -317,7 +317,7 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
317 break; 317 break;
318 318
319 default: 319 default:
320 bfa_assert(0); 320 bfa_sm_fault(ioim->bfa, event);
321 } 321 }
322} 322}
323 323
@@ -377,7 +377,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
377 break; 377 break;
378 378
379 default: 379 default:
380 bfa_assert(0); 380 bfa_sm_fault(ioim->bfa, event);
381 } 381 }
382} 382}
383 383
@@ -419,7 +419,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
419 break; 419 break;
420 420
421 default: 421 default:
422 bfa_assert(0); 422 bfa_sm_fault(ioim->bfa, event);
423 } 423 }
424} 424}
425 425
@@ -467,7 +467,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
467 break; 467 break;
468 468
469 default: 469 default:
470 bfa_assert(0); 470 bfa_sm_fault(ioim->bfa, event);
471 } 471 }
472} 472}
473 473
@@ -516,7 +516,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
516 break; 516 break;
517 517
518 default: 518 default:
519 bfa_assert(0); 519 bfa_sm_fault(ioim->bfa, event);
520 } 520 }
521} 521}
522 522
@@ -544,7 +544,7 @@ bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
544 break; 544 break;
545 545
546 default: 546 default:
547 bfa_assert(0); 547 bfa_sm_fault(ioim->bfa, event);
548 } 548 }
549} 549}
550 550
@@ -577,7 +577,7 @@ bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
577 break; 577 break;
578 578
579 default: 579 default:
580 bfa_assert(0); 580 bfa_sm_fault(ioim->bfa, event);
581 } 581 }
582} 582}
583 583
@@ -605,7 +605,7 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
605 break; 605 break;
606 606
607 default: 607 default:
608 bfa_assert(0); 608 bfa_sm_fault(ioim->bfa, event);
609 } 609 }
610} 610}
611 611
diff --git a/drivers/scsi/bfa/bfa_itnim.c b/drivers/scsi/bfa/bfa_itnim.c
index eabf7d38bd09..a914ff255135 100644
--- a/drivers/scsi/bfa/bfa_itnim.c
+++ b/drivers/scsi/bfa/bfa_itnim.c
@@ -144,7 +144,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
144 break; 144 break;
145 145
146 default: 146 default:
147 bfa_assert(0); 147 bfa_sm_fault(itnim->bfa, event);
148 } 148 }
149} 149}
150 150
@@ -175,7 +175,7 @@ bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
175 break; 175 break;
176 176
177 default: 177 default:
178 bfa_assert(0); 178 bfa_sm_fault(itnim->bfa, event);
179 } 179 }
180} 180}
181 181
@@ -212,7 +212,7 @@ bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
212 break; 212 break;
213 213
214 default: 214 default:
215 bfa_assert(0); 215 bfa_sm_fault(itnim->bfa, event);
216 } 216 }
217} 217}
218 218
@@ -247,7 +247,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
247 break; 247 break;
248 248
249 default: 249 default:
250 bfa_assert(0); 250 bfa_sm_fault(itnim->bfa, event);
251 } 251 }
252} 252}
253 253
@@ -275,7 +275,7 @@ bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
275 break; 275 break;
276 276
277 default: 277 default:
278 bfa_assert(0); 278 bfa_sm_fault(itnim->bfa, event);
279 } 279 }
280} 280}
281 281
@@ -317,7 +317,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
317 break; 317 break;
318 318
319 default: 319 default:
320 bfa_assert(0); 320 bfa_sm_fault(itnim->bfa, event);
321 } 321 }
322} 322}
323 323
@@ -348,7 +348,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
348 break; 348 break;
349 349
350 default: 350 default:
351 bfa_assert(0); 351 bfa_sm_fault(itnim->bfa, event);
352 } 352 }
353} 353}
354 354
@@ -385,7 +385,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
385 break; 385 break;
386 386
387 default: 387 default:
388 bfa_assert(0); 388 bfa_sm_fault(itnim->bfa, event);
389 } 389 }
390} 390}
391 391
@@ -413,7 +413,7 @@ bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
413 break; 413 break;
414 414
415 default: 415 default:
416 bfa_assert(0); 416 bfa_sm_fault(itnim->bfa, event);
417 } 417 }
418} 418}
419 419
@@ -442,7 +442,7 @@ bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
442 break; 442 break;
443 443
444 default: 444 default:
445 bfa_assert(0); 445 bfa_sm_fault(itnim->bfa, event);
446 } 446 }
447} 447}
448 448
@@ -470,7 +470,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
470 break; 470 break;
471 471
472 default: 472 default:
473 bfa_assert(0); 473 bfa_sm_fault(itnim->bfa, event);
474 } 474 }
475} 475}
476 476
@@ -502,7 +502,7 @@ bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
502 break; 502 break;
503 503
504 default: 504 default:
505 bfa_assert(0); 505 bfa_sm_fault(itnim->bfa, event);
506 } 506 }
507} 507}
508 508
@@ -538,7 +538,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
538 break; 538 break;
539 539
540 default: 540 default:
541 bfa_assert(0); 541 bfa_sm_fault(itnim->bfa, event);
542 } 542 }
543} 543}
544 544
@@ -559,7 +559,7 @@ bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
559 break; 559 break;
560 560
561 default: 561 default:
562 bfa_assert(0); 562 bfa_sm_fault(itnim->bfa, event);
563 } 563 }
564} 564}
565 565
@@ -583,7 +583,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
583 break; 583 break;
584 584
585 default: 585 default:
586 bfa_assert(0); 586 bfa_sm_fault(itnim->bfa, event);
587 } 587 }
588} 588}
589 589
diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c
index 9844b45412b6..ad06f6189092 100644
--- a/drivers/scsi/bfa/bfa_lps.c
+++ b/drivers/scsi/bfa/bfa_lps.c
@@ -18,6 +18,7 @@
18#include <bfa.h> 18#include <bfa.h>
19#include <bfi/bfi_lps.h> 19#include <bfi/bfi_lps.h>
20#include <cs/bfa_debug.h> 20#include <cs/bfa_debug.h>
21#include <defs/bfa_defs_pci.h>
21 22
22BFA_TRC_FILE(HAL, LPS); 23BFA_TRC_FILE(HAL, LPS);
23BFA_MODULE(lps); 24BFA_MODULE(lps);
@@ -25,6 +26,12 @@ BFA_MODULE(lps);
25#define BFA_LPS_MIN_LPORTS (1) 26#define BFA_LPS_MIN_LPORTS (1)
26#define BFA_LPS_MAX_LPORTS (256) 27#define BFA_LPS_MAX_LPORTS (256)
27 28
29/*
30 * Maximum Vports supported per physical port or vf.
31 */
32#define BFA_LPS_MAX_VPORTS_SUPP_CB 255
33#define BFA_LPS_MAX_VPORTS_SUPP_CT 190
34
28/** 35/**
29 * forward declarations 36 * forward declarations
30 */ 37 */
@@ -49,7 +56,7 @@ static void bfa_lps_send_login(struct bfa_lps_s *lps);
49static void bfa_lps_send_logout(struct bfa_lps_s *lps); 56static void bfa_lps_send_logout(struct bfa_lps_s *lps);
50static void bfa_lps_login_comp(struct bfa_lps_s *lps); 57static void bfa_lps_login_comp(struct bfa_lps_s *lps);
51static void bfa_lps_logout_comp(struct bfa_lps_s *lps); 58static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
52 59static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
53 60
54/** 61/**
55 * lps_pvt BFA LPS private functions 62 * lps_pvt BFA LPS private functions
@@ -62,6 +69,7 @@ enum bfa_lps_event {
62 BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */ 69 BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */
63 BFA_LPS_SM_DELETE = 5, /* lps delete from user */ 70 BFA_LPS_SM_DELETE = 5, /* lps delete from user */
64 BFA_LPS_SM_OFFLINE = 6, /* Link is offline */ 71 BFA_LPS_SM_OFFLINE = 6, /* Link is offline */
72 BFA_LPS_SM_RX_CVL = 7, /* Rx clear virtual link */
65}; 73};
66 74
67static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); 75static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
@@ -91,6 +99,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
91 bfa_sm_set_state(lps, bfa_lps_sm_login); 99 bfa_sm_set_state(lps, bfa_lps_sm_login);
92 bfa_lps_send_login(lps); 100 bfa_lps_send_login(lps);
93 } 101 }
102 if (lps->fdisc)
103 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
104 BFA_PL_EID_LOGIN, 0, "FDISC Request");
105 else
106 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
107 BFA_PL_EID_LOGIN, 0, "FLOGI Request");
94 break; 108 break;
95 109
96 case BFA_LPS_SM_LOGOUT: 110 case BFA_LPS_SM_LOGOUT:
@@ -101,6 +115,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
101 bfa_lps_free(lps); 115 bfa_lps_free(lps);
102 break; 116 break;
103 117
118 case BFA_LPS_SM_RX_CVL:
104 case BFA_LPS_SM_OFFLINE: 119 case BFA_LPS_SM_OFFLINE:
105 break; 120 break;
106 121
@@ -112,7 +127,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
112 break; 127 break;
113 128
114 default: 129 default:
115 bfa_assert(0); 130 bfa_sm_fault(lps->bfa, event);
116 } 131 }
117} 132}
118 133
@@ -127,10 +142,25 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
127 142
128 switch (event) { 143 switch (event) {
129 case BFA_LPS_SM_FWRSP: 144 case BFA_LPS_SM_FWRSP:
130 if (lps->status == BFA_STATUS_OK) 145 if (lps->status == BFA_STATUS_OK) {
131 bfa_sm_set_state(lps, bfa_lps_sm_online); 146 bfa_sm_set_state(lps, bfa_lps_sm_online);
132 else 147 if (lps->fdisc)
148 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
149 BFA_PL_EID_LOGIN, 0, "FDISC Accept");
150 else
151 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
152 BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
153 } else {
133 bfa_sm_set_state(lps, bfa_lps_sm_init); 154 bfa_sm_set_state(lps, bfa_lps_sm_init);
155 if (lps->fdisc)
156 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
157 BFA_PL_EID_LOGIN, 0,
158 "FDISC Fail (RJT or timeout)");
159 else
160 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
161 BFA_PL_EID_LOGIN, 0,
162 "FLOGI Fail (RJT or timeout)");
163 }
134 bfa_lps_login_comp(lps); 164 bfa_lps_login_comp(lps);
135 break; 165 break;
136 166
@@ -139,7 +169,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
139 break; 169 break;
140 170
141 default: 171 default:
142 bfa_assert(0); 172 bfa_sm_fault(lps->bfa, event);
143 } 173 }
144} 174}
145 175
@@ -162,8 +192,16 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
162 bfa_reqq_wcancel(&lps->wqe); 192 bfa_reqq_wcancel(&lps->wqe);
163 break; 193 break;
164 194
195 case BFA_LPS_SM_RX_CVL:
196 /*
197 * Login was not even sent out; so when getting out
198 * of this state, it will appear like a login retry
199 * after Clear virtual link
200 */
201 break;
202
165 default: 203 default:
166 bfa_assert(0); 204 bfa_sm_fault(lps->bfa, event);
167 } 205 }
168} 206}
169 207
@@ -185,6 +223,17 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
185 bfa_sm_set_state(lps, bfa_lps_sm_logout); 223 bfa_sm_set_state(lps, bfa_lps_sm_logout);
186 bfa_lps_send_logout(lps); 224 bfa_lps_send_logout(lps);
187 } 225 }
226 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
227 BFA_PL_EID_LOGO, 0, "Logout");
228 break;
229
230 case BFA_LPS_SM_RX_CVL:
231 bfa_sm_set_state(lps, bfa_lps_sm_init);
232
233 /* Let the vport module know about this event */
234 bfa_lps_cvl_event(lps);
235 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
236 BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
188 break; 237 break;
189 238
190 case BFA_LPS_SM_OFFLINE: 239 case BFA_LPS_SM_OFFLINE:
@@ -193,7 +242,7 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
193 break; 242 break;
194 243
195 default: 244 default:
196 bfa_assert(0); 245 bfa_sm_fault(lps->bfa, event);
197 } 246 }
198} 247}
199 248
@@ -217,7 +266,7 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
217 break; 266 break;
218 267
219 default: 268 default:
220 bfa_assert(0); 269 bfa_sm_fault(lps->bfa, event);
221 } 270 }
222} 271}
223 272
@@ -242,7 +291,7 @@ bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
242 break; 291 break;
243 292
244 default: 293 default:
245 bfa_assert(0); 294 bfa_sm_fault(lps->bfa, event);
246 } 295 }
247} 296}
248 297
@@ -396,6 +445,20 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
396} 445}
397 446
398/** 447/**
448 * Firmware received a Clear virtual link request (for FCoE)
449 */
450static void
451bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl)
452{
453 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
454 struct bfa_lps_s *lps;
455
456 lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag);
457
458 bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL);
459}
460
461/**
399 * Space is available in request queue, resume queueing request to firmware. 462 * Space is available in request queue, resume queueing request to firmware.
400 */ 463 */
401static void 464static void
@@ -531,7 +594,48 @@ bfa_lps_logout_comp(struct bfa_lps_s *lps)
531 bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); 594 bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
532} 595}
533 596
597/**
598 * Clear virtual link completion handler for non-fcs
599 */
600static void
601bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete)
602{
603 struct bfa_lps_s *lps = arg;
604
605 if (!complete)
606 return;
607
608 /* Clear virtual link to base port will result in link down */
609 if (lps->fdisc)
610 bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
611}
612
613/**
614 * Received Clear virtual link event --direct call for fcs,
615 * queue for others
616 */
617static void
618bfa_lps_cvl_event(struct bfa_lps_s *lps)
619{
620 if (!lps->bfa->fcs) {
621 bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb,
622 lps);
623 return;
624 }
625
626 /* Clear virtual link to base port will result in link down */
627 if (lps->fdisc)
628 bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
629}
534 630
631u32
632bfa_lps_get_max_vport(struct bfa_s *bfa)
633{
634 if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT)
635 return BFA_LPS_MAX_VPORTS_SUPP_CT;
636 else
637 return BFA_LPS_MAX_VPORTS_SUPP_CB;
638}
535 639
536/** 640/**
537 * lps_public BFA LPS public functions 641 * lps_public BFA LPS public functions
@@ -752,6 +856,14 @@ bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
752 return lps->lsrjt_expl; 856 return lps->lsrjt_expl;
753} 857}
754 858
859/**
860 * Return fpma/spma MAC for lport
861 */
862struct mac_s
863bfa_lps_get_lp_mac(struct bfa_lps_s *lps)
864{
865 return lps->lp_mac;
866}
755 867
756/** 868/**
757 * LPS firmware message class handler. 869 * LPS firmware message class handler.
@@ -773,6 +885,10 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
773 bfa_lps_logout_rsp(bfa, msg.logout_rsp); 885 bfa_lps_logout_rsp(bfa, msg.logout_rsp);
774 break; 886 break;
775 887
888 case BFI_LPS_H2I_CVL_EVENT:
889 bfa_lps_rx_cvl_event(bfa, msg.cvl_event);
890 break;
891
776 default: 892 default:
777 bfa_trc(bfa, m->mhdr.msg_id); 893 bfa_trc(bfa, m->mhdr.msg_id);
778 bfa_assert(0); 894 bfa_assert(0);
diff --git a/drivers/scsi/bfa/bfa_module.c b/drivers/scsi/bfa/bfa_module.c
index 32eda8e1ec65..a7fcc80c177e 100644
--- a/drivers/scsi/bfa/bfa_module.c
+++ b/drivers/scsi/bfa/bfa_module.c
@@ -24,7 +24,7 @@
24 */ 24 */
25struct bfa_module_s *hal_mods[] = { 25struct bfa_module_s *hal_mods[] = {
26 &hal_mod_sgpg, 26 &hal_mod_sgpg,
27 &hal_mod_pport, 27 &hal_mod_fcport,
28 &hal_mod_fcxp, 28 &hal_mod_fcxp,
29 &hal_mod_lps, 29 &hal_mod_lps,
30 &hal_mod_uf, 30 &hal_mod_uf,
@@ -45,7 +45,7 @@ bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = {
45 bfa_isr_unhandled, /* BFI_MC_DIAG */ 45 bfa_isr_unhandled, /* BFI_MC_DIAG */
46 bfa_isr_unhandled, /* BFI_MC_FLASH */ 46 bfa_isr_unhandled, /* BFI_MC_FLASH */
47 bfa_isr_unhandled, /* BFI_MC_CEE */ 47 bfa_isr_unhandled, /* BFI_MC_CEE */
48 bfa_pport_isr, /* BFI_MC_PORT */ 48 bfa_fcport_isr, /* BFI_MC_FCPORT */
49 bfa_isr_unhandled, /* BFI_MC_IOCFC */ 49 bfa_isr_unhandled, /* BFI_MC_IOCFC */
50 bfa_isr_unhandled, /* BFI_MC_LL */ 50 bfa_isr_unhandled, /* BFI_MC_LL */
51 bfa_uf_isr, /* BFI_MC_UF */ 51 bfa_uf_isr, /* BFI_MC_UF */
diff --git a/drivers/scsi/bfa/bfa_modules_priv.h b/drivers/scsi/bfa/bfa_modules_priv.h
index 96f70534593c..f554c2fad6a9 100644
--- a/drivers/scsi/bfa/bfa_modules_priv.h
+++ b/drivers/scsi/bfa/bfa_modules_priv.h
@@ -29,7 +29,7 @@
29 29
30 30
31struct bfa_modules_s { 31struct bfa_modules_s {
32 struct bfa_pport_s pport; /* physical port module */ 32 struct bfa_fcport_s fcport; /* fc port module */
33 struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */ 33 struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */
34 struct bfa_lps_mod_s lps_mod; /* fcxp module */ 34 struct bfa_lps_mod_s lps_mod; /* fcxp module */
35 struct bfa_uf_mod_s uf_mod; /* unsolicited frame module */ 35 struct bfa_uf_mod_s uf_mod; /* unsolicited frame module */
diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h
index 51f698a06b6d..40e256ec67ff 100644
--- a/drivers/scsi/bfa/bfa_port_priv.h
+++ b/drivers/scsi/bfa/bfa_port_priv.h
@@ -23,9 +23,19 @@
23#include "bfa_intr_priv.h" 23#include "bfa_intr_priv.h"
24 24
25/** 25/**
26 * BFA physical port data structure 26 * Link notification data structure
27 */ 27 */
28struct bfa_pport_s { 28struct bfa_fcport_ln_s {
29 struct bfa_fcport_s *fcport;
30 bfa_sm_t sm;
31 struct bfa_cb_qe_s ln_qe; /* BFA callback queue elem for ln */
32 enum bfa_pport_linkstate ln_event; /* ln event for callback */
33};
34
35/**
36 * BFA FC port data structure
37 */
38struct bfa_fcport_s {
29 struct bfa_s *bfa; /* parent BFA instance */ 39 struct bfa_s *bfa; /* parent BFA instance */
30 bfa_sm_t sm; /* port state machine */ 40 bfa_sm_t sm; /* port state machine */
31 wwn_t nwwn; /* node wwn of physical port */ 41 wwn_t nwwn; /* node wwn of physical port */
@@ -36,6 +46,8 @@ struct bfa_pport_s {
36 enum bfa_pport_topology topology; /* current topology */ 46 enum bfa_pport_topology topology; /* current topology */
37 u8 myalpa; /* my ALPA in LOOP topology */ 47 u8 myalpa; /* my ALPA in LOOP topology */
38 u8 rsvd[3]; 48 u8 rsvd[3];
49 u32 mypid:24;
50 u32 rsvd_b:8;
39 struct bfa_pport_cfg_s cfg; /* current port configuration */ 51 struct bfa_pport_cfg_s cfg; /* current port configuration */
40 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ 52 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
41 struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */ 53 struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
@@ -49,42 +61,31 @@ struct bfa_pport_s {
49 void (*event_cbfn) (void *cbarg, 61 void (*event_cbfn) (void *cbarg,
50 bfa_pport_event_t event); 62 bfa_pport_event_t event);
51 union { 63 union {
52 union bfi_pport_i2h_msg_u i2hmsg; 64 union bfi_fcport_i2h_msg_u i2hmsg;
53 } event_arg; 65 } event_arg;
54 void *bfad; /* BFA driver handle */ 66 void *bfad; /* BFA driver handle */
67 struct bfa_fcport_ln_s ln; /* Link Notification */
55 struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */ 68 struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */
56 enum bfa_pport_linkstate hcb_event; 69 struct bfa_timer_s timer; /* timer */
57 /* link event for callback */
58 u32 msgtag; /* fimrware msg tag for reply */ 70 u32 msgtag; /* fimrware msg tag for reply */
59 u8 *stats_kva; 71 u8 *stats_kva;
60 u64 stats_pa; 72 u64 stats_pa;
61 union bfa_pport_stats_u *stats; /* pport stats */ 73 union bfa_fcport_stats_u *stats;
62 u32 mypid:24; 74 union bfa_fcport_stats_u *stats_ret; /* driver stats location */
63 u32 rsvd_b:8; 75 bfa_status_t stats_status; /* stats/statsclr status */
64 struct bfa_timer_s timer; /* timer */ 76 bfa_boolean_t stats_busy; /* outstanding stats/statsclr */
65 union bfa_pport_stats_u *stats_ret; 77 bfa_boolean_t stats_qfull;
66 /* driver stats location */ 78 bfa_cb_pport_t stats_cbfn; /* driver callback function */
67 bfa_status_t stats_status; 79 void *stats_cbarg; /* *!< user callback arg */
68 /* stats/statsclr status */ 80 bfa_boolean_t diag_busy; /* diag busy status */
69 bfa_boolean_t stats_busy; 81 bfa_boolean_t beacon; /* port beacon status */
70 /* outstanding stats/statsclr */ 82 bfa_boolean_t link_e2e_beacon; /* link beacon status */
71 bfa_boolean_t stats_qfull;
72 bfa_boolean_t diag_busy;
73 /* diag busy status */
74 bfa_boolean_t beacon;
75 /* port beacon status */
76 bfa_boolean_t link_e2e_beacon;
77 /* link beacon status */
78 bfa_cb_pport_t stats_cbfn;
79 /* driver callback function */
80 void *stats_cbarg;
81 /* *!< user callback arg */
82}; 83};
83 84
84#define BFA_PORT_MOD(__bfa) (&(__bfa)->modules.pport) 85#define BFA_FCPORT_MOD(__bfa) (&(__bfa)->modules.fcport)
85 86
86/* 87/*
87 * public functions 88 * public functions
88 */ 89 */
89void bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); 90void bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
90#endif /* __BFA_PORT_PRIV_H__ */ 91#endif /* __BFA_PORT_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_priv.h b/drivers/scsi/bfa/bfa_priv.h
index 0747a6b26f7b..be80fc7e1b0e 100644
--- a/drivers/scsi/bfa/bfa_priv.h
+++ b/drivers/scsi/bfa/bfa_priv.h
@@ -101,7 +101,7 @@ extern bfa_boolean_t bfa_auto_recover;
101extern struct bfa_module_s hal_mod_flash; 101extern struct bfa_module_s hal_mod_flash;
102extern struct bfa_module_s hal_mod_fcdiag; 102extern struct bfa_module_s hal_mod_fcdiag;
103extern struct bfa_module_s hal_mod_sgpg; 103extern struct bfa_module_s hal_mod_sgpg;
104extern struct bfa_module_s hal_mod_pport; 104extern struct bfa_module_s hal_mod_fcport;
105extern struct bfa_module_s hal_mod_fcxp; 105extern struct bfa_module_s hal_mod_fcxp;
106extern struct bfa_module_s hal_mod_lps; 106extern struct bfa_module_s hal_mod_lps;
107extern struct bfa_module_s hal_mod_uf; 107extern struct bfa_module_s hal_mod_uf;
diff --git a/drivers/scsi/bfa/bfa_rport.c b/drivers/scsi/bfa/bfa_rport.c
index 3e1990a74258..7c509fa244e4 100644
--- a/drivers/scsi/bfa/bfa_rport.c
+++ b/drivers/scsi/bfa/bfa_rport.c
@@ -114,7 +114,7 @@ bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event)
114 114
115 default: 115 default:
116 bfa_stats(rp, sm_un_unexp); 116 bfa_stats(rp, sm_un_unexp);
117 bfa_assert(0); 117 bfa_sm_fault(rp->bfa, event);
118 } 118 }
119} 119}
120 120
@@ -146,7 +146,7 @@ bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
146 146
147 default: 147 default:
148 bfa_stats(rp, sm_cr_unexp); 148 bfa_stats(rp, sm_cr_unexp);
149 bfa_assert(0); 149 bfa_sm_fault(rp->bfa, event);
150 } 150 }
151} 151}
152 152
@@ -183,7 +183,7 @@ bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
183 183
184 default: 184 default:
185 bfa_stats(rp, sm_fwc_unexp); 185 bfa_stats(rp, sm_fwc_unexp);
186 bfa_assert(0); 186 bfa_sm_fault(rp->bfa, event);
187 } 187 }
188} 188}
189 189
@@ -224,7 +224,7 @@ bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
224 224
225 default: 225 default:
226 bfa_stats(rp, sm_fwc_unexp); 226 bfa_stats(rp, sm_fwc_unexp);
227 bfa_assert(0); 227 bfa_sm_fault(rp->bfa, event);
228 } 228 }
229} 229}
230 230
@@ -296,7 +296,7 @@ bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
296 296
297 default: 297 default:
298 bfa_stats(rp, sm_on_unexp); 298 bfa_stats(rp, sm_on_unexp);
299 bfa_assert(0); 299 bfa_sm_fault(rp->bfa, event);
300 } 300 }
301} 301}
302 302
@@ -329,7 +329,7 @@ bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event)
329 329
330 default: 330 default:
331 bfa_stats(rp, sm_fwd_unexp); 331 bfa_stats(rp, sm_fwd_unexp);
332 bfa_assert(0); 332 bfa_sm_fault(rp->bfa, event);
333 } 333 }
334} 334}
335 335
@@ -359,7 +359,7 @@ bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
359 359
360 default: 360 default:
361 bfa_stats(rp, sm_fwd_unexp); 361 bfa_stats(rp, sm_fwd_unexp);
362 bfa_assert(0); 362 bfa_sm_fault(rp->bfa, event);
363 } 363 }
364} 364}
365 365
@@ -394,7 +394,7 @@ bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
394 394
395 default: 395 default:
396 bfa_stats(rp, sm_off_unexp); 396 bfa_stats(rp, sm_off_unexp);
397 bfa_assert(0); 397 bfa_sm_fault(rp->bfa, event);
398 } 398 }
399} 399}
400 400
@@ -421,7 +421,7 @@ bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event)
421 break; 421 break;
422 422
423 default: 423 default:
424 bfa_assert(0); 424 bfa_sm_fault(rp->bfa, event);
425 } 425 }
426} 426}
427 427
@@ -446,7 +446,7 @@ bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
446 break; 446 break;
447 447
448 default: 448 default:
449 bfa_assert(0); 449 bfa_sm_fault(rp->bfa, event);
450 } 450 }
451} 451}
452 452
@@ -477,7 +477,7 @@ bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
477 477
478 default: 478 default:
479 bfa_stats(rp, sm_delp_unexp); 479 bfa_stats(rp, sm_delp_unexp);
480 bfa_assert(0); 480 bfa_sm_fault(rp->bfa, event);
481 } 481 }
482} 482}
483 483
@@ -512,7 +512,7 @@ bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
512 512
513 default: 513 default:
514 bfa_stats(rp, sm_offp_unexp); 514 bfa_stats(rp, sm_offp_unexp);
515 bfa_assert(0); 515 bfa_sm_fault(rp->bfa, event);
516 } 516 }
517} 517}
518 518
@@ -550,7 +550,7 @@ bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
550 550
551 default: 551 default:
552 bfa_stats(rp, sm_iocd_unexp); 552 bfa_stats(rp, sm_iocd_unexp);
553 bfa_assert(0); 553 bfa_sm_fault(rp->bfa, event);
554 } 554 }
555} 555}
556 556
diff --git a/drivers/scsi/bfa/bfa_trcmod_priv.h b/drivers/scsi/bfa/bfa_trcmod_priv.h
index b3562dce7e9f..a7a82610db85 100644
--- a/drivers/scsi/bfa/bfa_trcmod_priv.h
+++ b/drivers/scsi/bfa/bfa_trcmod_priv.h
@@ -29,38 +29,36 @@
29 * !!! needed between trace utility and driver version 29 * !!! needed between trace utility and driver version
30 */ 30 */
31enum { 31enum {
32 BFA_TRC_HAL_IOC = 1, 32 BFA_TRC_HAL_INTR = 1,
33 BFA_TRC_HAL_INTR = 2, 33 BFA_TRC_HAL_FCXP = 2,
34 BFA_TRC_HAL_FCXP = 3, 34 BFA_TRC_HAL_UF = 3,
35 BFA_TRC_HAL_UF = 4, 35 BFA_TRC_HAL_RPORT = 4,
36 BFA_TRC_HAL_DIAG = 5, 36 BFA_TRC_HAL_FCPIM = 5,
37 BFA_TRC_HAL_RPORT = 6, 37 BFA_TRC_HAL_IOIM = 6,
38 BFA_TRC_HAL_FCPIM = 7, 38 BFA_TRC_HAL_TSKIM = 7,
39 BFA_TRC_HAL_IOIM = 8, 39 BFA_TRC_HAL_ITNIM = 8,
40 BFA_TRC_HAL_TSKIM = 9, 40 BFA_TRC_HAL_FCPORT = 9,
41 BFA_TRC_HAL_ITNIM = 10, 41 BFA_TRC_HAL_SGPG = 10,
42 BFA_TRC_HAL_PPORT = 11, 42 BFA_TRC_HAL_FLASH = 11,
43 BFA_TRC_HAL_SGPG = 12, 43 BFA_TRC_HAL_DEBUG = 12,
44 BFA_TRC_HAL_FLASH = 13, 44 BFA_TRC_HAL_WWN = 13,
45 BFA_TRC_HAL_DEBUG = 14, 45 BFA_TRC_HAL_FLASH_RAW = 14,
46 BFA_TRC_HAL_WWN = 15, 46 BFA_TRC_HAL_SBOOT = 15,
47 BFA_TRC_HAL_FLASH_RAW = 16, 47 BFA_TRC_HAL_SBOOT_IO = 16,
48 BFA_TRC_HAL_SBOOT = 17, 48 BFA_TRC_HAL_SBOOT_INTR = 17,
49 BFA_TRC_HAL_SBOOT_IO = 18, 49 BFA_TRC_HAL_SBTEST = 18,
50 BFA_TRC_HAL_SBOOT_INTR = 19, 50 BFA_TRC_HAL_IPFC = 19,
51 BFA_TRC_HAL_SBTEST = 20, 51 BFA_TRC_HAL_IOCFC = 20,
52 BFA_TRC_HAL_IPFC = 21, 52 BFA_TRC_HAL_FCPTM = 21,
53 BFA_TRC_HAL_IOCFC = 22, 53 BFA_TRC_HAL_IOTM = 22,
54 BFA_TRC_HAL_FCPTM = 23, 54 BFA_TRC_HAL_TSKTM = 23,
55 BFA_TRC_HAL_IOTM = 24, 55 BFA_TRC_HAL_TIN = 24,
56 BFA_TRC_HAL_TSKTM = 25, 56 BFA_TRC_HAL_LPS = 25,
57 BFA_TRC_HAL_TIN = 26, 57 BFA_TRC_HAL_FCDIAG = 26,
58 BFA_TRC_HAL_LPS = 27, 58 BFA_TRC_HAL_PBIND = 27,
59 BFA_TRC_HAL_FCDIAG = 28, 59 BFA_TRC_HAL_IOCFC_CT = 28,
60 BFA_TRC_HAL_PBIND = 29, 60 BFA_TRC_HAL_IOCFC_CB = 29,
61 BFA_TRC_HAL_IOCFC_CT = 30, 61 BFA_TRC_HAL_IOCFC_Q = 30,
62 BFA_TRC_HAL_IOCFC_CB = 31,
63 BFA_TRC_HAL_IOCFC_Q = 32,
64}; 62};
65 63
66#endif /* __BFA_TRCMOD_PRIV_H__ */ 64#endif /* __BFA_TRCMOD_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_tskim.c b/drivers/scsi/bfa/bfa_tskim.c
index ff7a4dc0bf3c..ad9aaaedd3f1 100644
--- a/drivers/scsi/bfa/bfa_tskim.c
+++ b/drivers/scsi/bfa/bfa_tskim.c
@@ -110,7 +110,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
110 break; 110 break;
111 111
112 default: 112 default:
113 bfa_assert(0); 113 bfa_sm_fault(tskim->bfa, event);
114 } 114 }
115} 115}
116 116
@@ -146,7 +146,7 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
146 break; 146 break;
147 147
148 default: 148 default:
149 bfa_assert(0); 149 bfa_sm_fault(tskim->bfa, event);
150 } 150 }
151} 151}
152 152
@@ -178,7 +178,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
178 break; 178 break;
179 179
180 default: 180 default:
181 bfa_assert(0); 181 bfa_sm_fault(tskim->bfa, event);
182 } 182 }
183} 183}
184 184
@@ -207,7 +207,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
207 break; 207 break;
208 208
209 default: 209 default:
210 bfa_assert(0); 210 bfa_sm_fault(tskim->bfa, event);
211 } 211 }
212} 212}
213 213
@@ -242,7 +242,7 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
242 break; 242 break;
243 243
244 default: 244 default:
245 bfa_assert(0); 245 bfa_sm_fault(tskim->bfa, event);
246 } 246 }
247} 247}
248 248
@@ -277,7 +277,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
277 break; 277 break;
278 278
279 default: 279 default:
280 bfa_assert(0); 280 bfa_sm_fault(tskim->bfa, event);
281 } 281 }
282} 282}
283 283
@@ -303,7 +303,7 @@ bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
303 break; 303 break;
304 304
305 default: 305 default:
306 bfa_assert(0); 306 bfa_sm_fault(tskim->bfa, event);
307 } 307 }
308} 308}
309 309
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index b52b773d49d9..6bff08ea4029 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/kthread.h>
23#include "bfad_drv.h" 24#include "bfad_drv.h"
24#include "bfad_im.h" 25#include "bfad_im.h"
25#include "bfad_tm.h" 26#include "bfad_tm.h"
@@ -53,6 +54,7 @@ static int log_level = BFA_LOG_WARNING;
53static int ioc_auto_recover = BFA_TRUE; 54static int ioc_auto_recover = BFA_TRUE;
54static int ipfc_enable = BFA_FALSE; 55static int ipfc_enable = BFA_FALSE;
55static int ipfc_mtu = -1; 56static int ipfc_mtu = -1;
57static int fdmi_enable = BFA_TRUE;
56int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH; 58int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
57int bfa_linkup_delay = -1; 59int bfa_linkup_delay = -1;
58 60
@@ -74,6 +76,7 @@ module_param(log_level, int, S_IRUGO | S_IWUSR);
74module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); 76module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
75module_param(ipfc_enable, int, S_IRUGO | S_IWUSR); 77module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
76module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR); 78module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
79module_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
77module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR); 80module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
78 81
79/* 82/*
@@ -95,6 +98,8 @@ bfad_fc4_probe(struct bfad_s *bfad)
95 98
96 if (ipfc_enable) 99 if (ipfc_enable)
97 bfad_ipfc_probe(bfad); 100 bfad_ipfc_probe(bfad);
101
102 bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
98ext: 103ext:
99 return rc; 104 return rc;
100} 105}
@@ -106,6 +111,7 @@ bfad_fc4_probe_undo(struct bfad_s *bfad)
106 bfad_tm_probe_undo(bfad); 111 bfad_tm_probe_undo(bfad);
107 if (ipfc_enable) 112 if (ipfc_enable)
108 bfad_ipfc_probe_undo(bfad); 113 bfad_ipfc_probe_undo(bfad);
114 bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
109} 115}
110 116
111static void 117static void
@@ -173,9 +179,19 @@ bfa_cb_init(void *drv, bfa_status_t init_status)
173{ 179{
174 struct bfad_s *bfad = drv; 180 struct bfad_s *bfad = drv;
175 181
176 if (init_status == BFA_STATUS_OK) 182 if (init_status == BFA_STATUS_OK) {
177 bfad->bfad_flags |= BFAD_HAL_INIT_DONE; 183 bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
178 184
185 /* If BFAD_HAL_INIT_FAIL flag is set:
186 * Wake up the kernel thread to start
187 * the bfad operations after HAL init done
188 */
189 if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
190 bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
191 wake_up_process(bfad->bfad_tsk);
192 }
193 }
194
179 complete(&bfad->comp); 195 complete(&bfad->comp);
180} 196}
181 197
@@ -648,7 +664,7 @@ bfad_fcs_port_cfg(struct bfad_s *bfad)
648 664
649 sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no); 665 sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
650 memcpy(port_cfg.sym_name.symname, symname, strlen(symname)); 666 memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
651 bfa_pport_get_attr(&bfad->bfa, &attr); 667 bfa_fcport_get_attr(&bfad->bfa, &attr);
652 port_cfg.nwwn = attr.nwwn; 668 port_cfg.nwwn = attr.nwwn;
653 port_cfg.pwwn = attr.pwwn; 669 port_cfg.pwwn = attr.pwwn;
654 670
@@ -661,7 +677,6 @@ bfad_drv_init(struct bfad_s *bfad)
661 bfa_status_t rc; 677 bfa_status_t rc;
662 unsigned long flags; 678 unsigned long flags;
663 struct bfa_fcs_driver_info_s driver_info; 679 struct bfa_fcs_driver_info_s driver_info;
664 int i;
665 680
666 bfad->cfg_data.rport_del_timeout = rport_del_timeout; 681 bfad->cfg_data.rport_del_timeout = rport_del_timeout;
667 bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth; 682 bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
@@ -681,12 +696,7 @@ bfad_drv_init(struct bfad_s *bfad)
681 bfa_init_log(&bfad->bfa, bfad->logmod); 696 bfa_init_log(&bfad->bfa, bfad->logmod);
682 bfa_init_trc(&bfad->bfa, bfad->trcmod); 697 bfa_init_trc(&bfad->bfa, bfad->trcmod);
683 bfa_init_aen(&bfad->bfa, bfad->aen); 698 bfa_init_aen(&bfad->bfa, bfad->aen);
684 INIT_LIST_HEAD(&bfad->file_q); 699 memset(bfad->file_map, 0, sizeof(bfad->file_map));
685 INIT_LIST_HEAD(&bfad->file_free_q);
686 for (i = 0; i < BFAD_AEN_MAX_APPS; i++) {
687 bfa_q_qe_init(&bfad->file_buf[i].qe);
688 list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q);
689 }
690 bfa_init_plog(&bfad->bfa, &bfad->plog_buf); 700 bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
691 bfa_plog_init(&bfad->plog_buf); 701 bfa_plog_init(&bfad->plog_buf);
692 bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START, 702 bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
@@ -746,8 +756,16 @@ bfad_drv_init(struct bfad_s *bfad)
746 bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod); 756 bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
747 bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod); 757 bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
748 bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen); 758 bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
749 bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); 759 bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
760
761 /* Do FCS init only when HAL init is done */
762 if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
763 bfa_fcs_init(&bfad->bfa_fcs);
764 bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
765 }
766
750 bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info); 767 bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
768 bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
751 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 769 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
752 770
753 bfad->bfad_flags |= BFAD_DRV_INIT_DONE; 771 bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
@@ -763,12 +781,21 @@ out_hal_mem_alloc_failure:
763void 781void
764bfad_drv_uninit(struct bfad_s *bfad) 782bfad_drv_uninit(struct bfad_s *bfad)
765{ 783{
784 unsigned long flags;
785
786 spin_lock_irqsave(&bfad->bfad_lock, flags);
787 init_completion(&bfad->comp);
788 bfa_stop(&bfad->bfa);
789 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
790 wait_for_completion(&bfad->comp);
791
766 del_timer_sync(&bfad->hal_tmo); 792 del_timer_sync(&bfad->hal_tmo);
767 bfa_isr_disable(&bfad->bfa); 793 bfa_isr_disable(&bfad->bfa);
768 bfa_detach(&bfad->bfa); 794 bfa_detach(&bfad->bfa);
769 bfad_remove_intr(bfad); 795 bfad_remove_intr(bfad);
770 bfa_assert(list_empty(&bfad->file_q));
771 bfad_hal_mem_release(bfad); 796 bfad_hal_mem_release(bfad);
797
798 bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
772} 799}
773 800
774void 801void
@@ -859,6 +886,86 @@ bfad_drv_log_level_set(struct bfad_s *bfad)
859 bfa_log_set_level_all(&bfad->log_data, log_level); 886 bfa_log_set_level_all(&bfad->log_data, log_level);
860} 887}
861 888
889bfa_status_t
890bfad_start_ops(struct bfad_s *bfad)
891{
892 int retval;
893
894 /* PPORT FCS config */
895 bfad_fcs_port_cfg(bfad);
896
897 retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
898 if (retval != BFA_STATUS_OK)
899 goto out_cfg_pport_failure;
900
901 /* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */
902 retval = bfad_fc4_probe(bfad);
903 if (retval != BFA_STATUS_OK) {
904 printk(KERN_WARNING "bfad_fc4_probe failed\n");
905 goto out_fc4_probe_failure;
906 }
907
908 bfad_drv_start(bfad);
909
910 /*
911 * If bfa_linkup_delay is set to -1 default; try to retrive the
912 * value using the bfad_os_get_linkup_delay(); else use the
913 * passed in module param value as the bfa_linkup_delay.
914 */
915 if (bfa_linkup_delay < 0) {
916
917 bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
918 bfad_os_rport_online_wait(bfad);
919 bfa_linkup_delay = -1;
920
921 } else {
922 bfad_os_rport_online_wait(bfad);
923 }
924
925 bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
926
927 return BFA_STATUS_OK;
928
929out_fc4_probe_failure:
930 bfad_fc4_probe_undo(bfad);
931 bfad_uncfg_pport(bfad);
932out_cfg_pport_failure:
933 return BFA_STATUS_FAILED;
934}
935
936int
937bfad_worker (void *ptr)
938{
939 struct bfad_s *bfad;
940 unsigned long flags;
941
942 bfad = (struct bfad_s *)ptr;
943
944 while (!kthread_should_stop()) {
945
946 /* Check if the FCS init is done from bfad_drv_init;
947 * if not done do FCS init and set the flag.
948 */
949 if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) {
950 spin_lock_irqsave(&bfad->bfad_lock, flags);
951 bfa_fcs_init(&bfad->bfa_fcs);
952 bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
953 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
954 }
955
956 /* Start the bfad operations after HAL init done */
957 bfad_start_ops(bfad);
958
959 spin_lock_irqsave(&bfad->bfad_lock, flags);
960 bfad->bfad_tsk = NULL;
961 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
962
963 break;
964 }
965
966 return 0;
967}
968
862 /* 969 /*
863 * PCI_entry PCI driver entries * { 970 * PCI_entry PCI driver entries * {
864 */ 971 */
@@ -871,7 +978,6 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
871{ 978{
872 struct bfad_s *bfad; 979 struct bfad_s *bfad;
873 int error = -ENODEV, retval; 980 int error = -ENODEV, retval;
874 char buf[16];
875 981
876 /* 982 /*
877 * For single port cards - only claim function 0 983 * For single port cards - only claim function 0
@@ -902,8 +1008,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
902 bfa_trc(bfad, bfad_inst); 1008 bfa_trc(bfad, bfad_inst);
903 1009
904 bfad->logmod = &bfad->log_data; 1010 bfad->logmod = &bfad->log_data;
905 sprintf(buf, "%d", bfad_inst); 1011 bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf);
906 bfa_log_init(bfad->logmod, buf, bfa_os_printf);
907 1012
908 bfad_drv_log_level_set(bfad); 1013 bfad_drv_log_level_set(bfad);
909 1014
@@ -933,57 +1038,39 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
933 bfad->ref_count = 0; 1038 bfad->ref_count = 0;
934 bfad->pport.bfad = bfad; 1039 bfad->pport.bfad = bfad;
935 1040
1041 bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
1042 "bfad_worker");
1043 if (IS_ERR(bfad->bfad_tsk)) {
1044 printk(KERN_INFO "bfad[%d]: Kernel thread"
1045 " creation failed!\n",
1046 bfad->inst_no);
1047 goto out_kthread_create_failure;
1048 }
1049
936 retval = bfad_drv_init(bfad); 1050 retval = bfad_drv_init(bfad);
937 if (retval != BFA_STATUS_OK) 1051 if (retval != BFA_STATUS_OK)
938 goto out_drv_init_failure; 1052 goto out_drv_init_failure;
939 if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { 1053 if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1054 bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
940 printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no); 1055 printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
941 goto ok; 1056 goto ok;
942 } 1057 }
943 1058
944 /* 1059 retval = bfad_start_ops(bfad);
945 * PPORT FCS config
946 */
947 bfad_fcs_port_cfg(bfad);
948
949 retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
950 if (retval != BFA_STATUS_OK) 1060 if (retval != BFA_STATUS_OK)
951 goto out_cfg_pport_failure; 1061 goto out_start_ops_failure;
952
953 /*
954 * BFAD level FC4 (IM/TM/IPFC) specific resource allocation
955 */
956 retval = bfad_fc4_probe(bfad);
957 if (retval != BFA_STATUS_OK) {
958 printk(KERN_WARNING "bfad_fc4_probe failed\n");
959 goto out_fc4_probe_failure;
960 }
961 1062
962 bfad_drv_start(bfad); 1063 kthread_stop(bfad->bfad_tsk);
963 1064 bfad->bfad_tsk = NULL;
964 /*
965 * If bfa_linkup_delay is set to -1 default; try to retrive the
966 * value using the bfad_os_get_linkup_delay(); else use the
967 * passed in module param value as the bfa_linkup_delay.
968 */
969 if (bfa_linkup_delay < 0) {
970 bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
971 bfad_os_rport_online_wait(bfad);
972 bfa_linkup_delay = -1;
973 } else {
974 bfad_os_rport_online_wait(bfad);
975 }
976 1065
977 bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
978ok: 1066ok:
979 return 0; 1067 return 0;
980 1068
981out_fc4_probe_failure: 1069out_start_ops_failure:
982 bfad_fc4_probe_undo(bfad);
983 bfad_uncfg_pport(bfad);
984out_cfg_pport_failure:
985 bfad_drv_uninit(bfad); 1070 bfad_drv_uninit(bfad);
986out_drv_init_failure: 1071out_drv_init_failure:
1072 kthread_stop(bfad->bfad_tsk);
1073out_kthread_create_failure:
987 mutex_lock(&bfad_mutex); 1074 mutex_lock(&bfad_mutex);
988 bfad_inst--; 1075 bfad_inst--;
989 list_del(&bfad->list_entry); 1076 list_del(&bfad->list_entry);
@@ -1008,6 +1095,11 @@ bfad_pci_remove(struct pci_dev *pdev)
1008 1095
1009 bfa_trc(bfad, bfad->inst_no); 1096 bfa_trc(bfad, bfad->inst_no);
1010 1097
1098 spin_lock_irqsave(&bfad->bfad_lock, flags);
1099 if (bfad->bfad_tsk != NULL)
1100 kthread_stop(bfad->bfad_tsk);
1101 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1102
1011 if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE) 1103 if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
1012 && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { 1104 && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1013 1105
@@ -1024,13 +1116,25 @@ bfad_pci_remove(struct pci_dev *pdev)
1024 goto remove_sysfs; 1116 goto remove_sysfs;
1025 } 1117 }
1026 1118
1027 if (bfad->bfad_flags & BFAD_HAL_START_DONE) 1119 if (bfad->bfad_flags & BFAD_HAL_START_DONE) {
1028 bfad_drv_stop(bfad); 1120 bfad_drv_stop(bfad);
1121 } else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) {
1122 /* Invoking bfa_stop() before bfa_detach
1123 * when HAL and DRV init are success
1124 * but HAL start did not occur.
1125 */
1126 spin_lock_irqsave(&bfad->bfad_lock, flags);
1127 init_completion(&bfad->comp);
1128 bfa_stop(&bfad->bfa);
1129 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1130 wait_for_completion(&bfad->comp);
1131 }
1029 1132
1030 bfad_remove_intr(bfad); 1133 bfad_remove_intr(bfad);
1031
1032 del_timer_sync(&bfad->hal_tmo); 1134 del_timer_sync(&bfad->hal_tmo);
1033 bfad_fc4_probe_undo(bfad); 1135
1136 if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE)
1137 bfad_fc4_probe_undo(bfad);
1034 1138
1035 if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE) 1139 if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
1036 bfad_uncfg_pport(bfad); 1140 bfad_uncfg_pport(bfad);
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
index 9129ae3040ff..d97f69191838 100644
--- a/drivers/scsi/bfa/bfad_attr.c
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -141,7 +141,7 @@ bfad_im_get_host_port_type(struct Scsi_Host *shost)
141 struct bfad_s *bfad = im_port->bfad; 141 struct bfad_s *bfad = im_port->bfad;
142 struct bfa_pport_attr_s attr; 142 struct bfa_pport_attr_s attr;
143 143
144 bfa_pport_get_attr(&bfad->bfa, &attr); 144 bfa_fcport_get_attr(&bfad->bfa, &attr);
145 145
146 switch (attr.port_type) { 146 switch (attr.port_type) {
147 case BFA_PPORT_TYPE_NPORT: 147 case BFA_PPORT_TYPE_NPORT:
@@ -173,7 +173,7 @@ bfad_im_get_host_port_state(struct Scsi_Host *shost)
173 struct bfad_s *bfad = im_port->bfad; 173 struct bfad_s *bfad = im_port->bfad;
174 struct bfa_pport_attr_s attr; 174 struct bfa_pport_attr_s attr;
175 175
176 bfa_pport_get_attr(&bfad->bfa, &attr); 176 bfa_fcport_get_attr(&bfad->bfa, &attr);
177 177
178 switch (attr.port_state) { 178 switch (attr.port_state) {
179 case BFA_PPORT_ST_LINKDOWN: 179 case BFA_PPORT_ST_LINKDOWN:
@@ -229,8 +229,10 @@ bfad_im_get_host_speed(struct Scsi_Host *shost)
229 (struct bfad_im_port_s *) shost->hostdata[0]; 229 (struct bfad_im_port_s *) shost->hostdata[0];
230 struct bfad_s *bfad = im_port->bfad; 230 struct bfad_s *bfad = im_port->bfad;
231 struct bfa_pport_attr_s attr; 231 struct bfa_pport_attr_s attr;
232 unsigned long flags;
232 233
233 bfa_pport_get_attr(&bfad->bfa, &attr); 234 spin_lock_irqsave(shost->host_lock, flags);
235 bfa_fcport_get_attr(&bfad->bfa, &attr);
234 switch (attr.speed) { 236 switch (attr.speed) {
235 case BFA_PPORT_SPEED_8GBPS: 237 case BFA_PPORT_SPEED_8GBPS:
236 fc_host_speed(shost) = FC_PORTSPEED_8GBIT; 238 fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
@@ -248,6 +250,7 @@ bfad_im_get_host_speed(struct Scsi_Host *shost)
248 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; 250 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
249 break; 251 break;
250 } 252 }
253 spin_unlock_irqrestore(shost->host_lock, flags);
251} 254}
252 255
253/** 256/**
@@ -285,7 +288,7 @@ bfad_im_get_stats(struct Scsi_Host *shost)
285 init_completion(&fcomp.comp); 288 init_completion(&fcomp.comp);
286 spin_lock_irqsave(&bfad->bfad_lock, flags); 289 spin_lock_irqsave(&bfad->bfad_lock, flags);
287 memset(hstats, 0, sizeof(struct fc_host_statistics)); 290 memset(hstats, 0, sizeof(struct fc_host_statistics));
288 rc = bfa_pport_get_stats(&bfad->bfa, 291 rc = bfa_port_get_stats(BFA_FCPORT(&bfad->bfa),
289 (union bfa_pport_stats_u *) hstats, 292 (union bfa_pport_stats_u *) hstats,
290 bfad_hcb_comp, &fcomp); 293 bfad_hcb_comp, &fcomp);
291 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 294 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -312,7 +315,8 @@ bfad_im_reset_stats(struct Scsi_Host *shost)
312 315
313 init_completion(&fcomp.comp); 316 init_completion(&fcomp.comp);
314 spin_lock_irqsave(&bfad->bfad_lock, flags); 317 spin_lock_irqsave(&bfad->bfad_lock, flags);
315 rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp); 318 rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp,
319 &fcomp);
316 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 320 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
317 321
318 if (rc != BFA_STATUS_OK) 322 if (rc != BFA_STATUS_OK)
@@ -421,12 +425,10 @@ bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
421 struct bfad_im_port_s *im_port = 425 struct bfad_im_port_s *im_port =
422 (struct bfad_im_port_s *) shost->hostdata[0]; 426 (struct bfad_im_port_s *) shost->hostdata[0];
423 struct bfad_s *bfad = im_port->bfad; 427 struct bfad_s *bfad = im_port->bfad;
424 struct bfa_ioc_attr_s ioc_attr; 428 char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
425 429
426 memset(&ioc_attr, 0, sizeof(ioc_attr)); 430 bfa_get_adapter_serial_num(&bfad->bfa, serial_num);
427 bfa_get_attr(&bfad->bfa, &ioc_attr); 431 return snprintf(buf, PAGE_SIZE, "%s\n", serial_num);
428 return snprintf(buf, PAGE_SIZE, "%s\n",
429 ioc_attr.adapter_attr.serial_num);
430} 432}
431 433
432static ssize_t 434static ssize_t
@@ -437,11 +439,10 @@ bfad_im_model_show(struct device *dev, struct device_attribute *attr,
437 struct bfad_im_port_s *im_port = 439 struct bfad_im_port_s *im_port =
438 (struct bfad_im_port_s *) shost->hostdata[0]; 440 (struct bfad_im_port_s *) shost->hostdata[0];
439 struct bfad_s *bfad = im_port->bfad; 441 struct bfad_s *bfad = im_port->bfad;
440 struct bfa_ioc_attr_s ioc_attr; 442 char model[BFA_ADAPTER_MODEL_NAME_LEN];
441 443
442 memset(&ioc_attr, 0, sizeof(ioc_attr)); 444 bfa_get_adapter_model(&bfad->bfa, model);
443 bfa_get_attr(&bfad->bfa, &ioc_attr); 445 return snprintf(buf, PAGE_SIZE, "%s\n", model);
444 return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model);
445} 446}
446 447
447static ssize_t 448static ssize_t
@@ -452,12 +453,10 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
452 struct bfad_im_port_s *im_port = 453 struct bfad_im_port_s *im_port =
453 (struct bfad_im_port_s *) shost->hostdata[0]; 454 (struct bfad_im_port_s *) shost->hostdata[0];
454 struct bfad_s *bfad = im_port->bfad; 455 struct bfad_s *bfad = im_port->bfad;
455 struct bfa_ioc_attr_s ioc_attr; 456 char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
456 457
457 memset(&ioc_attr, 0, sizeof(ioc_attr)); 458 bfa_get_adapter_model(&bfad->bfa, model_descr);
458 bfa_get_attr(&bfad->bfa, &ioc_attr); 459 return snprintf(buf, PAGE_SIZE, "%s\n", model_descr);
459 return snprintf(buf, PAGE_SIZE, "%s\n",
460 ioc_attr.adapter_attr.model_descr);
461} 460}
462 461
463static ssize_t 462static ssize_t
@@ -482,14 +481,13 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
482 struct bfad_im_port_s *im_port = 481 struct bfad_im_port_s *im_port =
483 (struct bfad_im_port_s *) shost->hostdata[0]; 482 (struct bfad_im_port_s *) shost->hostdata[0];
484 struct bfad_s *bfad = im_port->bfad; 483 struct bfad_s *bfad = im_port->bfad;
485 struct bfa_ioc_attr_s ioc_attr; 484 char model[BFA_ADAPTER_MODEL_NAME_LEN];
486 485 char fw_ver[BFA_VERSION_LEN];
487 memset(&ioc_attr, 0, sizeof(ioc_attr));
488 bfa_get_attr(&bfad->bfa, &ioc_attr);
489 486
487 bfa_get_adapter_model(&bfad->bfa, model);
488 bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
490 return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n", 489 return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n",
491 ioc_attr.adapter_attr.model, 490 model, fw_ver, BFAD_DRIVER_VERSION);
492 ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
493} 491}
494 492
495static ssize_t 493static ssize_t
@@ -500,11 +498,10 @@ bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
500 struct bfad_im_port_s *im_port = 498 struct bfad_im_port_s *im_port =
501 (struct bfad_im_port_s *) shost->hostdata[0]; 499 (struct bfad_im_port_s *) shost->hostdata[0];
502 struct bfad_s *bfad = im_port->bfad; 500 struct bfad_s *bfad = im_port->bfad;
503 struct bfa_ioc_attr_s ioc_attr; 501 char hw_ver[BFA_VERSION_LEN];
504 502
505 memset(&ioc_attr, 0, sizeof(ioc_attr)); 503 bfa_get_pci_chip_rev(&bfad->bfa, hw_ver);
506 bfa_get_attr(&bfad->bfa, &ioc_attr); 504 return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver);
507 return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver);
508} 505}
509 506
510static ssize_t 507static ssize_t
@@ -522,12 +519,10 @@ bfad_im_optionrom_version_show(struct device *dev,
522 struct bfad_im_port_s *im_port = 519 struct bfad_im_port_s *im_port =
523 (struct bfad_im_port_s *) shost->hostdata[0]; 520 (struct bfad_im_port_s *) shost->hostdata[0];
524 struct bfad_s *bfad = im_port->bfad; 521 struct bfad_s *bfad = im_port->bfad;
525 struct bfa_ioc_attr_s ioc_attr; 522 char optrom_ver[BFA_VERSION_LEN];
526 523
527 memset(&ioc_attr, 0, sizeof(ioc_attr)); 524 bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
528 bfa_get_attr(&bfad->bfa, &ioc_attr); 525 return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver);
529 return snprintf(buf, PAGE_SIZE, "%s\n",
530 ioc_attr.adapter_attr.optrom_ver);
531} 526}
532 527
533static ssize_t 528static ssize_t
@@ -538,11 +533,10 @@ bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
538 struct bfad_im_port_s *im_port = 533 struct bfad_im_port_s *im_port =
539 (struct bfad_im_port_s *) shost->hostdata[0]; 534 (struct bfad_im_port_s *) shost->hostdata[0];
540 struct bfad_s *bfad = im_port->bfad; 535 struct bfad_s *bfad = im_port->bfad;
541 struct bfa_ioc_attr_s ioc_attr; 536 char fw_ver[BFA_VERSION_LEN];
542 537
543 memset(&ioc_attr, 0, sizeof(ioc_attr)); 538 bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
544 bfa_get_attr(&bfad->bfa, &ioc_attr); 539 return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver);
545 return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver);
546} 540}
547 541
548static ssize_t 542static ssize_t
@@ -553,11 +547,9 @@ bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
553 struct bfad_im_port_s *im_port = 547 struct bfad_im_port_s *im_port =
554 (struct bfad_im_port_s *) shost->hostdata[0]; 548 (struct bfad_im_port_s *) shost->hostdata[0];
555 struct bfad_s *bfad = im_port->bfad; 549 struct bfad_s *bfad = im_port->bfad;
556 struct bfa_ioc_attr_s ioc_attr;
557 550
558 memset(&ioc_attr, 0, sizeof(ioc_attr)); 551 return snprintf(buf, PAGE_SIZE, "%d\n",
559 bfa_get_attr(&bfad->bfa, &ioc_attr); 552 bfa_get_nports(&bfad->bfa));
560 return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports);
561} 553}
562 554
563static ssize_t 555static ssize_t
diff --git a/drivers/scsi/bfa/bfad_attr.h b/drivers/scsi/bfa/bfad_attr.h
index 4d3312da6a81..bf0102076508 100644
--- a/drivers/scsi/bfa/bfad_attr.h
+++ b/drivers/scsi/bfa/bfad_attr.h
@@ -17,9 +17,6 @@
17 17
18#ifndef __BFAD_ATTR_H__ 18#ifndef __BFAD_ATTR_H__
19#define __BFAD_ATTR_H__ 19#define __BFAD_ATTR_H__
20/**
21 * bfad_attr.h VMware driver configuration interface module.
22 */
23 20
24/** 21/**
25 * FC_transport_template FC transport template 22 * FC_transport_template FC transport template
@@ -52,12 +49,6 @@ bfad_im_get_starget_port_name(struct scsi_target *starget);
52void 49void
53bfad_im_get_host_port_id(struct Scsi_Host *shost); 50bfad_im_get_host_port_id(struct Scsi_Host *shost);
54 51
55/**
56 * FC transport template entry, issue a LIP.
57 */
58int
59bfad_im_issue_fc_host_lip(struct Scsi_Host *shost);
60
61struct Scsi_Host* 52struct Scsi_Host*
62bfad_os_starget_to_shost(struct scsi_target *starget); 53bfad_os_starget_to_shost(struct scsi_target *starget);
63 54
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h
index 172c81e25c1c..107848cd3b6d 100644
--- a/drivers/scsi/bfa/bfad_drv.h
+++ b/drivers/scsi/bfa/bfad_drv.h
@@ -46,7 +46,7 @@
46#ifdef BFA_DRIVER_VERSION 46#ifdef BFA_DRIVER_VERSION
47#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION 47#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION
48#else 48#else
49#define BFAD_DRIVER_VERSION "2.0.0.0" 49#define BFAD_DRIVER_VERSION "2.1.2.1"
50#endif 50#endif
51 51
52 52
@@ -62,7 +62,9 @@
62#define BFAD_HAL_START_DONE 0x00000010 62#define BFAD_HAL_START_DONE 0x00000010
63#define BFAD_PORT_ONLINE 0x00000020 63#define BFAD_PORT_ONLINE 0x00000020
64#define BFAD_RPORT_ONLINE 0x00000040 64#define BFAD_RPORT_ONLINE 0x00000040
65 65#define BFAD_FCS_INIT_DONE 0x00000080
66#define BFAD_HAL_INIT_FAIL 0x00000100
67#define BFAD_FC4_PROBE_DONE 0x00000200
66#define BFAD_PORT_DELETE 0x00000001 68#define BFAD_PORT_DELETE 0x00000001
67 69
68/* 70/*
@@ -137,12 +139,16 @@ struct bfad_cfg_param_s {
137 u32 binding_method; 139 u32 binding_method;
138}; 140};
139 141
140#define BFAD_AEN_MAX_APPS 8 142union bfad_tmp_buf {
141struct bfad_aen_file_s { 143 /* From struct bfa_adapter_attr_s */
142 struct list_head qe; 144 char manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
143 struct bfad_s *bfad; 145 char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
144 s32 ri; 146 char model[BFA_ADAPTER_MODEL_NAME_LEN];
145 s32 app_id; 147 char fw_ver[BFA_VERSION_LEN];
148 char optrom_ver[BFA_VERSION_LEN];
149
150 /* From struct bfa_ioc_pci_attr_s */
151 u8 chip_rev[BFA_IOC_CHIP_REV_LEN]; /* chip revision */
146}; 152};
147 153
148/* 154/*
@@ -168,6 +174,7 @@ struct bfad_s {
168 u32 inst_no; /* BFAD instance number */ 174 u32 inst_no; /* BFAD instance number */
169 u32 bfad_flags; 175 u32 bfad_flags;
170 spinlock_t bfad_lock; 176 spinlock_t bfad_lock;
177 struct task_struct *bfad_tsk;
171 struct bfad_cfg_param_s cfg_data; 178 struct bfad_cfg_param_s cfg_data;
172 struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY]; 179 struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY];
173 int nvec; 180 int nvec;
@@ -183,18 +190,12 @@ struct bfad_s {
183 struct bfa_log_mod_s *logmod; 190 struct bfa_log_mod_s *logmod;
184 struct bfa_aen_s *aen; 191 struct bfa_aen_s *aen;
185 struct bfa_aen_s aen_buf; 192 struct bfa_aen_s aen_buf;
186 struct bfad_aen_file_s file_buf[BFAD_AEN_MAX_APPS]; 193 void *file_map[BFA_AEN_MAX_APP];
187 struct list_head file_q;
188 struct list_head file_free_q;
189 struct bfa_plog_s plog_buf; 194 struct bfa_plog_s plog_buf;
190 int ref_count; 195 int ref_count;
191 bfa_boolean_t ipfc_enabled; 196 bfa_boolean_t ipfc_enabled;
197 union bfad_tmp_buf tmp_buf;
192 struct fc_host_statistics link_stats; 198 struct fc_host_statistics link_stats;
193
194 struct kobject *bfa_kobj;
195 struct kobject *ioc_kobj;
196 struct kobject *pport_kobj;
197 struct kobject *lport_kobj;
198}; 199};
199 200
200/* 201/*
@@ -258,6 +259,7 @@ bfa_status_t bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
258 struct bfa_port_cfg_s *port_cfg); 259 struct bfa_port_cfg_s *port_cfg);
259bfa_status_t bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role); 260bfa_status_t bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role);
260bfa_status_t bfad_drv_init(struct bfad_s *bfad); 261bfa_status_t bfad_drv_init(struct bfad_s *bfad);
262bfa_status_t bfad_start_ops(struct bfad_s *bfad);
261void bfad_drv_start(struct bfad_s *bfad); 263void bfad_drv_start(struct bfad_s *bfad);
262void bfad_uncfg_pport(struct bfad_s *bfad); 264void bfad_uncfg_pport(struct bfad_s *bfad);
263void bfad_drv_stop(struct bfad_s *bfad); 265void bfad_drv_stop(struct bfad_s *bfad);
@@ -279,6 +281,7 @@ void bfad_drv_uninit(struct bfad_s *bfad);
279void bfad_drv_log_level_set(struct bfad_s *bfad); 281void bfad_drv_log_level_set(struct bfad_s *bfad);
280bfa_status_t bfad_fc4_module_init(void); 282bfa_status_t bfad_fc4_module_init(void);
281void bfad_fc4_module_exit(void); 283void bfad_fc4_module_exit(void);
284int bfad_worker (void *ptr);
282 285
283void bfad_pci_remove(struct pci_dev *pdev); 286void bfad_pci_remove(struct pci_dev *pdev);
284int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid); 287int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid);
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index f788c2a0ab07..f9fc67a25bf2 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -43,11 +43,11 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
43 struct bfad_s *bfad = drv; 43 struct bfad_s *bfad = drv;
44 struct bfad_itnim_data_s *itnim_data; 44 struct bfad_itnim_data_s *itnim_data;
45 struct bfad_itnim_s *itnim; 45 struct bfad_itnim_s *itnim;
46 u8 host_status = DID_OK;
46 47
47 switch (io_status) { 48 switch (io_status) {
48 case BFI_IOIM_STS_OK: 49 case BFI_IOIM_STS_OK:
49 bfa_trc(bfad, scsi_status); 50 bfa_trc(bfad, scsi_status);
50 cmnd->result = ScsiResult(DID_OK, scsi_status);
51 scsi_set_resid(cmnd, 0); 51 scsi_set_resid(cmnd, 0);
52 52
53 if (sns_len > 0) { 53 if (sns_len > 0) {
@@ -56,8 +56,18 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
56 sns_len = SCSI_SENSE_BUFFERSIZE; 56 sns_len = SCSI_SENSE_BUFFERSIZE;
57 memcpy(cmnd->sense_buffer, sns_info, sns_len); 57 memcpy(cmnd->sense_buffer, sns_info, sns_len);
58 } 58 }
59 if (residue > 0) 59 if (residue > 0) {
60 bfa_trc(bfad, residue);
60 scsi_set_resid(cmnd, residue); 61 scsi_set_resid(cmnd, residue);
62 if (!sns_len && (scsi_status == SAM_STAT_GOOD) &&
63 (scsi_bufflen(cmnd) - residue) <
64 cmnd->underflow) {
65 bfa_trc(bfad, 0);
66 host_status = DID_ERROR;
67 }
68 }
69 cmnd->result = ScsiResult(host_status, scsi_status);
70
61 break; 71 break;
62 72
63 case BFI_IOIM_STS_ABORTED: 73 case BFI_IOIM_STS_ABORTED:
@@ -167,17 +177,15 @@ bfad_im_info(struct Scsi_Host *shost)
167 static char bfa_buf[256]; 177 static char bfa_buf[256];
168 struct bfad_im_port_s *im_port = 178 struct bfad_im_port_s *im_port =
169 (struct bfad_im_port_s *) shost->hostdata[0]; 179 (struct bfad_im_port_s *) shost->hostdata[0];
170 struct bfa_ioc_attr_s ioc_attr;
171 struct bfad_s *bfad = im_port->bfad; 180 struct bfad_s *bfad = im_port->bfad;
181 char model[BFA_ADAPTER_MODEL_NAME_LEN];
172 182
173 memset(&ioc_attr, 0, sizeof(ioc_attr)); 183 bfa_get_adapter_model(&bfad->bfa, model);
174 bfa_get_attr(&bfad->bfa, &ioc_attr);
175 184
176 memset(bfa_buf, 0, sizeof(bfa_buf)); 185 memset(bfa_buf, 0, sizeof(bfa_buf));
177 snprintf(bfa_buf, sizeof(bfa_buf), 186 snprintf(bfa_buf, sizeof(bfa_buf),
178 "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s", 187 "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
179 ioc_attr.adapter_attr.model, bfad->pci_name, 188 model, bfad->pci_name, BFAD_DRIVER_VERSION);
180 BFAD_DRIVER_VERSION);
181 return bfa_buf; 189 return bfa_buf;
182} 190}
183 191
@@ -501,16 +509,6 @@ void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim)
501} 509}
502 510
503/** 511/**
504 * Path TOV processing begin notification -- dummy for linux
505 */
506void
507bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim)
508{
509}
510
511
512
513/**
514 * Allocate a Scsi_Host for a port. 512 * Allocate a Scsi_Host for a port.
515 */ 513 */
516int 514int
@@ -931,10 +929,9 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
931 struct Scsi_Host *host = im_port->shost; 929 struct Scsi_Host *host = im_port->shost;
932 struct bfad_s *bfad = im_port->bfad; 930 struct bfad_s *bfad = im_port->bfad;
933 struct bfad_port_s *port = im_port->port; 931 struct bfad_port_s *port = im_port->port;
934 union attr { 932 struct bfa_pport_attr_s pattr;
935 struct bfa_pport_attr_s pattr; 933 char model[BFA_ADAPTER_MODEL_NAME_LEN];
936 struct bfa_ioc_attr_s ioc_attr; 934 char fw_ver[BFA_VERSION_LEN];
937 } attr;
938 935
939 fc_host_node_name(host) = 936 fc_host_node_name(host) =
940 bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port))); 937 bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port)));
@@ -954,20 +951,18 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
954 /* For fibre channel services type 0x20 */ 951 /* For fibre channel services type 0x20 */
955 fc_host_supported_fc4s(host)[7] = 1; 952 fc_host_supported_fc4s(host)[7] = 1;
956 953
957 memset(&attr.ioc_attr, 0, sizeof(attr.ioc_attr)); 954 bfa_get_adapter_model(&bfad->bfa, model);
958 bfa_get_attr(&bfad->bfa, &attr.ioc_attr); 955 bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
959 sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s", 956 sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s",
960 attr.ioc_attr.adapter_attr.model, 957 model, fw_ver, BFAD_DRIVER_VERSION);
961 attr.ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
962 958
963 fc_host_supported_speeds(host) = 0; 959 fc_host_supported_speeds(host) = 0;
964 fc_host_supported_speeds(host) |= 960 fc_host_supported_speeds(host) |=
965 FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | 961 FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
966 FC_PORTSPEED_1GBIT; 962 FC_PORTSPEED_1GBIT;
967 963
968 memset(&attr.pattr, 0, sizeof(attr.pattr)); 964 bfa_fcport_get_attr(&bfad->bfa, &pattr);
969 bfa_pport_get_attr(&bfad->bfa, &attr.pattr); 965 fc_host_maxframe_size(host) = pattr.pport_cfg.maxfrsize;
970 fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize;
971} 966}
972 967
973static void 968static void
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
index 189a5b29e21a..85ab2da21321 100644
--- a/drivers/scsi/bfa/bfad_im.h
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -23,7 +23,6 @@
23 23
24#define FCPI_NAME " fcpim" 24#define FCPI_NAME " fcpim"
25 25
26void bfad_flags_set(struct bfad_s *bfad, u32 flags);
27bfa_status_t bfad_im_module_init(void); 26bfa_status_t bfad_im_module_init(void);
28void bfad_im_module_exit(void); 27void bfad_im_module_exit(void);
29bfa_status_t bfad_im_probe(struct bfad_s *bfad); 28bfa_status_t bfad_im_probe(struct bfad_s *bfad);
@@ -126,7 +125,6 @@ bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad);
126void bfad_os_destroy_workq(struct bfad_im_s *im); 125void bfad_os_destroy_workq(struct bfad_im_s *im);
127void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv); 126void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv);
128void bfad_os_fc_host_init(struct bfad_im_port_s *im_port); 127void bfad_os_fc_host_init(struct bfad_im_port_s *im_port);
129void bfad_os_init_work(struct bfad_im_port_s *im_port);
130void bfad_os_scsi_host_free(struct bfad_s *bfad, 128void bfad_os_scsi_host_free(struct bfad_s *bfad,
131 struct bfad_im_port_s *im_port); 129 struct bfad_im_port_s *im_port);
132void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, 130void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim,
@@ -136,9 +134,6 @@ struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id);
136int bfad_os_scsi_add_host(struct Scsi_Host *shost, 134int bfad_os_scsi_add_host(struct Scsi_Host *shost,
137 struct bfad_im_port_s *im_port, struct bfad_s *bfad); 135 struct bfad_im_port_s *im_port, struct bfad_s *bfad);
138 136
139/*
140 * scsi_host_template entries
141 */
142void bfad_im_itnim_unmap(struct bfad_im_port_s *im_port, 137void bfad_im_itnim_unmap(struct bfad_im_port_s *im_port,
143 struct bfad_itnim_s *itnim); 138 struct bfad_itnim_s *itnim);
144 139
diff --git a/drivers/scsi/bfa/bfad_intr.c b/drivers/scsi/bfa/bfad_intr.c
index 7de8832f6fee..2b7dbecbebca 100644
--- a/drivers/scsi/bfa/bfad_intr.c
+++ b/drivers/scsi/bfa/bfad_intr.c
@@ -23,8 +23,10 @@ BFA_TRC_FILE(LDRV, INTR);
23/** 23/**
24 * bfa_isr BFA driver interrupt functions 24 * bfa_isr BFA driver interrupt functions
25 */ 25 */
26static int msix_disable; 26static int msix_disable_cb;
27module_param(msix_disable, int, S_IRUGO | S_IWUSR); 27static int msix_disable_ct;
28module_param(msix_disable_cb, int, S_IRUGO | S_IWUSR);
29module_param(msix_disable_ct, int, S_IRUGO | S_IWUSR);
28/** 30/**
29 * Line based interrupt handler. 31 * Line based interrupt handler.
30 */ 32 */
@@ -141,6 +143,7 @@ bfad_setup_intr(struct bfad_s *bfad)
141 int error = 0; 143 int error = 0;
142 u32 mask = 0, i, num_bit = 0, max_bit = 0; 144 u32 mask = 0, i, num_bit = 0, max_bit = 0;
143 struct msix_entry msix_entries[MAX_MSIX_ENTRY]; 145 struct msix_entry msix_entries[MAX_MSIX_ENTRY];
146 struct pci_dev *pdev = bfad->pcidev;
144 147
145 /* Call BFA to get the msix map for this PCI function. */ 148 /* Call BFA to get the msix map for this PCI function. */
146 bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit); 149 bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit);
@@ -148,7 +151,9 @@ bfad_setup_intr(struct bfad_s *bfad)
148 /* Set up the msix entry table */ 151 /* Set up the msix entry table */
149 bfad_init_msix_entry(bfad, msix_entries, mask, max_bit); 152 bfad_init_msix_entry(bfad, msix_entries, mask, max_bit);
150 153
151 if (!msix_disable) { 154 if ((pdev->device == BFA_PCI_DEVICE_ID_CT && !msix_disable_ct) ||
155 (pdev->device != BFA_PCI_DEVICE_ID_CT && !msix_disable_cb)) {
156
152 error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec); 157 error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
153 if (error) { 158 if (error) {
154 /* 159 /*
diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c
index a4b5dd449573..8166e9745ec0 100644
--- a/drivers/scsi/bfa/fabric.c
+++ b/drivers/scsi/bfa/fabric.c
@@ -37,7 +37,7 @@ BFA_TRC_FILE(FCS, FABRIC);
37#define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */ 37#define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */
38 38
39#define bfa_fcs_fabric_set_opertype(__fabric) do { \ 39#define bfa_fcs_fabric_set_opertype(__fabric) do { \
40 if (bfa_pport_get_topology((__fabric)->fcs->bfa) \ 40 if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \
41 == BFA_PPORT_TOPOLOGY_P2P) \ 41 == BFA_PPORT_TOPOLOGY_P2P) \
42 (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \ 42 (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \
43 else \ 43 else \
@@ -136,8 +136,7 @@ bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
136 case BFA_FCS_FABRIC_SM_CREATE: 136 case BFA_FCS_FABRIC_SM_CREATE:
137 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created); 137 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
138 bfa_fcs_fabric_init(fabric); 138 bfa_fcs_fabric_init(fabric);
139 bfa_fcs_lport_init(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, 139 bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
140 &fabric->bport.port_cfg, NULL);
141 break; 140 break;
142 141
143 case BFA_FCS_FABRIC_SM_LINK_UP: 142 case BFA_FCS_FABRIC_SM_LINK_UP:
@@ -161,7 +160,7 @@ bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
161 160
162 switch (event) { 161 switch (event) {
163 case BFA_FCS_FABRIC_SM_START: 162 case BFA_FCS_FABRIC_SM_START:
164 if (bfa_pport_is_linkup(fabric->fcs->bfa)) { 163 if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
165 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); 164 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
166 bfa_fcs_fabric_login(fabric); 165 bfa_fcs_fabric_login(fabric);
167 } else 166 } else
@@ -225,7 +224,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
225 switch (event) { 224 switch (event) {
226 case BFA_FCS_FABRIC_SM_CONT_OP: 225 case BFA_FCS_FABRIC_SM_CONT_OP:
227 226
228 bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); 227 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
229 fabric->fab_type = BFA_FCS_FABRIC_SWITCHED; 228 fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
230 229
231 if (fabric->auth_reqd && fabric->is_auth) { 230 if (fabric->auth_reqd && fabric->is_auth) {
@@ -252,7 +251,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
252 251
253 case BFA_FCS_FABRIC_SM_NO_FABRIC: 252 case BFA_FCS_FABRIC_SM_NO_FABRIC:
254 fabric->fab_type = BFA_FCS_FABRIC_N2N; 253 fabric->fab_type = BFA_FCS_FABRIC_N2N;
255 bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); 254 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
256 bfa_fcs_fabric_notify_online(fabric); 255 bfa_fcs_fabric_notify_online(fabric);
257 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric); 256 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
258 break; 257 break;
@@ -419,7 +418,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
419 418
420 case BFA_FCS_FABRIC_SM_NO_FABRIC: 419 case BFA_FCS_FABRIC_SM_NO_FABRIC:
421 bfa_trc(fabric->fcs, fabric->bb_credit); 420 bfa_trc(fabric->fcs, fabric->bb_credit);
422 bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); 421 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
423 break; 422 break;
424 423
425 default: 424 default:
@@ -563,17 +562,15 @@ void
563bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric) 562bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
564{ 563{
565 struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg; 564 struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
566 struct bfa_adapter_attr_s adapter_attr; 565 char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
567 struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info; 566 struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
568 567
569 bfa_os_memset((void *)&adapter_attr, 0, 568 bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
570 sizeof(struct bfa_adapter_attr_s));
571 bfa_ioc_get_adapter_attr(&fabric->fcs->bfa->ioc, &adapter_attr);
572 569
573 /* 570 /*
574 * Model name/number 571 * Model name/number
575 */ 572 */
576 strncpy((char *)&port_cfg->sym_name, adapter_attr.model, 573 strncpy((char *)&port_cfg->sym_name, model,
577 BFA_FCS_PORT_SYMBNAME_MODEL_SZ); 574 BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
578 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, 575 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
579 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); 576 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
@@ -719,10 +716,10 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
719 struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg; 716 struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
720 u8 alpa = 0; 717 u8 alpa = 0;
721 718
722 if (bfa_pport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP) 719 if (bfa_fcport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
723 alpa = bfa_pport_get_myalpa(bfa); 720 alpa = bfa_fcport_get_myalpa(bfa);
724 721
725 bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_pport_get_maxfrsize(bfa), 722 bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
726 pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd); 723 pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
727 724
728 fabric->stats.flogi_sent++; 725 fabric->stats.flogi_sent++;
@@ -814,10 +811,10 @@ bfa_fcs_fabric_delete_comp(void *cbarg)
814 */ 811 */
815 812
816/** 813/**
817 * Module initialization 814 * Attach time initialization
818 */ 815 */
819void 816void
820bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs) 817bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
821{ 818{
822 struct bfa_fcs_fabric_s *fabric; 819 struct bfa_fcs_fabric_s *fabric;
823 820
@@ -841,7 +838,13 @@ bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
841 bfa_wc_up(&fabric->wc); /* For the base port */ 838 bfa_wc_up(&fabric->wc); /* For the base port */
842 839
843 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit); 840 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
844 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CREATE); 841 bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
842}
843
844void
845bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
846{
847 bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
845 bfa_trc(fcs, 0); 848 bfa_trc(fcs, 0);
846} 849}
847 850
@@ -890,6 +893,12 @@ bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
890 return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback); 893 return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback);
891} 894}
892 895
896bfa_boolean_t
897bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric)
898{
899 return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_auth_failed);
900}
901
893enum bfa_pport_type 902enum bfa_pport_type
894bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric) 903bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
895{ 904{
@@ -1165,8 +1174,8 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1165 reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), 1174 reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1166 bfa_os_hton3b(FC_FABRIC_PORT), 1175 bfa_os_hton3b(FC_FABRIC_PORT),
1167 n2n_port->reply_oxid, pcfg->pwwn, 1176 n2n_port->reply_oxid, pcfg->pwwn,
1168 pcfg->nwwn, bfa_pport_get_maxfrsize(bfa), 1177 pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa),
1169 bfa_pport_get_rx_bbcredit(bfa)); 1178 bfa_fcport_get_rx_bbcredit(bfa));
1170 1179
1171 bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps), 1180 bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps),
1172 BFA_FALSE, FC_CLASS_3, reqlen, &fchs, 1181 BFA_FALSE, FC_CLASS_3, reqlen, &fchs,
@@ -1224,14 +1233,8 @@ bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port,
1224 wwn2str(pwwn_ptr, pwwn); 1233 wwn2str(pwwn_ptr, pwwn);
1225 wwn2str(fwwn_ptr, fwwn); 1234 wwn2str(fwwn_ptr, fwwn);
1226 1235
1227 switch (event) { 1236 bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event),
1228 case BFA_PORT_AEN_FABRIC_NAME_CHANGE: 1237 pwwn_ptr, fwwn_ptr);
1229 bfa_log(logmod, BFA_AEN_PORT_FABRIC_NAME_CHANGE, pwwn_ptr,
1230 fwwn_ptr);
1231 break;
1232 default:
1233 break;
1234 }
1235 1238
1236 aen_data.port.pwwn = pwwn; 1239 aen_data.port.pwwn = pwwn;
1237 aen_data.port.fwwn = fwwn; 1240 aen_data.port.fwwn = fwwn;
diff --git a/drivers/scsi/bfa/fcbuild.h b/drivers/scsi/bfa/fcbuild.h
index 8fa7f270ef7b..981d98d542b9 100644
--- a/drivers/scsi/bfa/fcbuild.h
+++ b/drivers/scsi/bfa/fcbuild.h
@@ -72,6 +72,9 @@ fc_rpsc_operspeed_to_bfa_speed(enum fc_rpsc_op_speed_s speed)
72 case RPSC_OP_SPEED_8G: 72 case RPSC_OP_SPEED_8G:
73 return BFA_PPORT_SPEED_8GBPS; 73 return BFA_PPORT_SPEED_8GBPS;
74 74
75 case RPSC_OP_SPEED_10G:
76 return BFA_PPORT_SPEED_10GBPS;
77
75 default: 78 default:
76 return BFA_PPORT_SPEED_UNKNOWN; 79 return BFA_PPORT_SPEED_UNKNOWN;
77 } 80 }
@@ -97,6 +100,9 @@ fc_bfa_speed_to_rpsc_operspeed(enum bfa_pport_speed op_speed)
97 case BFA_PPORT_SPEED_8GBPS: 100 case BFA_PPORT_SPEED_8GBPS:
98 return RPSC_OP_SPEED_8G; 101 return RPSC_OP_SPEED_8G;
99 102
103 case BFA_PPORT_SPEED_10GBPS:
104 return RPSC_OP_SPEED_10G;
105
100 default: 106 default:
101 return RPSC_OP_SPEED_NOT_EST; 107 return RPSC_OP_SPEED_NOT_EST;
102 } 108 }
diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c
index 1f3c06efaa9e..8ae4a2cfa85b 100644
--- a/drivers/scsi/bfa/fcpim.c
+++ b/drivers/scsi/bfa/fcpim.c
@@ -126,7 +126,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
126 break; 126 break;
127 127
128 default: 128 default:
129 bfa_assert(0); 129 bfa_sm_fault(itnim->fcs, event);
130 } 130 }
131 131
132} 132}
@@ -161,7 +161,7 @@ bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
161 break; 161 break;
162 162
163 default: 163 default:
164 bfa_assert(0); 164 bfa_sm_fault(itnim->fcs, event);
165 } 165 }
166} 166}
167 167
@@ -205,7 +205,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
205 break; 205 break;
206 206
207 default: 207 default:
208 bfa_assert(0); 208 bfa_sm_fault(itnim->fcs, event);
209 } 209 }
210} 210}
211 211
@@ -240,7 +240,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
240 break; 240 break;
241 241
242 default: 242 default:
243 bfa_assert(0); 243 bfa_sm_fault(itnim->fcs, event);
244 } 244 }
245} 245}
246 246
@@ -270,7 +270,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
270 break; 270 break;
271 271
272 default: 272 default:
273 bfa_assert(0); 273 bfa_sm_fault(itnim->fcs, event);
274 } 274 }
275} 275}
276 276
@@ -298,7 +298,7 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
298 break; 298 break;
299 299
300 default: 300 default:
301 bfa_assert(0); 301 bfa_sm_fault(itnim->fcs, event);
302 } 302 }
303} 303}
304 304
@@ -321,7 +321,7 @@ bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
321 break; 321 break;
322 322
323 default: 323 default:
324 bfa_assert(0); 324 bfa_sm_fault(itnim->fcs, event);
325 } 325 }
326} 326}
327 327
@@ -354,7 +354,7 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
354 break; 354 break;
355 355
356 default: 356 default:
357 bfa_assert(0); 357 bfa_sm_fault(itnim->fcs, event);
358 } 358 }
359} 359}
360 360
@@ -385,19 +385,8 @@ bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
385 wwn2str(lpwwn_ptr, lpwwn); 385 wwn2str(lpwwn_ptr, lpwwn);
386 wwn2str(rpwwn_ptr, rpwwn); 386 wwn2str(rpwwn_ptr, rpwwn);
387 387
388 switch (event) { 388 bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, event),
389 case BFA_ITNIM_AEN_ONLINE: 389 rpwwn_ptr, lpwwn_ptr);
390 bfa_log(logmod, BFA_AEN_ITNIM_ONLINE, rpwwn_ptr, lpwwn_ptr);
391 break;
392 case BFA_ITNIM_AEN_OFFLINE:
393 bfa_log(logmod, BFA_AEN_ITNIM_OFFLINE, rpwwn_ptr, lpwwn_ptr);
394 break;
395 case BFA_ITNIM_AEN_DISCONNECT:
396 bfa_log(logmod, BFA_AEN_ITNIM_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
397 break;
398 default:
399 break;
400 }
401 390
402 aen_data.itnim.vf_id = rport->port->fabric->vf_id; 391 aen_data.itnim.vf_id = rport->port->fabric->vf_id;
403 aen_data.itnim.ppwwn = 392 aen_data.itnim.ppwwn =
@@ -689,7 +678,6 @@ bfa_cb_itnim_tov_begin(void *cb_arg)
689 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg; 678 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
690 679
691 bfa_trc(itnim->fcs, itnim->rport->pwwn); 680 bfa_trc(itnim->fcs, itnim->rport->pwwn);
692 bfa_fcb_itnim_tov_begin(itnim->itnim_drv);
693} 681}
694 682
695/** 683/**
@@ -822,22 +810,3 @@ void
822bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim) 810bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim)
823{ 811{
824} 812}
825
826/**
827 * Module initialization
828 */
829void
830bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs)
831{
832}
833
834/**
835 * Module cleanup
836 */
837void
838bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs)
839{
840 bfa_fcs_modexit_comp(fcs);
841}
842
843
diff --git a/drivers/scsi/bfa/fcs_fabric.h b/drivers/scsi/bfa/fcs_fabric.h
index eee960820f86..244c3f00c50c 100644
--- a/drivers/scsi/bfa/fcs_fabric.h
+++ b/drivers/scsi/bfa/fcs_fabric.h
@@ -29,6 +29,7 @@
29/* 29/*
30* fcs friend functions: only between fcs modules 30* fcs friend functions: only between fcs modules
31 */ 31 */
32void bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs);
32void bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs); 33void bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs);
33void bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs); 34void bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs);
34void bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs); 35void bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs);
@@ -46,6 +47,7 @@ void bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric,
46 struct fchs_s *fchs, u16 len); 47 struct fchs_s *fchs, u16 len);
47u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric); 48u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
48bfa_boolean_t bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric); 49bfa_boolean_t bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric);
50bfa_boolean_t bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric);
49enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric); 51enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric);
50void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric); 52void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric);
51void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric); 53void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric);
diff --git a/drivers/scsi/bfa/fcs_fcpim.h b/drivers/scsi/bfa/fcs_fcpim.h
index 61e9e2687de3..11e6e7bce9f6 100644
--- a/drivers/scsi/bfa/fcs_fcpim.h
+++ b/drivers/scsi/bfa/fcs_fcpim.h
@@ -34,11 +34,6 @@ void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim);
34void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim); 34void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim);
35void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim); 35void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim);
36 36
37/*
38 * Modudle init/cleanup routines.
39 */
40void bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs);
41void bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs);
42void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs, 37void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs,
43 u16 len); 38 u16 len);
44#endif /* __FCS_FCPIM_H__ */ 39#endif /* __FCS_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/fcs_lport.h b/drivers/scsi/bfa/fcs_lport.h
index ae744ba35671..a6508c8ab184 100644
--- a/drivers/scsi/bfa/fcs_lport.h
+++ b/drivers/scsi/bfa/fcs_lport.h
@@ -84,9 +84,10 @@ void bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs,
84 * Following routines will be called by Fabric to indicate port 84 * Following routines will be called by Fabric to indicate port
85 * online/offline to vport. 85 * online/offline to vport.
86 */ 86 */
87void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, 87void bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
88 u16 vf_id, struct bfa_port_cfg_s *port_cfg, 88 uint16_t vf_id, struct bfa_fcs_vport_s *vport);
89 struct bfa_fcs_vport_s *vport); 89void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
90 struct bfa_port_cfg_s *port_cfg);
90void bfa_fcs_port_online(struct bfa_fcs_port_s *port); 91void bfa_fcs_port_online(struct bfa_fcs_port_s *port);
91void bfa_fcs_port_offline(struct bfa_fcs_port_s *port); 92void bfa_fcs_port_offline(struct bfa_fcs_port_s *port);
92void bfa_fcs_port_delete(struct bfa_fcs_port_s *port); 93void bfa_fcs_port_delete(struct bfa_fcs_port_s *port);
diff --git a/drivers/scsi/bfa/fcs_port.h b/drivers/scsi/bfa/fcs_port.h
index abb65191dd27..408c06a7d164 100644
--- a/drivers/scsi/bfa/fcs_port.h
+++ b/drivers/scsi/bfa/fcs_port.h
@@ -26,7 +26,6 @@
26/* 26/*
27 * fcs friend functions: only between fcs modules 27 * fcs friend functions: only between fcs modules
28 */ 28 */
29void bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs); 29void bfa_fcs_pport_attach(struct bfa_fcs_s *fcs);
30void bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs);
31 30
32#endif /* __FCS_PPORT_H__ */ 31#endif /* __FCS_PPORT_H__ */
diff --git a/drivers/scsi/bfa/fcs_rport.h b/drivers/scsi/bfa/fcs_rport.h
index f601e9d74236..9c8d1d292380 100644
--- a/drivers/scsi/bfa/fcs_rport.h
+++ b/drivers/scsi/bfa/fcs_rport.h
@@ -24,9 +24,6 @@
24 24
25#include <fcs/bfa_fcs_rport.h> 25#include <fcs/bfa_fcs_rport.h>
26 26
27void bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs);
28void bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs);
29
30void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs, 27void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
31 u16 len); 28 u16 len);
32void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport); 29void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport);
diff --git a/drivers/scsi/bfa/fcs_uf.h b/drivers/scsi/bfa/fcs_uf.h
index 96f1bdcb31ed..f591072214fe 100644
--- a/drivers/scsi/bfa/fcs_uf.h
+++ b/drivers/scsi/bfa/fcs_uf.h
@@ -26,7 +26,6 @@
26/* 26/*
27 * fcs friend functions: only between fcs modules 27 * fcs friend functions: only between fcs modules
28 */ 28 */
29void bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs); 29void bfa_fcs_uf_attach(struct bfa_fcs_s *fcs);
30void bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs);
31 30
32#endif /* __FCS_UF_H__ */ 31#endif /* __FCS_UF_H__ */
diff --git a/drivers/scsi/bfa/fcs_vport.h b/drivers/scsi/bfa/fcs_vport.h
index 9e80b6a97b7f..13c32ebf946c 100644
--- a/drivers/scsi/bfa/fcs_vport.h
+++ b/drivers/scsi/bfa/fcs_vport.h
@@ -22,18 +22,10 @@
22#include <fcs/bfa_fcs_vport.h> 22#include <fcs/bfa_fcs_vport.h>
23#include <defs/bfa_defs_pci.h> 23#include <defs/bfa_defs_pci.h>
24 24
25/*
26 * Modudle init/cleanup routines.
27 */
28
29void bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs);
30void bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs);
31
32void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport); 25void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport);
33void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport); 26void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport);
34void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport); 27void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport);
35void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport); 28void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport);
36u32 bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs);
37 29
38#endif /* __FCS_VPORT_H__ */ 30#endif /* __FCS_VPORT_H__ */
39 31
diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c
index df2a1e54e16b..8f17076d1a87 100644
--- a/drivers/scsi/bfa/fdmi.c
+++ b/drivers/scsi/bfa/fdmi.c
@@ -116,6 +116,9 @@ static void bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
116 enum port_fdmi_event event); 116 enum port_fdmi_event event);
117static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, 117static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
118 enum port_fdmi_event event); 118 enum port_fdmi_event event);
119static void bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi,
120 enum port_fdmi_event event);
121
119/** 122/**
120 * Start in offline state - awaiting MS to send start. 123 * Start in offline state - awaiting MS to send start.
121 */ 124 */
@@ -155,7 +158,7 @@ bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
155 break; 158 break;
156 159
157 default: 160 default:
158 bfa_assert(0); 161 bfa_sm_fault(port->fcs, event);
159 } 162 }
160} 163}
161 164
@@ -180,7 +183,7 @@ bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
180 break; 183 break;
181 184
182 default: 185 default:
183 bfa_assert(0); 186 bfa_sm_fault(port->fcs, event);
184 } 187 }
185} 188}
186 189
@@ -227,7 +230,7 @@ bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
227 break; 230 break;
228 231
229 default: 232 default:
230 bfa_assert(0); 233 bfa_sm_fault(port->fcs, event);
231 } 234 }
232} 235}
233 236
@@ -255,7 +258,7 @@ bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
255 break; 258 break;
256 259
257 default: 260 default:
258 bfa_assert(0); 261 bfa_sm_fault(port->fcs, event);
259 } 262 }
260} 263}
261 264
@@ -283,7 +286,7 @@ bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
283 break; 286 break;
284 287
285 default: 288 default:
286 bfa_assert(0); 289 bfa_sm_fault(port->fcs, event);
287 } 290 }
288} 291}
289 292
@@ -328,7 +331,7 @@ bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
328 break; 331 break;
329 332
330 default: 333 default:
331 bfa_assert(0); 334 bfa_sm_fault(port->fcs, event);
332 } 335 }
333} 336}
334 337
@@ -356,7 +359,7 @@ bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
356 break; 359 break;
357 360
358 default: 361 default:
359 bfa_assert(0); 362 bfa_sm_fault(port->fcs, event);
360 } 363 }
361} 364}
362 365
@@ -384,7 +387,7 @@ bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
384 break; 387 break;
385 388
386 default: 389 default:
387 bfa_assert(0); 390 bfa_sm_fault(port->fcs, event);
388 } 391 }
389} 392}
390 393
@@ -428,7 +431,7 @@ bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
428 break; 431 break;
429 432
430 default: 433 default:
431 bfa_assert(0); 434 bfa_sm_fault(port->fcs, event);
432 } 435 }
433} 436}
434 437
@@ -456,7 +459,7 @@ bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
456 break; 459 break;
457 460
458 default: 461 default:
459 bfa_assert(0); 462 bfa_sm_fault(port->fcs, event);
460 } 463 }
461} 464}
462 465
@@ -475,10 +478,24 @@ bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
475 break; 478 break;
476 479
477 default: 480 default:
478 bfa_assert(0); 481 bfa_sm_fault(port->fcs, event);
479 } 482 }
480} 483}
481 484
485/**
486 * FDMI is disabled state.
487 */
488static void
489bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi,
490 enum port_fdmi_event event)
491{
492 struct bfa_fcs_port_s *port = fdmi->ms->port;
493
494 bfa_trc(port->fcs, port->port_cfg.pwwn);
495 bfa_trc(port->fcs, event);
496
497 /* No op State. It can only be enabled at Driver Init. */
498}
482 499
483/** 500/**
484* RHBA : Register HBA Attributes. 501* RHBA : Register HBA Attributes.
@@ -1097,36 +1114,23 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
1097{ 1114{
1098 struct bfa_fcs_port_s *port = fdmi->ms->port; 1115 struct bfa_fcs_port_s *port = fdmi->ms->port;
1099 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; 1116 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
1100 struct bfa_adapter_attr_s adapter_attr;
1101 1117
1102 bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); 1118 bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
1103 bfa_os_memset(&adapter_attr, 0, sizeof(struct bfa_adapter_attr_s));
1104
1105 bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr);
1106
1107 strncpy(hba_attr->manufacturer, adapter_attr.manufacturer,
1108 sizeof(adapter_attr.manufacturer));
1109
1110 strncpy(hba_attr->serial_num, adapter_attr.serial_num,
1111 sizeof(adapter_attr.serial_num));
1112 1119
1113 strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model)); 1120 bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
1114 1121 hba_attr->manufacturer);
1115 strncpy(hba_attr->model_desc, adapter_attr.model_descr, 1122 bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
1116 sizeof(hba_attr->model_desc)); 1123 hba_attr->serial_num);
1117 1124 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model);
1118 strncpy(hba_attr->hw_version, adapter_attr.hw_ver, 1125 bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model_desc);
1119 sizeof(hba_attr->hw_version)); 1126 bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, hba_attr->hw_version);
1127 bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
1128 hba_attr->option_rom_ver);
1129 bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, hba_attr->fw_version);
1120 1130
1121 strncpy(hba_attr->driver_version, (char *)driver_info->version, 1131 strncpy(hba_attr->driver_version, (char *)driver_info->version,
1122 sizeof(hba_attr->driver_version)); 1132 sizeof(hba_attr->driver_version));
1123 1133
1124 strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver,
1125 sizeof(hba_attr->option_rom_ver));
1126
1127 strncpy(hba_attr->fw_version, adapter_attr.fw_ver,
1128 sizeof(hba_attr->fw_version));
1129
1130 strncpy(hba_attr->os_name, driver_info->host_os_name, 1134 strncpy(hba_attr->os_name, driver_info->host_os_name,
1131 sizeof(hba_attr->os_name)); 1135 sizeof(hba_attr->os_name));
1132 1136
@@ -1158,7 +1162,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
1158 /* 1162 /*
1159 * get pport attributes from hal 1163 * get pport attributes from hal
1160 */ 1164 */
1161 bfa_pport_get_attr(port->fcs->bfa, &pport_attr); 1165 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
1162 1166
1163 /* 1167 /*
1164 * get FC4 type Bitmask 1168 * get FC4 type Bitmask
@@ -1201,7 +1205,10 @@ bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms)
1201 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi; 1205 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1202 1206
1203 fdmi->ms = ms; 1207 fdmi->ms = ms;
1204 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); 1208 if (ms->port->fcs->fdmi_enabled)
1209 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
1210 else
1211 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_disabled);
1205} 1212}
1206 1213
1207void 1214void
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen.h b/drivers/scsi/bfa/include/aen/bfa_aen.h
index d9cbc2a783d4..6abbab005db6 100644
--- a/drivers/scsi/bfa/include/aen/bfa_aen.h
+++ b/drivers/scsi/bfa/include/aen/bfa_aen.h
@@ -18,21 +18,24 @@
18#define __BFA_AEN_H__ 18#define __BFA_AEN_H__
19 19
20#include "defs/bfa_defs_aen.h" 20#include "defs/bfa_defs_aen.h"
21#include "defs/bfa_defs_status.h"
22#include "cs/bfa_debug.h"
21 23
22#define BFA_AEN_MAX_ENTRY 512 24#define BFA_AEN_MAX_ENTRY 512
23 25
24extern s32 bfa_aen_max_cfg_entry; 26extern int bfa_aen_max_cfg_entry;
25struct bfa_aen_s { 27struct bfa_aen_s {
26 void *bfad; 28 void *bfad;
27 s32 max_entry; 29 int max_entry;
28 s32 write_index; 30 int write_index;
29 s32 read_index; 31 int read_index;
30 u32 bfad_num; 32 int bfad_num;
31 u32 seq_num; 33 int seq_num;
32 void (*aen_cb_notify)(void *bfad); 34 void (*aen_cb_notify)(void *bfad);
33 void (*gettimeofday)(struct bfa_timeval_s *tv); 35 void (*gettimeofday)(struct bfa_timeval_s *tv);
34 struct bfa_trc_mod_s *trcmod; 36 struct bfa_trc_mod_s *trcmod;
35 struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */ 37 int app_ri[BFA_AEN_MAX_APP]; /* For multiclient support */
38 struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */
36}; 39};
37 40
38 41
@@ -45,48 +48,49 @@ bfa_aen_set_max_cfg_entry(int max_entry)
45 bfa_aen_max_cfg_entry = max_entry; 48 bfa_aen_max_cfg_entry = max_entry;
46} 49}
47 50
48static inline s32 51static inline int
49bfa_aen_get_max_cfg_entry(void) 52bfa_aen_get_max_cfg_entry(void)
50{ 53{
51 return bfa_aen_max_cfg_entry; 54 return bfa_aen_max_cfg_entry;
52} 55}
53 56
54static inline s32 57static inline int
55bfa_aen_get_meminfo(void) 58bfa_aen_get_meminfo(void)
56{ 59{
57 return sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry(); 60 return sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry();
58} 61}
59 62
60static inline s32 63static inline int
61bfa_aen_get_wi(struct bfa_aen_s *aen) 64bfa_aen_get_wi(struct bfa_aen_s *aen)
62{ 65{
63 return aen->write_index; 66 return aen->write_index;
64} 67}
65 68
66static inline s32 69static inline int
67bfa_aen_get_ri(struct bfa_aen_s *aen) 70bfa_aen_get_ri(struct bfa_aen_s *aen)
68{ 71{
69 return aen->read_index; 72 return aen->read_index;
70} 73}
71 74
72static inline s32 75static inline int
73bfa_aen_fetch_count(struct bfa_aen_s *aen, s32 read_index) 76bfa_aen_fetch_count(struct bfa_aen_s *aen, enum bfa_aen_app app_id)
74{ 77{
75 return ((aen->write_index + aen->max_entry) - read_index) 78 bfa_assert((app_id < BFA_AEN_MAX_APP) && (app_id >= bfa_aen_app_bcu));
79 return ((aen->write_index + aen->max_entry) - aen->app_ri[app_id])
76 % aen->max_entry; 80 % aen->max_entry;
77} 81}
78 82
79s32 bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod, 83int bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod,
80 void *bfad, u32 inst_id, void (*aen_cb_notify)(void *), 84 void *bfad, int bfad_num, void (*aen_cb_notify)(void *),
81 void (*gettimeofday)(struct bfa_timeval_s *)); 85 void (*gettimeofday)(struct bfa_timeval_s *));
82 86
83s32 bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category, 87void bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category,
84 int aen_type, union bfa_aen_data_u *aen_data); 88 int aen_type, union bfa_aen_data_u *aen_data);
85 89
86s32 bfa_aen_fetch(struct bfa_aen_s *aen, struct bfa_aen_entry_s *aen_entry, 90bfa_status_t bfa_aen_fetch(struct bfa_aen_s *aen,
87 s32 entry_space, s32 rii, s32 *ri_arr, 91 struct bfa_aen_entry_s *aen_entry,
88 s32 ri_arr_cnt); 92 int entry_req, enum bfa_aen_app app_id, int *entry_ret);
89 93
90s32 bfa_aen_get_inst(struct bfa_aen_s *aen); 94int bfa_aen_get_inst(struct bfa_aen_s *aen);
91 95
92#endif /* __BFA_AEN_H__ */ 96#endif /* __BFA_AEN_H__ */
diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h
index d4bc0d9fa42c..1f5966cfbd16 100644
--- a/drivers/scsi/bfa/include/bfa.h
+++ b/drivers/scsi/bfa/include/bfa.h
@@ -106,6 +106,26 @@ struct bfa_sge_s {
106 bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats) 106 bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats)
107#define bfa_ioc_clear_stats(__bfa) \ 107#define bfa_ioc_clear_stats(__bfa) \
108 bfa_ioc_clr_stats(&(__bfa)->ioc) 108 bfa_ioc_clr_stats(&(__bfa)->ioc)
109#define bfa_get_nports(__bfa) \
110 bfa_ioc_get_nports(&(__bfa)->ioc)
111#define bfa_get_adapter_manufacturer(__bfa, __manufacturer) \
112 bfa_ioc_get_adapter_manufacturer(&(__bfa)->ioc, __manufacturer)
113#define bfa_get_adapter_model(__bfa, __model) \
114 bfa_ioc_get_adapter_model(&(__bfa)->ioc, __model)
115#define bfa_get_adapter_serial_num(__bfa, __serial_num) \
116 bfa_ioc_get_adapter_serial_num(&(__bfa)->ioc, __serial_num)
117#define bfa_get_adapter_fw_ver(__bfa, __fw_ver) \
118 bfa_ioc_get_adapter_fw_ver(&(__bfa)->ioc, __fw_ver)
119#define bfa_get_adapter_optrom_ver(__bfa, __optrom_ver) \
120 bfa_ioc_get_adapter_optrom_ver(&(__bfa)->ioc, __optrom_ver)
121#define bfa_get_pci_chip_rev(__bfa, __chip_rev) \
122 bfa_ioc_get_pci_chip_rev(&(__bfa)->ioc, __chip_rev)
123#define bfa_get_ioc_state(__bfa) \
124 bfa_ioc_get_state(&(__bfa)->ioc)
125#define bfa_get_type(__bfa) \
126 bfa_ioc_get_type(&(__bfa)->ioc)
127#define bfa_get_mac(__bfa) \
128 bfa_ioc_get_mac(&(__bfa)->ioc)
109 129
110/* 130/*
111 * bfa API functions 131 * bfa API functions
@@ -161,6 +181,7 @@ bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa,
161void bfa_iocfc_enable(struct bfa_s *bfa); 181void bfa_iocfc_enable(struct bfa_s *bfa);
162void bfa_iocfc_disable(struct bfa_s *bfa); 182void bfa_iocfc_disable(struct bfa_s *bfa);
163void bfa_ioc_auto_recover(bfa_boolean_t auto_recover); 183void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
184void bfa_chip_reset(struct bfa_s *bfa);
164void bfa_cb_ioc_disable(void *bfad); 185void bfa_cb_ioc_disable(void *bfad);
165void bfa_timer_tick(struct bfa_s *bfa); 186void bfa_timer_tick(struct bfa_s *bfa);
166#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \ 187#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \
@@ -171,6 +192,7 @@ void bfa_timer_tick(struct bfa_s *bfa);
171 */ 192 */
172bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen); 193bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen);
173bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen); 194bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen);
195void bfa_debug_fwsave_clear(struct bfa_s *bfa);
174 196
175#include "bfa_priv.h" 197#include "bfa_priv.h"
176 198
diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h
index 268d956bad89..1349b99a3c6d 100644
--- a/drivers/scsi/bfa/include/bfa_svc.h
+++ b/drivers/scsi/bfa/include/bfa_svc.h
@@ -26,6 +26,7 @@ struct bfa_fcxp_s;
26#include <defs/bfa_defs_pport.h> 26#include <defs/bfa_defs_pport.h>
27#include <defs/bfa_defs_rport.h> 27#include <defs/bfa_defs_rport.h>
28#include <defs/bfa_defs_qos.h> 28#include <defs/bfa_defs_qos.h>
29#include <defs/bfa_defs_fcport.h>
29#include <cs/bfa_sm.h> 30#include <cs/bfa_sm.h>
30#include <bfa.h> 31#include <bfa.h>
31 32
@@ -35,7 +36,7 @@ struct bfa_fcxp_s;
35struct bfa_rport_info_s { 36struct bfa_rport_info_s {
36 u16 max_frmsz; /* max rcv pdu size */ 37 u16 max_frmsz; /* max rcv pdu size */
37 u32 pid:24, /* remote port ID */ 38 u32 pid:24, /* remote port ID */
38 lp_tag:8; 39 lp_tag:8; /* tag */
39 u32 local_pid:24, /* local port ID */ 40 u32 local_pid:24, /* local port ID */
40 cisc:8; /* CIRO supported */ 41 cisc:8; /* CIRO supported */
41 u8 fc_class; /* supported FC classes. enum fc_cos */ 42 u8 fc_class; /* supported FC classes. enum fc_cos */
@@ -54,7 +55,7 @@ struct bfa_rport_s {
54 void *rport_drv; /* fcs/driver rport object */ 55 void *rport_drv; /* fcs/driver rport object */
55 u16 fw_handle; /* firmware rport handle */ 56 u16 fw_handle; /* firmware rport handle */
56 u16 rport_tag; /* BFA rport tag */ 57 u16 rport_tag; /* BFA rport tag */
57 struct bfa_rport_info_s rport_info; /* rport info from *fcs/driver */ 58 struct bfa_rport_info_s rport_info; /* rport info from fcs/driver */
58 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ 59 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
59 struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */ 60 struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */
60 struct bfa_rport_hal_stats_s stats; /* BFA rport statistics */ 61 struct bfa_rport_hal_stats_s stats; /* BFA rport statistics */
@@ -101,7 +102,7 @@ struct bfa_uf_buf_s {
101struct bfa_uf_s { 102struct bfa_uf_s {
102 struct list_head qe; /* queue element */ 103 struct list_head qe; /* queue element */
103 struct bfa_s *bfa; /* bfa instance */ 104 struct bfa_s *bfa; /* bfa instance */
104 u16 uf_tag; /* identifying tag f/w messages */ 105 u16 uf_tag; /* identifying tag fw msgs */
105 u16 vf_id; 106 u16 vf_id;
106 u16 src_rport_handle; 107 u16 src_rport_handle;
107 u16 rsvd; 108 u16 rsvd;
@@ -127,7 +128,7 @@ struct bfa_lps_s {
127 u8 reqq; /* lport request queue */ 128 u8 reqq; /* lport request queue */
128 u8 alpa; /* ALPA for loop topologies */ 129 u8 alpa; /* ALPA for loop topologies */
129 u32 lp_pid; /* lport port ID */ 130 u32 lp_pid; /* lport port ID */
130 bfa_boolean_t fdisc; /* send FDISC instead of FLOGI*/ 131 bfa_boolean_t fdisc; /* send FDISC instead of FLOGI */
131 bfa_boolean_t auth_en; /* enable authentication */ 132 bfa_boolean_t auth_en; /* enable authentication */
132 bfa_boolean_t auth_req; /* authentication required */ 133 bfa_boolean_t auth_req; /* authentication required */
133 bfa_boolean_t npiv_en; /* NPIV is allowed by peer */ 134 bfa_boolean_t npiv_en; /* NPIV is allowed by peer */
@@ -151,60 +152,69 @@ struct bfa_lps_s {
151 bfa_eproto_status_t ext_status; 152 bfa_eproto_status_t ext_status;
152}; 153};
153 154
155#define BFA_FCPORT(_bfa) (&((_bfa)->modules.port))
156
154/* 157/*
155 * bfa pport API functions 158 * bfa pport API functions
156 */ 159 */
157bfa_status_t bfa_pport_enable(struct bfa_s *bfa); 160bfa_status_t bfa_fcport_enable(struct bfa_s *bfa);
158bfa_status_t bfa_pport_disable(struct bfa_s *bfa); 161bfa_status_t bfa_fcport_disable(struct bfa_s *bfa);
159bfa_status_t bfa_pport_cfg_speed(struct bfa_s *bfa, 162bfa_status_t bfa_fcport_cfg_speed(struct bfa_s *bfa,
160 enum bfa_pport_speed speed); 163 enum bfa_pport_speed speed);
161enum bfa_pport_speed bfa_pport_get_speed(struct bfa_s *bfa); 164enum bfa_pport_speed bfa_fcport_get_speed(struct bfa_s *bfa);
162bfa_status_t bfa_pport_cfg_topology(struct bfa_s *bfa, 165bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa,
163 enum bfa_pport_topology topo); 166 enum bfa_pport_topology topo);
164enum bfa_pport_topology bfa_pport_get_topology(struct bfa_s *bfa); 167enum bfa_pport_topology bfa_fcport_get_topology(struct bfa_s *bfa);
165bfa_status_t bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa); 168bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
166bfa_boolean_t bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa); 169bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
167u8 bfa_pport_get_myalpa(struct bfa_s *bfa); 170u8 bfa_fcport_get_myalpa(struct bfa_s *bfa);
168bfa_status_t bfa_pport_clr_hardalpa(struct bfa_s *bfa); 171bfa_status_t bfa_fcport_clr_hardalpa(struct bfa_s *bfa);
169bfa_status_t bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize); 172bfa_status_t bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize);
170u16 bfa_pport_get_maxfrsize(struct bfa_s *bfa); 173u16 bfa_fcport_get_maxfrsize(struct bfa_s *bfa);
171u32 bfa_pport_mypid(struct bfa_s *bfa); 174u32 bfa_fcport_mypid(struct bfa_s *bfa);
172u8 bfa_pport_get_rx_bbcredit(struct bfa_s *bfa); 175u8 bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa);
173bfa_status_t bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap); 176bfa_status_t bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap);
174bfa_status_t bfa_pport_trunk_disable(struct bfa_s *bfa); 177bfa_status_t bfa_fcport_trunk_disable(struct bfa_s *bfa);
175bfa_boolean_t bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap); 178bfa_boolean_t bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap);
176void bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr); 179void bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr);
177wwn_t bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node); 180wwn_t bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node);
178bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa, 181void bfa_fcport_event_register(struct bfa_s *bfa,
179 union bfa_pport_stats_u *stats,
180 bfa_cb_pport_t cbfn, void *cbarg);
181bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
182 void *cbarg);
183void bfa_pport_event_register(struct bfa_s *bfa,
184 void (*event_cbfn) (void *cbarg, 182 void (*event_cbfn) (void *cbarg,
185 bfa_pport_event_t event), void *event_cbarg); 183 bfa_pport_event_t event), void *event_cbarg);
186bfa_boolean_t bfa_pport_is_disabled(struct bfa_s *bfa); 184bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
187void bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off); 185void bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off);
188void bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off); 186void bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off);
189bfa_status_t bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, 187bfa_status_t bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa,
190 enum bfa_pport_speed speed); 188 enum bfa_pport_speed speed);
191enum bfa_pport_speed bfa_pport_get_ratelim_speed(struct bfa_s *bfa); 189enum bfa_pport_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
192 190
193void bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit); 191void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
194void bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status); 192void bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status);
195void bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, 193void bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
196 bfa_boolean_t link_e2e_beacon); 194 bfa_boolean_t link_e2e_beacon);
197void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event); 195void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event);
198void bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr); 196void bfa_fcport_qos_get_attr(struct bfa_s *bfa,
199void bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, 197 struct bfa_qos_attr_s *qos_attr);
198void bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
200 struct bfa_qos_vc_attr_s *qos_vc_attr); 199 struct bfa_qos_vc_attr_s *qos_vc_attr);
201bfa_status_t bfa_pport_get_qos_stats(struct bfa_s *bfa, 200bfa_status_t bfa_fcport_get_qos_stats(struct bfa_s *bfa,
202 union bfa_pport_stats_u *stats, 201 union bfa_fcport_stats_u *stats,
203 bfa_cb_pport_t cbfn, void *cbarg); 202 bfa_cb_pport_t cbfn, void *cbarg);
204bfa_status_t bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, 203bfa_status_t bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
205 void *cbarg); 204 void *cbarg);
206bfa_boolean_t bfa_pport_is_ratelim(struct bfa_s *bfa); 205bfa_status_t bfa_fcport_get_fcoe_stats(struct bfa_s *bfa,
207bfa_boolean_t bfa_pport_is_linkup(struct bfa_s *bfa); 206 union bfa_fcport_stats_u *stats,
207 bfa_cb_pport_t cbfn, void *cbarg);
208bfa_status_t bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
209 void *cbarg);
210
211bfa_boolean_t bfa_fcport_is_ratelim(struct bfa_s *bfa);
212bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa);
213bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa,
214 union bfa_fcport_stats_u *stats,
215 bfa_cb_pport_t cbfn, void *cbarg);
216bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
217 void *cbarg);
208 218
209/* 219/*
210 * bfa rport API functions 220 * bfa rport API functions
@@ -293,6 +303,7 @@ void bfa_uf_free(struct bfa_uf_s *uf);
293 * bfa lport service api 303 * bfa lport service api
294 */ 304 */
295 305
306u32 bfa_lps_get_max_vport(struct bfa_s *bfa);
296struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa); 307struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa);
297void bfa_lps_delete(struct bfa_lps_s *lps); 308void bfa_lps_delete(struct bfa_lps_s *lps);
298void bfa_lps_discard(struct bfa_lps_s *lps); 309void bfa_lps_discard(struct bfa_lps_s *lps);
@@ -315,10 +326,12 @@ wwn_t bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps);
315wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps); 326wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps);
316u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps); 327u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps);
317u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps); 328u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps);
329mac_t bfa_lps_get_lp_mac(struct bfa_lps_s *lps);
318void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status); 330void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
319void bfa_cb_lps_flogo_comp(void *bfad, void *uarg); 331void bfa_cb_lps_flogo_comp(void *bfad, void *uarg);
320void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status); 332void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
321void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg); 333void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
334void bfa_cb_lps_cvl_event(void *bfad, void *uarg);
322 335
323#endif /* __BFA_SVC_H__ */ 336#endif /* __BFA_SVC_H__ */
324 337
diff --git a/drivers/scsi/bfa/include/bfa_timer.h b/drivers/scsi/bfa/include/bfa_timer.h
index e407103fa565..f71087448222 100644
--- a/drivers/scsi/bfa/include/bfa_timer.h
+++ b/drivers/scsi/bfa/include/bfa_timer.h
@@ -41,7 +41,7 @@ struct bfa_timer_mod_s {
41 struct list_head timer_q; 41 struct list_head timer_q;
42}; 42};
43 43
44#define BFA_TIMER_FREQ 500 /**< specified in millisecs */ 44#define BFA_TIMER_FREQ 200 /**< specified in millisecs */
45 45
46void bfa_timer_beat(struct bfa_timer_mod_s *mod); 46void bfa_timer_beat(struct bfa_timer_mod_s *mod);
47void bfa_timer_init(struct bfa_timer_mod_s *mod); 47void bfa_timer_init(struct bfa_timer_mod_s *mod);
diff --git a/drivers/scsi/bfa/include/bfi/bfi.h b/drivers/scsi/bfa/include/bfi/bfi.h
index 7042c18e542d..a550e80cabd2 100644
--- a/drivers/scsi/bfa/include/bfi/bfi.h
+++ b/drivers/scsi/bfa/include/bfi/bfi.h
@@ -143,8 +143,8 @@ enum bfi_mclass {
143 BFI_MC_IOC = 1, /* IO Controller (IOC) */ 143 BFI_MC_IOC = 1, /* IO Controller (IOC) */
144 BFI_MC_DIAG = 2, /* Diagnostic Msgs */ 144 BFI_MC_DIAG = 2, /* Diagnostic Msgs */
145 BFI_MC_FLASH = 3, /* Flash message class */ 145 BFI_MC_FLASH = 3, /* Flash message class */
146 BFI_MC_CEE = 4, 146 BFI_MC_CEE = 4, /* CEE */
147 BFI_MC_FC_PORT = 5, /* FC port */ 147 BFI_MC_FCPORT = 5, /* FC port */
148 BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */ 148 BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */
149 BFI_MC_LL = 7, /* Link Layer */ 149 BFI_MC_LL = 7, /* Link Layer */
150 BFI_MC_UF = 8, /* Unsolicited frame receive */ 150 BFI_MC_UF = 8, /* Unsolicited frame receive */
diff --git a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
index b3bb52b565b1..a51ee61ddb19 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
@@ -177,7 +177,21 @@
177#define __PSS_LMEM_INIT_EN 0x00000100 177#define __PSS_LMEM_INIT_EN 0x00000100
178#define __PSS_LPU1_RESET 0x00000002 178#define __PSS_LPU1_RESET 0x00000002
179#define __PSS_LPU0_RESET 0x00000001 179#define __PSS_LPU0_RESET 0x00000001
180 180#define PSS_ERR_STATUS_REG 0x00018810
181#define __PSS_LMEM1_CORR_ERR 0x00000800
182#define __PSS_LMEM0_CORR_ERR 0x00000400
183#define __PSS_LMEM1_UNCORR_ERR 0x00000200
184#define __PSS_LMEM0_UNCORR_ERR 0x00000100
185#define __PSS_BAL_PERR 0x00000080
186#define __PSS_DIP_IF_ERR 0x00000040
187#define __PSS_IOH_IF_ERR 0x00000020
188#define __PSS_TDS_IF_ERR 0x00000010
189#define __PSS_RDS_IF_ERR 0x00000008
190#define __PSS_SGM_IF_ERR 0x00000004
191#define __PSS_LPU1_RAM_ERR 0x00000002
192#define __PSS_LPU0_RAM_ERR 0x00000001
193#define ERR_SET_REG 0x00018818
194#define __PSS_ERR_STATUS_SET 0x00000fff
181 195
182/* 196/*
183 * These definitions are either in error/missing in spec. Its auto-generated 197 * These definitions are either in error/missing in spec. Its auto-generated
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
index d3caa58c0a0a..57a8497105af 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
@@ -430,6 +430,31 @@ enum {
430#define __PSS_LMEM_INIT_EN 0x00000100 430#define __PSS_LMEM_INIT_EN 0x00000100
431#define __PSS_LPU1_RESET 0x00000002 431#define __PSS_LPU1_RESET 0x00000002
432#define __PSS_LPU0_RESET 0x00000001 432#define __PSS_LPU0_RESET 0x00000001
433#define PSS_ERR_STATUS_REG 0x00018810
434#define __PSS_LPU1_TCM_READ_ERR 0x00200000
435#define __PSS_LPU0_TCM_READ_ERR 0x00100000
436#define __PSS_LMEM5_CORR_ERR 0x00080000
437#define __PSS_LMEM4_CORR_ERR 0x00040000
438#define __PSS_LMEM3_CORR_ERR 0x00020000
439#define __PSS_LMEM2_CORR_ERR 0x00010000
440#define __PSS_LMEM1_CORR_ERR 0x00008000
441#define __PSS_LMEM0_CORR_ERR 0x00004000
442#define __PSS_LMEM5_UNCORR_ERR 0x00002000
443#define __PSS_LMEM4_UNCORR_ERR 0x00001000
444#define __PSS_LMEM3_UNCORR_ERR 0x00000800
445#define __PSS_LMEM2_UNCORR_ERR 0x00000400
446#define __PSS_LMEM1_UNCORR_ERR 0x00000200
447#define __PSS_LMEM0_UNCORR_ERR 0x00000100
448#define __PSS_BAL_PERR 0x00000080
449#define __PSS_DIP_IF_ERR 0x00000040
450#define __PSS_IOH_IF_ERR 0x00000020
451#define __PSS_TDS_IF_ERR 0x00000010
452#define __PSS_RDS_IF_ERR 0x00000008
453#define __PSS_SGM_IF_ERR 0x00000004
454#define __PSS_LPU1_RAM_ERR 0x00000002
455#define __PSS_LPU0_RAM_ERR 0x00000001
456#define ERR_SET_REG 0x00018818
457#define __PSS_ERR_STATUS_SET 0x003fffff
433#define HQM_QSET0_RXQ_DRBL_P0 0x00038000 458#define HQM_QSET0_RXQ_DRBL_P0 0x00038000
434#define __RXQ0_ADD_VECTORS_P 0x80000000 459#define __RXQ0_ADD_VECTORS_P 0x80000000
435#define __RXQ0_STOP_P 0x40000000 460#define __RXQ0_STOP_P 0x40000000
@@ -589,6 +614,7 @@ enum {
589#define __HFN_INT_MBOX_LPU1 0x00200000U 614#define __HFN_INT_MBOX_LPU1 0x00200000U
590#define __HFN_INT_MBOX1_LPU0 0x00400000U 615#define __HFN_INT_MBOX1_LPU0 0x00400000U
591#define __HFN_INT_MBOX1_LPU1 0x00800000U 616#define __HFN_INT_MBOX1_LPU1 0x00800000U
617#define __HFN_INT_LL_HALT 0x01000000U
592#define __HFN_INT_CPE_MASK 0x000000ffU 618#define __HFN_INT_CPE_MASK 0x000000ffU
593#define __HFN_INT_RME_MASK 0x0000ff00U 619#define __HFN_INT_RME_MASK 0x0000ff00U
594 620
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ioc.h b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
index 96ef05670659..a0158aac0024 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_ioc.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
@@ -123,7 +123,7 @@ enum bfi_ioc_state {
123 BFI_IOC_DISABLING = 5, /* IOC is being disabled */ 123 BFI_IOC_DISABLING = 5, /* IOC is being disabled */
124 BFI_IOC_DISABLED = 6, /* IOC is disabled */ 124 BFI_IOC_DISABLED = 6, /* IOC is disabled */
125 BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */ 125 BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */
126 BFI_IOC_HBFAIL = 8, /* IOC heart-beat failure */ 126 BFI_IOC_FAIL = 8, /* IOC heart-beat failure */
127 BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */ 127 BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */
128}; 128};
129 129
diff --git a/drivers/scsi/bfa/include/bfi/bfi_lps.h b/drivers/scsi/bfa/include/bfi/bfi_lps.h
index c59d47badb4b..7ed31bbb8696 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_lps.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_lps.h
@@ -30,6 +30,7 @@ enum bfi_lps_h2i_msgs {
30enum bfi_lps_i2h_msgs { 30enum bfi_lps_i2h_msgs {
31 BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1), 31 BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1),
32 BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2), 32 BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2),
33 BFI_LPS_H2I_CVL_EVENT = BFA_I2HM(3),
33}; 34};
34 35
35struct bfi_lps_login_req_s { 36struct bfi_lps_login_req_s {
@@ -77,6 +78,12 @@ struct bfi_lps_logout_rsp_s {
77 u8 rsvd[2]; 78 u8 rsvd[2];
78}; 79};
79 80
81struct bfi_lps_cvl_event_s {
82 struct bfi_mhdr_s mh; /* common msg header */
83 u8 lp_tag;
84 u8 rsvd[3];
85};
86
80union bfi_lps_h2i_msg_u { 87union bfi_lps_h2i_msg_u {
81 struct bfi_mhdr_s *msg; 88 struct bfi_mhdr_s *msg;
82 struct bfi_lps_login_req_s *login_req; 89 struct bfi_lps_login_req_s *login_req;
@@ -87,6 +94,7 @@ union bfi_lps_i2h_msg_u {
87 struct bfi_msg_s *msg; 94 struct bfi_msg_s *msg;
88 struct bfi_lps_login_rsp_s *login_rsp; 95 struct bfi_lps_login_rsp_s *login_rsp;
89 struct bfi_lps_logout_rsp_s *logout_rsp; 96 struct bfi_lps_logout_rsp_s *logout_rsp;
97 struct bfi_lps_cvl_event_s *cvl_event;
90}; 98};
91 99
92#pragma pack() 100#pragma pack()
diff --git a/drivers/scsi/bfa/include/bfi/bfi_pport.h b/drivers/scsi/bfa/include/bfi/bfi_pport.h
index c96d246851af..50dcf45c7470 100644
--- a/drivers/scsi/bfa/include/bfi/bfi_pport.h
+++ b/drivers/scsi/bfa/include/bfi/bfi_pport.h
@@ -22,163 +22,97 @@
22 22
23#pragma pack(1) 23#pragma pack(1)
24 24
25enum bfi_pport_h2i { 25enum bfi_fcport_h2i {
26 BFI_PPORT_H2I_ENABLE_REQ = (1), 26 BFI_FCPORT_H2I_ENABLE_REQ = (1),
27 BFI_PPORT_H2I_DISABLE_REQ = (2), 27 BFI_FCPORT_H2I_DISABLE_REQ = (2),
28 BFI_PPORT_H2I_GET_STATS_REQ = (3), 28 BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ = (3),
29 BFI_PPORT_H2I_CLEAR_STATS_REQ = (4), 29 BFI_FCPORT_H2I_STATS_GET_REQ = (4),
30 BFI_PPORT_H2I_SET_SVC_PARAMS_REQ = (5), 30 BFI_FCPORT_H2I_STATS_CLEAR_REQ = (5),
31 BFI_PPORT_H2I_ENABLE_RX_VF_TAG_REQ = (6),
32 BFI_PPORT_H2I_ENABLE_TX_VF_TAG_REQ = (7),
33 BFI_PPORT_H2I_GET_QOS_STATS_REQ = (8),
34 BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ = (9),
35}; 31};
36 32
37enum bfi_pport_i2h { 33enum bfi_fcport_i2h {
38 BFI_PPORT_I2H_ENABLE_RSP = BFA_I2HM(1), 34 BFI_FCPORT_I2H_ENABLE_RSP = BFA_I2HM(1),
39 BFI_PPORT_I2H_DISABLE_RSP = BFA_I2HM(2), 35 BFI_FCPORT_I2H_DISABLE_RSP = BFA_I2HM(2),
40 BFI_PPORT_I2H_GET_STATS_RSP = BFA_I2HM(3), 36 BFI_FCPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(3),
41 BFI_PPORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4), 37 BFI_FCPORT_I2H_STATS_GET_RSP = BFA_I2HM(4),
42 BFI_PPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(5), 38 BFI_FCPORT_I2H_STATS_CLEAR_RSP = BFA_I2HM(5),
43 BFI_PPORT_I2H_ENABLE_RX_VF_TAG_RSP = BFA_I2HM(6), 39 BFI_FCPORT_I2H_EVENT = BFA_I2HM(6),
44 BFI_PPORT_I2H_ENABLE_TX_VF_TAG_RSP = BFA_I2HM(7),
45 BFI_PPORT_I2H_EVENT = BFA_I2HM(8),
46 BFI_PPORT_I2H_GET_QOS_STATS_RSP = BFA_I2HM(9),
47 BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP = BFA_I2HM(10),
48}; 40};
49 41
50/** 42/**
51 * Generic REQ type 43 * Generic REQ type
52 */ 44 */
53struct bfi_pport_generic_req_s { 45struct bfi_fcport_req_s {
54 struct bfi_mhdr_s mh; /* msg header */ 46 struct bfi_mhdr_s mh; /* msg header */
55 u32 msgtag; /* msgtag for reply */ 47 u32 msgtag; /* msgtag for reply */
56}; 48};
57 49
58/** 50/**
59 * Generic RSP type 51 * Generic RSP type
60 */ 52 */
61struct bfi_pport_generic_rsp_s { 53struct bfi_fcport_rsp_s {
62 struct bfi_mhdr_s mh; /* common msg header */ 54 struct bfi_mhdr_s mh; /* common msg header */
63 u8 status; /* port enable status */ 55 u8 status; /* port enable status */
64 u8 rsvd[3]; 56 u8 rsvd[3];
65 u32 msgtag; /* msgtag for reply */ 57 u32 msgtag; /* msgtag for reply */
66}; 58};
67 59
68/** 60/**
69 * BFI_PPORT_H2I_ENABLE_REQ 61 * BFI_FCPORT_H2I_ENABLE_REQ
70 */ 62 */
71struct bfi_pport_enable_req_s { 63struct bfi_fcport_enable_req_s {
72 struct bfi_mhdr_s mh; /* msg header */ 64 struct bfi_mhdr_s mh; /* msg header */
73 u32 rsvd1; 65 u32 rsvd1;
74 wwn_t nwwn; /* node wwn of physical port */ 66 wwn_t nwwn; /* node wwn of physical port */
75 wwn_t pwwn; /* port wwn of physical port */ 67 wwn_t pwwn; /* port wwn of physical port */
76 struct bfa_pport_cfg_s port_cfg; /* port configuration */ 68 struct bfa_pport_cfg_s port_cfg; /* port configuration */
77 union bfi_addr_u stats_dma_addr; /* DMA address for stats */ 69 union bfi_addr_u stats_dma_addr; /* DMA address for stats */
78 u32 msgtag; /* msgtag for reply */ 70 u32 msgtag; /* msgtag for reply */
79 u32 rsvd2; 71 u32 rsvd2;
80}; 72};
81 73
82/** 74/**
83 * BFI_PPORT_I2H_ENABLE_RSP 75 * BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ
84 */ 76 */
85#define bfi_pport_enable_rsp_t struct bfi_pport_generic_rsp_s 77struct bfi_fcport_set_svc_params_req_s {
86
87/**
88 * BFI_PPORT_H2I_DISABLE_REQ
89 */
90#define bfi_pport_disable_req_t struct bfi_pport_generic_req_s
91
92/**
93 * BFI_PPORT_I2H_DISABLE_RSP
94 */
95#define bfi_pport_disable_rsp_t struct bfi_pport_generic_rsp_s
96
97/**
98 * BFI_PPORT_H2I_GET_STATS_REQ
99 */
100#define bfi_pport_get_stats_req_t struct bfi_pport_generic_req_s
101
102/**
103 * BFI_PPORT_I2H_GET_STATS_RSP
104 */
105#define bfi_pport_get_stats_rsp_t struct bfi_pport_generic_rsp_s
106
107/**
108 * BFI_PPORT_H2I_CLEAR_STATS_REQ
109 */
110#define bfi_pport_clear_stats_req_t struct bfi_pport_generic_req_s
111
112/**
113 * BFI_PPORT_I2H_CLEAR_STATS_RSP
114 */
115#define bfi_pport_clear_stats_rsp_t struct bfi_pport_generic_rsp_s
116
117/**
118 * BFI_PPORT_H2I_GET_QOS_STATS_REQ
119 */
120#define bfi_pport_get_qos_stats_req_t struct bfi_pport_generic_req_s
121
122/**
123 * BFI_PPORT_H2I_GET_QOS_STATS_RSP
124 */
125#define bfi_pport_get_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
126
127/**
128 * BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ
129 */
130#define bfi_pport_clear_qos_stats_req_t struct bfi_pport_generic_req_s
131
132/**
133 * BFI_PPORT_H2I_CLEAR_QOS_STATS_RSP
134 */
135#define bfi_pport_clear_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
136
137/**
138 * BFI_PPORT_H2I_SET_SVC_PARAMS_REQ
139 */
140struct bfi_pport_set_svc_params_req_s {
141 struct bfi_mhdr_s mh; /* msg header */ 78 struct bfi_mhdr_s mh; /* msg header */
142 u16 tx_bbcredit; /* Tx credits */ 79 u16 tx_bbcredit; /* Tx credits */
143 u16 rsvd; 80 u16 rsvd;
144}; 81};
145 82
146/** 83/**
147 * BFI_PPORT_I2H_SET_SVC_PARAMS_RSP 84 * BFI_FCPORT_I2H_EVENT
148 */
149
150/**
151 * BFI_PPORT_I2H_EVENT
152 */ 85 */
153struct bfi_pport_event_s { 86struct bfi_fcport_event_s {
154 struct bfi_mhdr_s mh; /* common msg header */ 87 struct bfi_mhdr_s mh; /* common msg header */
155 struct bfa_pport_link_s link_state; 88 struct bfa_pport_link_s link_state;
156}; 89};
157 90
158union bfi_pport_h2i_msg_u { 91/**
92 * fcport H2I message
93 */
94union bfi_fcport_h2i_msg_u {
159 struct bfi_mhdr_s *mhdr; 95 struct bfi_mhdr_s *mhdr;
160 struct bfi_pport_enable_req_s *penable; 96 struct bfi_fcport_enable_req_s *penable;
161 struct bfi_pport_generic_req_s *pdisable; 97 struct bfi_fcport_req_s *pdisable;
162 struct bfi_pport_generic_req_s *pgetstats; 98 struct bfi_fcport_set_svc_params_req_s *psetsvcparams;
163 struct bfi_pport_generic_req_s *pclearstats; 99 struct bfi_fcport_req_s *pstatsget;
164 struct bfi_pport_set_svc_params_req_s *psetsvcparams; 100 struct bfi_fcport_req_s *pstatsclear;
165 struct bfi_pport_get_qos_stats_req_s *pgetqosstats;
166 struct bfi_pport_generic_req_s *pclearqosstats;
167}; 101};
168 102
169union bfi_pport_i2h_msg_u { 103/**
104 * fcport I2H message
105 */
106union bfi_fcport_i2h_msg_u {
170 struct bfi_msg_s *msg; 107 struct bfi_msg_s *msg;
171 struct bfi_pport_generic_rsp_s *enable_rsp; 108 struct bfi_fcport_rsp_s *penable_rsp;
172 struct bfi_pport_disable_rsp_s *disable_rsp; 109 struct bfi_fcport_rsp_s *pdisable_rsp;
173 struct bfi_pport_generic_rsp_s *getstats_rsp; 110 struct bfi_fcport_rsp_s *psetsvcparams_rsp;
174 struct bfi_pport_clear_stats_rsp_s *clearstats_rsp; 111 struct bfi_fcport_rsp_s *pstatsget_rsp;
175 struct bfi_pport_set_svc_params_rsp_s *setsvcparasm_rsp; 112 struct bfi_fcport_rsp_s *pstatsclear_rsp;
176 struct bfi_pport_get_qos_stats_rsp_s *getqosstats_rsp; 113 struct bfi_fcport_event_s *event;
177 struct bfi_pport_clear_qos_stats_rsp_s *clearqosstats_rsp;
178 struct bfi_pport_event_s *event;
179}; 114};
180 115
181#pragma pack() 116#pragma pack()
182 117
183#endif /* __BFI_PPORT_H__ */ 118#endif /* __BFI_PPORT_H__ */
184
diff --git a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
index 43ba7064e81a..a75a1f3be315 100644
--- a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
+++ b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
@@ -31,6 +31,10 @@
31enum { 31enum {
32 BFA_TRC_CNA_CEE = 1, 32 BFA_TRC_CNA_CEE = 1,
33 BFA_TRC_CNA_PORT = 2, 33 BFA_TRC_CNA_PORT = 2,
34 BFA_TRC_CNA_IOC = 3,
35 BFA_TRC_CNA_DIAG = 4,
36 BFA_TRC_CNA_IOC_CB = 5,
37 BFA_TRC_CNA_IOC_CT = 6,
34}; 38};
35 39
36#endif /* __BFA_CNA_TRCMOD_H__ */ 40#endif /* __BFA_CNA_TRCMOD_H__ */
diff --git a/drivers/scsi/bfa/include/cs/bfa_log.h b/drivers/scsi/bfa/include/cs/bfa_log.h
index 761cbe22130a..bc334e0a93fa 100644
--- a/drivers/scsi/bfa/include/cs/bfa_log.h
+++ b/drivers/scsi/bfa/include/cs/bfa_log.h
@@ -157,7 +157,7 @@ typedef void (*bfa_log_cb_t)(struct bfa_log_mod_s *log_mod, u32 msg_id,
157 157
158 158
159struct bfa_log_mod_s { 159struct bfa_log_mod_s {
160 char instance_info[16]; /* instance info */ 160 char instance_info[BFA_STRING_32]; /* instance info */
161 int log_level[BFA_LOG_MODULE_ID_MAX + 1]; 161 int log_level[BFA_LOG_MODULE_ID_MAX + 1];
162 /* log level for modules */ 162 /* log level for modules */
163 bfa_log_cb_t cbfn; /* callback function */ 163 bfa_log_cb_t cbfn; /* callback function */
diff --git a/drivers/scsi/bfa/include/cs/bfa_plog.h b/drivers/scsi/bfa/include/cs/bfa_plog.h
index 670f86e5fc6e..f5bef63b5877 100644
--- a/drivers/scsi/bfa/include/cs/bfa_plog.h
+++ b/drivers/scsi/bfa/include/cs/bfa_plog.h
@@ -80,7 +80,8 @@ enum bfa_plog_mid {
80 BFA_PL_MID_HAL_FCXP = 4, 80 BFA_PL_MID_HAL_FCXP = 4,
81 BFA_PL_MID_HAL_UF = 5, 81 BFA_PL_MID_HAL_UF = 5,
82 BFA_PL_MID_FCS = 6, 82 BFA_PL_MID_FCS = 6,
83 BFA_PL_MID_MAX = 7 83 BFA_PL_MID_LPS = 7,
84 BFA_PL_MID_MAX = 8
84}; 85};
85 86
86#define BFA_PL_MID_STRLEN 8 87#define BFA_PL_MID_STRLEN 8
@@ -118,7 +119,11 @@ enum bfa_plog_eid {
118 BFA_PL_EID_RSCN = 17, 119 BFA_PL_EID_RSCN = 17,
119 BFA_PL_EID_DEBUG = 18, 120 BFA_PL_EID_DEBUG = 18,
120 BFA_PL_EID_MISC = 19, 121 BFA_PL_EID_MISC = 19,
121 BFA_PL_EID_MAX = 20 122 BFA_PL_EID_FIP_FCF_DISC = 20,
123 BFA_PL_EID_FIP_FCF_CVL = 21,
124 BFA_PL_EID_LOGIN = 22,
125 BFA_PL_EID_LOGO = 23,
126 BFA_PL_EID_MAX = 24
122}; 127};
123 128
124#define BFA_PL_ENAME_STRLEN 8 129#define BFA_PL_ENAME_STRLEN 8
diff --git a/drivers/scsi/bfa/include/cs/bfa_sm.h b/drivers/scsi/bfa/include/cs/bfa_sm.h
index b0a92baf6657..11fba9082f05 100644
--- a/drivers/scsi/bfa/include/cs/bfa_sm.h
+++ b/drivers/scsi/bfa/include/cs/bfa_sm.h
@@ -23,6 +23,14 @@
23#define __BFA_SM_H__ 23#define __BFA_SM_H__
24 24
25typedef void (*bfa_sm_t)(void *sm, int event); 25typedef void (*bfa_sm_t)(void *sm, int event);
26/**
27 * oc - object class eg. bfa_ioc
28 * st - state, eg. reset
29 * otype - object type, eg. struct bfa_ioc_s
30 * etype - object type, eg. enum ioc_event
31 */
32#define bfa_sm_state_decl(oc, st, otype, etype) \
33 static void oc ## _sm_ ## st(otype * fsm, etype event)
26 34
27#define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state)) 35#define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state))
28#define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event))) 36#define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event)))
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
index 4c81a613db3d..35244698fcdc 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
@@ -30,6 +30,16 @@
30#include <defs/bfa_defs_audit.h> 30#include <defs/bfa_defs_audit.h>
31#include <defs/bfa_defs_ethport.h> 31#include <defs/bfa_defs_ethport.h>
32 32
33#define BFA_AEN_MAX_APP 5
34
35enum bfa_aen_app {
36 bfa_aen_app_bcu = 0, /* No thread for bcu */
37 bfa_aen_app_hcm = 1,
38 bfa_aen_app_cim = 2,
39 bfa_aen_app_snia = 3,
40 bfa_aen_app_test = 4, /* To be removed after unit test */
41};
42
33enum bfa_aen_category { 43enum bfa_aen_category {
34 BFA_AEN_CAT_ADAPTER = 1, 44 BFA_AEN_CAT_ADAPTER = 1,
35 BFA_AEN_CAT_PORT = 2, 45 BFA_AEN_CAT_PORT = 2,
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
index dd19c83aba58..45df32820911 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
@@ -23,6 +23,7 @@
23#define PRIVATE_KEY 19009 23#define PRIVATE_KEY 19009
24#define KEY_LEN 32399 24#define KEY_LEN 32399
25#define BFA_AUTH_SECRET_STRING_LEN 256 25#define BFA_AUTH_SECRET_STRING_LEN 256
26#define BFA_AUTH_FAIL_NO_PASSWORD 0xFE
26#define BFA_AUTH_FAIL_TIMEOUT 0xFF 27#define BFA_AUTH_FAIL_TIMEOUT 0xFF
27 28
28/** 29/**
@@ -41,6 +42,27 @@ enum bfa_auth_status {
41 BFA_AUTH_STATUS_UNKNOWN = 9, /* authentication status unknown */ 42 BFA_AUTH_STATUS_UNKNOWN = 9, /* authentication status unknown */
42}; 43};
43 44
45enum bfa_auth_rej_code {
46 BFA_AUTH_RJT_CODE_AUTH_FAILURE = 1, /* auth failure */
47 BFA_AUTH_RJT_CODE_LOGICAL_ERR = 2, /* logical error */
48};
49
50/**
51 * Authentication reject codes
52 */
53enum bfa_auth_rej_code_exp {
54 BFA_AUTH_MECH_NOT_USABLE = 1, /* auth. mechanism not usable */
55 BFA_AUTH_DH_GROUP_NOT_USABLE = 2, /* DH Group not usable */
56 BFA_AUTH_HASH_FUNC_NOT_USABLE = 3, /* hash Function not usable */
57 BFA_AUTH_AUTH_XACT_STARTED = 4, /* auth xact started */
58 BFA_AUTH_AUTH_FAILED = 5, /* auth failed */
59 BFA_AUTH_INCORRECT_PLD = 6, /* incorrect payload */
60 BFA_AUTH_INCORRECT_PROTO_MSG = 7, /* incorrect proto msg */
61 BFA_AUTH_RESTART_AUTH_PROTO = 8, /* restart auth protocol */
62 BFA_AUTH_AUTH_CONCAT_NOT_SUPP = 9, /* auth concat not supported */
63 BFA_AUTH_PROTO_VER_NOT_SUPP = 10,/* proto version not supported */
64};
65
44struct auth_proto_stats_s { 66struct auth_proto_stats_s {
45 u32 auth_rjts; 67 u32 auth_rjts;
46 u32 auth_negs; 68 u32 auth_negs;
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
index 520a22f52dd1..b0ac9ac15c5d 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
@@ -28,10 +28,6 @@
28 28
29#define BFA_CEE_LLDP_MAX_STRING_LEN (128) 29#define BFA_CEE_LLDP_MAX_STRING_LEN (128)
30 30
31
32/* FIXME: this is coming from the protocol spec. Can the host & apps share the
33 protocol .h files ?
34 */
35#define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001 31#define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001
36#define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002 32#define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002
37#define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004 33#define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004
@@ -94,9 +90,10 @@ struct bfa_cee_dcbx_cfg_s {
94/* CEE status */ 90/* CEE status */
95/* Making this to tri-state for the benefit of port list command */ 91/* Making this to tri-state for the benefit of port list command */
96enum bfa_cee_status_e { 92enum bfa_cee_status_e {
97 CEE_PHY_DOWN = 0, 93 CEE_UP = 0,
98 CEE_PHY_UP = 1, 94 CEE_PHY_UP = 1,
99 CEE_UP = 2, 95 CEE_LOOPBACK = 2,
96 CEE_PHY_DOWN = 3,
100}; 97};
101 98
102/* CEE Query */ 99/* CEE Query */
@@ -107,7 +104,8 @@ struct bfa_cee_attr_s {
107 struct bfa_cee_dcbx_cfg_s dcbx_remote; 104 struct bfa_cee_dcbx_cfg_s dcbx_remote;
108 mac_t src_mac; 105 mac_t src_mac;
109 u8 link_speed; 106 u8 link_speed;
110 u8 filler[3]; 107 u8 nw_priority;
108 u8 filler[2];
111}; 109};
112 110
113 111
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
index 57049805762b..50382dd2ab41 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
@@ -21,6 +21,7 @@
21/** 21/**
22 * Driver statistics 22 * Driver statistics
23 */ 23 */
24struct bfa_driver_stats_s {
24 u16 tm_io_abort; 25 u16 tm_io_abort;
25 u16 tm_io_abort_comp; 26 u16 tm_io_abort_comp;
26 u16 tm_lun_reset; 27 u16 tm_lun_reset;
@@ -34,7 +35,7 @@
34 u64 output_req; 35 u64 output_req;
35 u64 input_words; 36 u64 input_words;
36 u64 output_words; 37 u64 output_words;
37} bfa_driver_stats_t; 38};
38 39
39 40
40#endif /* __BFA_DEFS_DRIVER_H__ */ 41#endif /* __BFA_DEFS_DRIVER_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
index 79f9b3e146f7..b4fa0923aa89 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
@@ -19,6 +19,7 @@
19#define __BFA_DEFS_ETHPORT_H__ 19#define __BFA_DEFS_ETHPORT_H__
20 20
21#include <defs/bfa_defs_status.h> 21#include <defs/bfa_defs_status.h>
22#include <defs/bfa_defs_port.h>
22#include <protocol/types.h> 23#include <protocol/types.h>
23#include <cna/pstats/phyport_defs.h> 24#include <cna/pstats/phyport_defs.h>
24#include <cna/pstats/ethport_defs.h> 25#include <cna/pstats/ethport_defs.h>
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h
new file mode 100644
index 000000000000..a07ef4a3cd78
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h
@@ -0,0 +1,94 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * bfa_defs_fcport.h
7 *
8 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License (GPL) Version 2 as
12 * published by the Free Software Foundation
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */
19#ifndef __BFA_DEFS_FCPORT_H__
20#define __BFA_DEFS_FCPORT_H__
21
22#include <defs/bfa_defs_types.h>
23#include <protocol/types.h>
24
25#pragma pack(1)
26
27/**
28 * FCoE statistics
29 */
30struct bfa_fcoe_stats_s {
31 u64 secs_reset; /* Seconds since stats reset */
32 u64 cee_linkups; /* CEE link up */
33 u64 cee_linkdns; /* CEE link down */
34 u64 fip_linkups; /* FIP link up */
35 u64 fip_linkdns; /* FIP link down */
36 u64 fip_fails; /* FIP failures */
37 u64 mac_invalids; /* Invalid mac assignments */
38 u64 vlan_req; /* Vlan requests */
39 u64 vlan_notify; /* Vlan notifications */
40 u64 vlan_err; /* Vlan notification errors */
41 u64 vlan_timeouts; /* Vlan request timeouts */
42 u64 vlan_invalids; /* Vlan invalids */
43 u64 disc_req; /* Discovery requests */
44 u64 disc_rsp; /* Discovery responses */
45 u64 disc_err; /* Discovery error frames */
46 u64 disc_unsol; /* Discovery unsolicited */
47 u64 disc_timeouts; /* Discovery timeouts */
48 u64 disc_fcf_unavail; /* Discovery FCF not avail */
49 u64 linksvc_unsupp; /* FIP link service req unsupp. */
50 u64 linksvc_err; /* FIP link service req errors */
51 u64 logo_req; /* FIP logo */
52 u64 clrvlink_req; /* Clear virtual link requests */
53 u64 op_unsupp; /* FIP operation unsupp. */
54 u64 untagged; /* FIP untagged frames */
55 u64 txf_ucast; /* Tx FCoE unicast frames */
56 u64 txf_ucast_vlan; /* Tx FCoE unicast vlan frames */
57 u64 txf_ucast_octets; /* Tx FCoE unicast octets */
58 u64 txf_mcast; /* Tx FCoE mutlicast frames */
59 u64 txf_mcast_vlan; /* Tx FCoE mutlicast vlan frames */
60 u64 txf_mcast_octets; /* Tx FCoE multicast octets */
61 u64 txf_bcast; /* Tx FCoE broadcast frames */
62 u64 txf_bcast_vlan; /* Tx FCoE broadcast vlan frames */
63 u64 txf_bcast_octets; /* Tx FCoE broadcast octets */
64 u64 txf_timeout; /* Tx timeouts */
65 u64 txf_parity_errors; /* Transmit parity err */
66 u64 txf_fid_parity_errors; /* Transmit FID parity err */
67 u64 tx_pause; /* Tx pause frames */
68 u64 tx_zero_pause; /* Tx zero pause frames */
69 u64 tx_first_pause; /* Tx first pause frames */
70 u64 rx_pause; /* Rx pause frames */
71 u64 rx_zero_pause; /* Rx zero pause frames */
72 u64 rx_first_pause; /* Rx first pause frames */
73 u64 rxf_ucast_octets; /* Rx unicast octets */
74 u64 rxf_ucast; /* Rx unicast frames */
75 u64 rxf_ucast_vlan; /* Rx unicast vlan frames */
76 u64 rxf_mcast_octets; /* Rx multicast octets */
77 u64 rxf_mcast; /* Rx multicast frames */
78 u64 rxf_mcast_vlan; /* Rx multicast vlan frames */
79 u64 rxf_bcast_octets; /* Rx broadcast octests */
80 u64 rxf_bcast; /* Rx broadcast frames */
81 u64 rxf_bcast_vlan; /* Rx broadcast vlan frames */
82};
83
84/**
85 * QoS or FCoE stats (fcport stats excluding physical FC port stats)
86 */
87union bfa_fcport_stats_u {
88 struct bfa_qos_stats_s fcqos;
89 struct bfa_fcoe_stats_s fcoe;
90};
91
92#pragma pack()
93
94#endif /* __BFA_DEFS_FCPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h
deleted file mode 100644
index 9ccf53bef65a..000000000000
--- a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_IM_COMMON_H__
19#define __BFA_DEFS_IM_COMMON_H__
20
21#define BFA_ADAPTER_NAME_LEN 256
22#define BFA_ADAPTER_GUID_LEN 256
23#define RESERVED_VLAN_NAME L"PORT VLAN"
24#define PASSTHRU_VLAN_NAME L"PASSTHRU VLAN"
25
26 u64 tx_pkt_cnt;
27 u64 rx_pkt_cnt;
28 u32 duration;
29 u8 status;
30} bfa_im_stats_t, *pbfa_im_stats_t;
31
32#endif /* __BFA_DEFS_IM_COMMON_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h
deleted file mode 100644
index a486a7eb81d6..000000000000
--- a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h
+++ /dev/null
@@ -1,72 +0,0 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_IM_TEAM_H__
19#define __BFA_DEFS_IM_TEAM_H__
20
21#include <protocol/types.h>
22
23#define BFA_TEAM_MAX_PORTS 8
24#define BFA_TEAM_NAME_LEN 256
25#define BFA_MAX_NUM_TEAMS 16
26#define BFA_TEAM_INVALID_DELAY -1
27
28 BFA_LACP_RATE_SLOW = 1,
29 BFA_LACP_RATE_FAST
30} bfa_im_lacp_rate_t;
31
32 BFA_TEAM_MODE_FAIL_OVER = 1,
33 BFA_TEAM_MODE_FAIL_BACK,
34 BFA_TEAM_MODE_LACP,
35 BFA_TEAM_MODE_NONE
36} bfa_im_team_mode_t;
37
38 BFA_XMIT_POLICY_L2 = 1,
39 BFA_XMIT_POLICY_L3_L4
40} bfa_im_xmit_policy_t;
41
42 bfa_im_team_mode_t team_mode;
43 bfa_im_lacp_rate_t lacp_rate;
44 bfa_im_xmit_policy_t xmit_policy;
45 int delay;
46 wchar_t primary[BFA_ADAPTER_NAME_LEN];
47 wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN];
48 mac_t mac;
49 u16 num_ports;
50 u16 num_vlans;
51 u16 vlan_list[BFA_MAX_VLANS_PER_PORT];
52 wchar_t team_guid_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_GUID_LEN];
53 wchar_t ioc_name_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_NAME_LEN];
54} bfa_im_team_attr_t;
55
56 wchar_t team_name[BFA_TEAM_NAME_LEN];
57 bfa_im_xmit_policy_t xmit_policy;
58 int delay;
59 wchar_t primary[BFA_ADAPTER_NAME_LEN];
60 wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN];
61} bfa_im_team_edit_t, *pbfa_im_team_edit_t;
62
63 wchar_t team_name[BFA_TEAM_NAME_LEN];
64 bfa_im_team_mode_t team_mode;
65 mac_t mac;
66} bfa_im_team_info_t;
67
68 bfa_im_team_info_t team_info[BFA_MAX_NUM_TEAMS];
69 u16 num_teams;
70} bfa_im_team_list_t, *pbfa_im_team_list_t;
71
72#endif /* __BFA_DEFS_IM_TEAM_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
index b1d532da3a9d..8d8e6a966537 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
@@ -126,6 +126,7 @@ struct bfa_ioc_attr_s {
126 struct bfa_ioc_driver_attr_s driver_attr; /* driver attr */ 126 struct bfa_ioc_driver_attr_s driver_attr; /* driver attr */
127 struct bfa_ioc_pci_attr_s pci_attr; 127 struct bfa_ioc_pci_attr_s pci_attr;
128 u8 port_id; /* port number */ 128 u8 port_id; /* port number */
129 u8 rsvd[7]; /*!< 64bit align */
129}; 130};
130 131
131/** 132/**
@@ -143,8 +144,8 @@ enum bfa_ioc_aen_event {
143 * BFA IOC level event data, now just a place holder 144 * BFA IOC level event data, now just a place holder
144 */ 145 */
145struct bfa_ioc_aen_data_s { 146struct bfa_ioc_aen_data_s {
146 enum bfa_ioc_type_e ioc_type;
147 wwn_t pwwn; 147 wwn_t pwwn;
148 s16 ioc_type;
148 mac_t mac; 149 mac_t mac;
149}; 150};
150 151
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
index d76bcbd9820f..c290fb13d2d1 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
@@ -26,6 +26,8 @@
26 26
27#define BFA_IOCFC_INTR_DELAY 1125 27#define BFA_IOCFC_INTR_DELAY 1125
28#define BFA_IOCFC_INTR_LATENCY 225 28#define BFA_IOCFC_INTR_LATENCY 225
29#define BFA_IOCFCOE_INTR_DELAY 25
30#define BFA_IOCFCOE_INTR_LATENCY 5
29 31
30/** 32/**
31 * Interrupt coalescing configuration. 33 * Interrupt coalescing configuration.
@@ -50,7 +52,7 @@ struct bfa_iocfc_fwcfg_s {
50 u16 num_fcxp_reqs; /* unassisted FC exchanges */ 52 u16 num_fcxp_reqs; /* unassisted FC exchanges */
51 u16 num_uf_bufs; /* unsolicited recv buffers */ 53 u16 num_uf_bufs; /* unsolicited recv buffers */
52 u8 num_cqs; 54 u8 num_cqs;
53 u8 rsvd; 55 u8 rsvd[5];
54}; 56};
55 57
56struct bfa_iocfc_drvcfg_s { 58struct bfa_iocfc_drvcfg_s {
@@ -224,18 +226,24 @@ struct bfa_fw_port_physm_stats_s {
224 226
225 227
226struct bfa_fw_fip_stats_s { 228struct bfa_fw_fip_stats_s {
229 u32 vlan_req; /* vlan discovery requests */
230 u32 vlan_notify; /* vlan notifications */
231 u32 vlan_err; /* vlan response error */
232 u32 vlan_timeouts; /* vlan disvoery timeouts */
233 u32 vlan_invalids; /* invalid vlan in discovery advert. */
227 u32 disc_req; /* Discovery solicit requests */ 234 u32 disc_req; /* Discovery solicit requests */
228 u32 disc_rsp; /* Discovery solicit response */ 235 u32 disc_rsp; /* Discovery solicit response */
229 u32 disc_err; /* Discovery advt. parse errors */ 236 u32 disc_err; /* Discovery advt. parse errors */
230 u32 disc_unsol; /* Discovery unsolicited */ 237 u32 disc_unsol; /* Discovery unsolicited */
231 u32 disc_timeouts; /* Discovery timeouts */ 238 u32 disc_timeouts; /* Discovery timeouts */
239 u32 disc_fcf_unavail; /* Discovery FCF Not Avail. */
232 u32 linksvc_unsupp; /* Unsupported link service req */ 240 u32 linksvc_unsupp; /* Unsupported link service req */
233 u32 linksvc_err; /* Parse error in link service req */ 241 u32 linksvc_err; /* Parse error in link service req */
234 u32 logo_req; /* Number of FIP logos received */ 242 u32 logo_req; /* Number of FIP logos received */
235 u32 clrvlink_req; /* Clear virtual link req */ 243 u32 clrvlink_req; /* Clear virtual link req */
236 u32 op_unsupp; /* Unsupported FIP operation */ 244 u32 op_unsupp; /* Unsupported FIP operation */
237 u32 untagged; /* Untagged frames (ignored) */ 245 u32 untagged; /* Untagged frames (ignored) */
238 u32 rsvd; 246 u32 invalid_version; /*!< Invalid FIP version */
239}; 247};
240 248
241 249
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
index 7359f82aacfc..0952a139c47c 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
@@ -59,8 +59,8 @@ enum bfa_lport_aen_event {
59 */ 59 */
60struct bfa_lport_aen_data_s { 60struct bfa_lport_aen_data_s {
61 u16 vf_id; /* vf_id of this logical port */ 61 u16 vf_id; /* vf_id of this logical port */
62 u16 rsvd; 62 s16 roles; /* Logical port mode,IM/TM/IP etc */
63 enum bfa_port_role roles; /* Logical port mode,IM/TM/IP etc */ 63 u32 rsvd;
64 wwn_t ppwwn; /* WWN of its physical port */ 64 wwn_t ppwwn; /* WWN of its physical port */
65 wwn_t lpwwn; /* WWN of this logical port */ 65 wwn_t lpwwn; /* WWN of this logical port */
66}; 66};
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
index 13fd4ab6aae2..c5bd9c36ad4d 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
@@ -22,7 +22,47 @@
22/** 22/**
23 * Manufacturing block version 23 * Manufacturing block version
24 */ 24 */
25#define BFA_MFG_VERSION 1 25#define BFA_MFG_VERSION 2
26
27/**
28 * Manufacturing block encrypted version
29 */
30#define BFA_MFG_ENC_VER 2
31
32/**
33 * Manufacturing block version 1 length
34 */
35#define BFA_MFG_VER1_LEN 128
36
37/**
38 * Manufacturing block header length
39 */
40#define BFA_MFG_HDR_LEN 4
41
42/**
43 * Checksum size
44 */
45#define BFA_MFG_CHKSUM_SIZE 16
46
47/**
48 * Manufacturing block encrypted version
49 */
50#define BFA_MFG_ENC_VER 2
51
52/**
53 * Manufacturing block version 1 length
54 */
55#define BFA_MFG_VER1_LEN 128
56
57/**
58 * Manufacturing block header length
59 */
60#define BFA_MFG_HDR_LEN 4
61
62/**
63 * Checksum size
64 */
65#define BFA_MFG_CHKSUM_SIZE 16
26 66
27/** 67/**
28 * Manufacturing block format 68 * Manufacturing block format
@@ -30,29 +70,74 @@
30#define BFA_MFG_SERIALNUM_SIZE 11 70#define BFA_MFG_SERIALNUM_SIZE 11
31#define BFA_MFG_PARTNUM_SIZE 14 71#define BFA_MFG_PARTNUM_SIZE 14
32#define BFA_MFG_SUPPLIER_ID_SIZE 10 72#define BFA_MFG_SUPPLIER_ID_SIZE 10
33#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20 73#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20
34#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20 74#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20
35#define BFA_MFG_SUPPLIER_REVISION_SIZE 4 75#define BFA_MFG_SUPPLIER_REVISION_SIZE 4
36#define STRSZ(_n) (((_n) + 4) & ~3) 76#define STRSZ(_n) (((_n) + 4) & ~3)
37 77
38/** 78/**
79 * Manufacturing card type
80 */
81enum {
82 BFA_MFG_TYPE_CB_MAX = 825, /* Crossbow card type max */
83 BFA_MFG_TYPE_FC8P2 = 825, /* 8G 2port FC card */
84 BFA_MFG_TYPE_FC8P1 = 815, /* 8G 1port FC card */
85 BFA_MFG_TYPE_FC4P2 = 425, /* 4G 2port FC card */
86 BFA_MFG_TYPE_FC4P1 = 415, /* 4G 1port FC card */
87 BFA_MFG_TYPE_CNA10P2 = 1020, /* 10G 2port CNA card */
88 BFA_MFG_TYPE_CNA10P1 = 1010, /* 10G 1port CNA card */
89};
90
91#pragma pack(1)
92
93/**
94 * Card type to port number conversion
95 */
96#define bfa_mfg_type2port_num(card_type) (((card_type) / 10) % 10)
97
98
99/**
100 * All numerical fields are in big-endian format.
101 */
102struct bfa_mfg_block_s {
103};
104
105/**
39 * VPD data length 106 * VPD data length
40 */ 107 */
41#define BFA_MFG_VPD_LEN 256 108#define BFA_MFG_VPD_LEN 512
109
110#define BFA_MFG_VPD_PCI_HDR_OFF 137
111#define BFA_MFG_VPD_PCI_VER_MASK 0x07 /* version mask 3 bits */
112#define BFA_MFG_VPD_PCI_VDR_MASK 0xf8 /* vendor mask 5 bits */
113
114/**
115 * VPD vendor tag
116 */
117enum {
118 BFA_MFG_VPD_UNKNOWN = 0, /* vendor unknown */
119 BFA_MFG_VPD_IBM = 1, /* vendor IBM */
120 BFA_MFG_VPD_HP = 2, /* vendor HP */
121 BFA_MFG_VPD_DELL = 3, /* vendor DELL */
122 BFA_MFG_VPD_PCI_IBM = 0x08, /* PCI VPD IBM */
123 BFA_MFG_VPD_PCI_HP = 0x10, /* PCI VPD HP */
124 BFA_MFG_VPD_PCI_DELL = 0x20, /* PCI VPD DELL */
125 BFA_MFG_VPD_PCI_BRCD = 0xf8, /* PCI VPD Brocade */
126};
42 127
43/** 128/**
44 * All numerical fields are in big-endian format. 129 * All numerical fields are in big-endian format.
45 */ 130 */
46struct bfa_mfg_vpd_s { 131struct bfa_mfg_vpd_s {
47 u8 version; /* vpd data version */ 132 u8 version; /* vpd data version */
48 u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */ 133 u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */
49 u8 chksum; /* u8 checksum */ 134 u8 chksum; /* u8 checksum */
50 u8 vendor; /* vendor */ 135 u8 vendor; /* vendor */
51 u8 len; /* vpd data length excluding header */ 136 u8 len; /* vpd data length excluding header */
52 u8 rsv; 137 u8 rsv;
53 u8 data[BFA_MFG_VPD_LEN]; /* vpd data */ 138 u8 data[BFA_MFG_VPD_LEN]; /* vpd data */
54}; 139};
55 140
56#pragma pack(1) 141#pragma pack()
57 142
58#endif /* __BFA_DEFS_MFG_H__ */ 143#endif /* __BFA_DEFS_MFG_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_port.h b/drivers/scsi/bfa/include/defs/bfa_defs_port.h
index de0696c81bc4..501bc9739d9d 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_port.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_port.h
@@ -185,6 +185,8 @@ struct bfa_port_attr_s {
185 wwn_t fabric_name; /* attached switch's nwwn */ 185 wwn_t fabric_name; /* attached switch's nwwn */
186 u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached 186 u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached
187 * fabric's ip addr */ 187 * fabric's ip addr */
188 struct mac_s fpma_mac; /* Lport's FPMA Mac address */
189 u16 authfail; /* auth failed state */
188}; 190};
189 191
190/** 192/**
@@ -232,14 +234,15 @@ enum bfa_port_aen_sfp_pom {
232}; 234};
233 235
234struct bfa_port_aen_data_s { 236struct bfa_port_aen_data_s {
235 enum bfa_ioc_type_e ioc_type; 237 wwn_t pwwn; /* WWN of the physical port */
236 wwn_t pwwn; /* WWN of the physical port */ 238 wwn_t fwwn; /* WWN of the fabric port */
237 wwn_t fwwn; /* WWN of the fabric port */ 239 s32 phy_port_num; /*! For SFP related events */
238 mac_t mac; /* MAC addres of the ethernet port, 240 s16 ioc_type;
239 * applicable to CNA port only */ 241 s16 level; /* Only transitions will
240 int phy_port_num; /*! For SFP related events */ 242 * be informed */
241 enum bfa_port_aen_sfp_pom level; /* Only transitions will 243 struct mac_s mac; /* MAC address of the ethernet port,
242 * be informed */ 244 * applicable to CNA port only */
245 s16 rsvd;
243}; 246};
244 247
245#endif /* __BFA_DEFS_PORT_H__ */ 248#endif /* __BFA_DEFS_PORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
index bf320412ee24..26e5cc78095d 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
@@ -232,7 +232,7 @@ struct bfa_pport_attr_s {
232 u32 pid; /* port ID */ 232 u32 pid; /* port ID */
233 enum bfa_pport_type port_type; /* current topology */ 233 enum bfa_pport_type port_type; /* current topology */
234 u32 loopback; /* external loopback */ 234 u32 loopback; /* external loopback */
235 u32 rsvd1; 235 u32 authfail; /* auth fail state */
236 u32 rsvd2; /* padding for 64 bit */ 236 u32 rsvd2; /* padding for 64 bit */
237}; 237};
238 238
@@ -240,73 +240,79 @@ struct bfa_pport_attr_s {
240 * FC Port statistics. 240 * FC Port statistics.
241 */ 241 */
242struct bfa_pport_fc_stats_s { 242struct bfa_pport_fc_stats_s {
243 u64 secs_reset; /* seconds since stats is reset */ 243 u64 secs_reset; /* Seconds since stats is reset */
244 u64 tx_frames; /* transmitted frames */ 244 u64 tx_frames; /* Tx frames */
245 u64 tx_words; /* transmitted words */ 245 u64 tx_words; /* Tx words */
246 u64 rx_frames; /* received frames */ 246 u64 tx_lip; /* TX LIP */
247 u64 rx_words; /* received words */ 247 u64 tx_nos; /* Tx NOS */
248 u64 lip_count; /* LIPs seen */ 248 u64 tx_ols; /* Tx OLS */
249 u64 nos_count; /* NOS count */ 249 u64 tx_lr; /* Tx LR */
250 u64 error_frames; /* errored frames (sent?) */ 250 u64 tx_lrr; /* Tx LRR */
251 u64 dropped_frames; /* dropped frames */ 251 u64 rx_frames; /* Rx frames */
252 u64 link_failures; /* link failure count */ 252 u64 rx_words; /* Rx words */
253 u64 loss_of_syncs; /* loss of sync count */ 253 u64 lip_count; /* Rx LIP */
254 u64 loss_of_signals;/* loss of signal count */ 254 u64 nos_count; /* Rx NOS */
255 u64 primseq_errs; /* primitive sequence protocol */ 255 u64 ols_count; /* Rx OLS */
256 u64 bad_os_count; /* invalid ordered set */ 256 u64 lr_count; /* Rx LR */
257 u64 err_enc_out; /* Encoding error outside frame */ 257 u64 lrr_count; /* Rx LRR */
258 u64 invalid_crcs; /* frames received with invalid CRC*/ 258 u64 invalid_crcs; /* Rx CRC err frames */
259 u64 undersized_frm; /* undersized frames */ 259 u64 invalid_crc_gd_eof; /* Rx CRC err good EOF frames */
260 u64 oversized_frm; /* oversized frames */ 260 u64 undersized_frm; /* Rx undersized frames */
261 u64 bad_eof_frm; /* frames with bad EOF */ 261 u64 oversized_frm; /* Rx oversized frames */
262 struct bfa_qos_stats_s qos_stats; /* QoS statistics */ 262 u64 bad_eof_frm; /* Rx frames with bad EOF */
263 u64 error_frames; /* Errored frames */
264 u64 dropped_frames; /* Dropped frames */
265 u64 link_failures; /* Link Failure (LF) count */
266 u64 loss_of_syncs; /* Loss of sync count */
267 u64 loss_of_signals;/* Loss of signal count */
268 u64 primseq_errs; /* Primitive sequence protocol err. */
269 u64 bad_os_count; /* Invalid ordered sets */
270 u64 err_enc_out; /* Encoding err nonframe_8b10b */
271 u64 err_enc; /* Encoding err frame_8b10b */
263}; 272};
264 273
265/** 274/**
266 * Eth Port statistics. 275 * Eth Port statistics.
267 */ 276 */
268struct bfa_pport_eth_stats_s { 277struct bfa_pport_eth_stats_s {
269 u64 secs_reset; /* seconds since stats is reset */ 278 u64 secs_reset; /* Seconds since stats is reset */
270 u64 frame_64; /* both rx and tx counter */ 279 u64 frame_64; /* Frames 64 bytes */
271 u64 frame_65_127; /* both rx and tx counter */ 280 u64 frame_65_127; /* Frames 65-127 bytes */
272 u64 frame_128_255; /* both rx and tx counter */ 281 u64 frame_128_255; /* Frames 128-255 bytes */
273 u64 frame_256_511; /* both rx and tx counter */ 282 u64 frame_256_511; /* Frames 256-511 bytes */
274 u64 frame_512_1023; /* both rx and tx counter */ 283 u64 frame_512_1023; /* Frames 512-1023 bytes */
275 u64 frame_1024_1518; /* both rx and tx counter */ 284 u64 frame_1024_1518; /* Frames 1024-1518 bytes */
276 u64 frame_1519_1522; /* both rx and tx counter */ 285 u64 frame_1519_1522; /* Frames 1519-1522 bytes */
277 286 u64 tx_bytes; /* Tx bytes */
278 u64 tx_bytes; 287 u64 tx_packets; /* Tx packets */
279 u64 tx_packets; 288 u64 tx_mcast_packets; /* Tx multicast packets */
280 u64 tx_mcast_packets; 289 u64 tx_bcast_packets; /* Tx broadcast packets */
281 u64 tx_bcast_packets; 290 u64 tx_control_frame; /* Tx control frame */
282 u64 tx_control_frame; 291 u64 tx_drop; /* Tx drops */
283 u64 tx_drop; 292 u64 tx_jabber; /* Tx jabber */
284 u64 tx_jabber; 293 u64 tx_fcs_error; /* Tx FCS error */
285 u64 tx_fcs_error; 294 u64 tx_fragments; /* Tx fragments */
286 u64 tx_fragments; 295 u64 rx_bytes; /* Rx bytes */
287 296 u64 rx_packets; /* Rx packets */
288 u64 rx_bytes; 297 u64 rx_mcast_packets; /* Rx multicast packets */
289 u64 rx_packets; 298 u64 rx_bcast_packets; /* Rx broadcast packets */
290 u64 rx_mcast_packets; 299 u64 rx_control_frames; /* Rx control frames */
291 u64 rx_bcast_packets; 300 u64 rx_unknown_opcode; /* Rx unknown opcode */
292 u64 rx_control_frames; 301 u64 rx_drop; /* Rx drops */
293 u64 rx_unknown_opcode; 302 u64 rx_jabber; /* Rx jabber */
294 u64 rx_drop; 303 u64 rx_fcs_error; /* Rx FCS errors */
295 u64 rx_jabber; 304 u64 rx_alignment_error; /* Rx alignment errors */
296 u64 rx_fcs_error; 305 u64 rx_frame_length_error; /* Rx frame len errors */
297 u64 rx_alignment_error; 306 u64 rx_code_error; /* Rx code errors */
298 u64 rx_frame_length_error; 307 u64 rx_fragments; /* Rx fragments */
299 u64 rx_code_error; 308 u64 rx_pause; /* Rx pause */
300 u64 rx_fragments; 309 u64 rx_zero_pause; /* Rx zero pause */
301 310 u64 tx_pause; /* Tx pause */
302 u64 rx_pause; /* BPC */ 311 u64 tx_zero_pause; /* Tx zero pause */
303 u64 rx_zero_pause; /* BPC Pause cancellation */ 312 u64 rx_fcoe_pause; /* Rx fcoe pause */
304 u64 tx_pause; /* BPC */ 313 u64 rx_fcoe_zero_pause; /* Rx FCoE zero pause */
305 u64 tx_zero_pause; /* BPC Pause cancellation */ 314 u64 tx_fcoe_pause; /* Tx FCoE pause */
306 u64 rx_fcoe_pause; /* BPC */ 315 u64 tx_fcoe_zero_pause; /* Tx FCoE zero pause */
307 u64 rx_fcoe_zero_pause; /* BPC Pause cancellation */
308 u64 tx_fcoe_pause; /* BPC */
309 u64 tx_fcoe_zero_pause; /* BPC Pause cancellation */
310}; 316};
311 317
312/** 318/**
@@ -333,8 +339,7 @@ struct bfa_pport_fcpmap_s {
333}; 339};
334 340
335/** 341/**
336 * Port RNID info. 342 * Port RNI */
337 */
338struct bfa_pport_rnid_s { 343struct bfa_pport_rnid_s {
339 wwn_t wwn; 344 wwn_t wwn;
340 u32 unittype; 345 u32 unittype;
@@ -347,6 +352,23 @@ struct bfa_pport_rnid_s {
347 u16 topologydiscoveryflags; 352 u16 topologydiscoveryflags;
348}; 353};
349 354
355struct bfa_fcport_fcf_s {
356 wwn_t name; /* FCF name */
357 wwn_t fabric_name; /* Fabric Name */
358 u8 fipenabled; /* FIP enabled or not */
359 u8 fipfailed; /* FIP failed or not */
360 u8 resv[2];
361 u8 pri; /* FCF priority */
362 u8 version; /* FIP version used */
363 u8 available; /* Available for login */
364 u8 fka_disabled; /* FKA is disabled */
365 u8 maxsz_verified; /* FCoE max size verified */
366 u8 fc_map[3]; /* FC map */
367 u16 vlan; /* FCoE vlan tag/priority */
368 u32 fka_adv_per; /* FIP ka advert. period */
369 struct mac_s mac; /* FCF mac */
370};
371
350/** 372/**
351 * Link state information 373 * Link state information
352 */ 374 */
@@ -378,6 +400,7 @@ struct bfa_pport_link_s {
378 struct fc_alpabm_s alpabm; /* alpa bitmap */ 400 struct fc_alpabm_s alpabm; /* alpa bitmap */
379 } loop_info; 401 } loop_info;
380 } tl; 402 } tl;
403 struct bfa_fcport_fcf_s fcf; /*!< FCF information (for FCoE) */
381}; 404};
382 405
383#endif /* __BFA_DEFS_PPORT_H__ */ 406#endif /* __BFA_DEFS_PPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_status.h b/drivers/scsi/bfa/include/defs/bfa_defs_status.h
index cdceaeb9f4b8..4374494bd566 100644
--- a/drivers/scsi/bfa/include/defs/bfa_defs_status.h
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_status.h
@@ -180,8 +180,8 @@ enum bfa_status {
180 BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /* Given adapter is part 180 BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /* Given adapter is part
181 * of another team */ 181 * of another team */
182 BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /* Adapter has VLANs configured. 182 BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /* Adapter has VLANs configured.
183 * Delete all VLANs before 183 * Delete all VLANs to become
184 * creating team */ 184 * part of the team */
185 BFA_STATUS_IM_PVID_MISMATCH = 116, /* Mismatching PVIDs configured 185 BFA_STATUS_IM_PVID_MISMATCH = 116, /* Mismatching PVIDs configured
186 * for adapters */ 186 * for adapters */
187 BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /* Mismatching link speeds 187 BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /* Mismatching link speeds
@@ -213,7 +213,7 @@ enum bfa_status {
213 * loaded */ 213 * loaded */
214 BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */ 214 BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */
215 BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */ 215 BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */
216 BFA_STATUS_NO_DRIVER = 133, /* Storage/Ethernet driver not loaded */ 216 BFA_STATUS_NO_DRIVER = 133, /* Brocade adapter/driver not installed or loaded */
217 BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */ 217 BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */
218 BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */ 218 BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */
219 BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */ 219 BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */
@@ -228,8 +228,7 @@ enum bfa_status {
228 BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /* Acquiring Network Subsytem 228 BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /* Acquiring Network Subsytem
229 * handle Failed. Please try 229 * handle Failed. Please try
230 * after some time */ 230 * after some time */
231 BFA_STATUS_IM_NOT_BOUND = 143, /* Brocade 10G Ethernet Service is not 231 BFA_STATUS_IM_NOT_BOUND = 143, /* IM driver is not active */
232 * Enabled on this port */
233 BFA_STATUS_INSUFFICIENT_PERMS = 144, /* User doesn't have sufficient 232 BFA_STATUS_INSUFFICIENT_PERMS = 144, /* User doesn't have sufficient
234 * permissions to execute the BCU 233 * permissions to execute the BCU
235 * application */ 234 * application */
@@ -242,6 +241,14 @@ enum bfa_status {
242 * failed */ 241 * failed */
243 BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation 242 BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation
244 * failed */ 243 * failed */
244 BFA_STATUS_IM_PORT_IN_TEAM = 150, /* Port is already part of the
245 * team */
246 BFA_STATUS_IM_VLAN_NOT_FOUND = 151, /* VLAN ID doesn't exists */
247 BFA_STATUS_IM_TEAM_NOT_FOUND = 152, /* Teaming configuration doesn't
248 * exists */
249 BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, /* Given settings are not
250 * allowed for the current
251 * Teaming mode */
245 BFA_STATUS_MAX_VAL /* Unknown error code */ 252 BFA_STATUS_MAX_VAL /* Unknown error code */
246}; 253};
247#define bfa_status_t enum bfa_status 254#define bfa_status_t enum bfa_status
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
index a6c70aee0aa3..52585d3dd891 100644
--- a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
@@ -70,7 +70,6 @@ void bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv);
70 */ 70 */
71void bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv); 71void bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv);
72 72
73void bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim_drv);
74void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv); 73void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv);
75 74
76#endif /* __BFAD_FCB_FCPIM_H__ */ 75#endif /* __BFAD_FCB_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs.h b/drivers/scsi/bfa/include/fcs/bfa_fcs.h
index 627669c65546..f2fd35fdee28 100644
--- a/drivers/scsi/bfa/include/fcs/bfa_fcs.h
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs.h
@@ -49,6 +49,7 @@ struct bfa_fcs_s {
49 struct bfa_trc_mod_s *trcmod; /* tracing module */ 49 struct bfa_trc_mod_s *trcmod; /* tracing module */
50 struct bfa_aen_s *aen; /* aen component */ 50 struct bfa_aen_s *aen; /* aen component */
51 bfa_boolean_t vf_enabled; /* VF mode is enabled */ 51 bfa_boolean_t vf_enabled; /* VF mode is enabled */
52 bfa_boolean_t fdmi_enabled; /*!< FDMI is enabled */
52 bfa_boolean_t min_cfg; /* min cfg enabled/disabled */ 53 bfa_boolean_t min_cfg; /* min cfg enabled/disabled */
53 u16 port_vfid; /* port default VF ID */ 54 u16 port_vfid; /* port default VF ID */
54 struct bfa_fcs_driver_info_s driver_info; 55 struct bfa_fcs_driver_info_s driver_info;
@@ -60,10 +61,12 @@ struct bfa_fcs_s {
60/* 61/*
61 * bfa fcs API functions 62 * bfa fcs API functions
62 */ 63 */
63void bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, 64void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
64 bfa_boolean_t min_cfg); 65 bfa_boolean_t min_cfg);
66void bfa_fcs_init(struct bfa_fcs_s *fcs);
65void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, 67void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
66 struct bfa_fcs_driver_info_s *driver_info); 68 struct bfa_fcs_driver_info_s *driver_info);
69void bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable);
67void bfa_fcs_exit(struct bfa_fcs_s *fcs); 70void bfa_fcs_exit(struct bfa_fcs_s *fcs);
68void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod); 71void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod);
69void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod); 72void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod);
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
index 967ceb0eb074..ceaefd3060f4 100644
--- a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
@@ -34,14 +34,6 @@ struct bfa_fcs_s;
34struct bfa_fcs_fabric_s; 34struct bfa_fcs_fabric_s;
35 35
36/* 36/*
37* @todo : need to move to a global config file.
38 * Maximum Vports supported per physical port or vf.
39 */
40#define BFA_FCS_MAX_VPORTS_SUPP_CB 255
41#define BFA_FCS_MAX_VPORTS_SUPP_CT 191
42
43/*
44* @todo : need to move to a global config file.
45 * Maximum Rports supported per port (physical/logical). 37 * Maximum Rports supported per port (physical/logical).
46 */ 38 */
47#define BFA_FCS_MAX_RPORTS_SUPP 256 /* @todo : tentative value */ 39#define BFA_FCS_MAX_RPORTS_SUPP 256 /* @todo : tentative value */
diff --git a/drivers/scsi/bfa/include/log/bfa_log_hal.h b/drivers/scsi/bfa/include/log/bfa_log_hal.h
index 0412aea2ec30..5f8f5e30b9e8 100644
--- a/drivers/scsi/bfa/include/log/bfa_log_hal.h
+++ b/drivers/scsi/bfa/include/log/bfa_log_hal.h
@@ -27,4 +27,10 @@
27 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3) 27 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3)
28#define BFA_LOG_HAL_SM_ASSERT \ 28#define BFA_LOG_HAL_SM_ASSERT \
29 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4) 29 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4)
30#define BFA_LOG_HAL_DRIVER_ERROR \
31 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 5)
32#define BFA_LOG_HAL_DRIVER_CONFIG_ERROR \
33 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 6)
34#define BFA_LOG_HAL_MBOX_ERROR \
35 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 7)
30#endif 36#endif
diff --git a/drivers/scsi/bfa/include/log/bfa_log_linux.h b/drivers/scsi/bfa/include/log/bfa_log_linux.h
index 317c0547ee16..bd451db4c30a 100644
--- a/drivers/scsi/bfa/include/log/bfa_log_linux.h
+++ b/drivers/scsi/bfa/include/log/bfa_log_linux.h
@@ -41,4 +41,20 @@
41 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10) 41 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10)
42#define BFA_LOG_LINUX_SCSI_ABORT_COMP \ 42#define BFA_LOG_LINUX_SCSI_ABORT_COMP \
43 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11) 43 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11)
44#define BFA_LOG_LINUX_DRIVER_CONFIG_ERROR \
45 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 12)
46#define BFA_LOG_LINUX_BNA_STATE_MACHINE \
47 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 13)
48#define BFA_LOG_LINUX_IOC_ERROR \
49 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 14)
50#define BFA_LOG_LINUX_RESOURCE_ALLOC_ERROR \
51 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 15)
52#define BFA_LOG_LINUX_RING_BUFFER_ERROR \
53 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 16)
54#define BFA_LOG_LINUX_DRIVER_ERROR \
55 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 17)
56#define BFA_LOG_LINUX_DRIVER_DIAG \
57 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 18)
58#define BFA_LOG_LINUX_DRIVER_AEN \
59 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 19)
44#endif 60#endif
diff --git a/drivers/scsi/bfa/include/protocol/fc.h b/drivers/scsi/bfa/include/protocol/fc.h
index 14969eecf6a9..8d1038035a76 100644
--- a/drivers/scsi/bfa/include/protocol/fc.h
+++ b/drivers/scsi/bfa/include/protocol/fc.h
@@ -50,6 +50,11 @@ struct fchs_s {
50 50
51 u32 ro; /* relative offset */ 51 u32 ro; /* relative offset */
52}; 52};
53
54#define FC_SOF_LEN 4
55#define FC_EOF_LEN 4
56#define FC_CRC_LEN 4
57
53/* 58/*
54 * Fibre Channel BB_E Header Structure 59 * Fibre Channel BB_E Header Structure
55 */ 60 */
diff --git a/drivers/scsi/bfa/include/protocol/pcifw.h b/drivers/scsi/bfa/include/protocol/pcifw.h
deleted file mode 100644
index 6830dc3ee58a..000000000000
--- a/drivers/scsi/bfa/include/protocol/pcifw.h
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * pcifw.h PCI FW related headers
20 */
21
22#ifndef __PCIFW_H__
23#define __PCIFW_H__
24
25#pragma pack(1)
26
27struct pnp_hdr_s{
28 u32 signature; /* "$PnP" */
29 u8 rev; /* Struct revision */
30 u8 len; /* Header structure len in multiples
31 * of 16 bytes */
32 u16 off; /* Offset to next header 00 if none */
33 u8 rsvd; /* Reserved byte */
34 u8 cksum; /* 8-bit checksum for this header */
35 u32 pnp_dev_id; /* PnP Device Id */
36 u16 mfstr; /* Pointer to manufacturer string */
37 u16 prstr; /* Pointer to product string */
38 u8 devtype[3]; /* Device Type Code */
39 u8 devind; /* Device Indicator */
40 u16 bcventr; /* Bootstrap entry vector */
41 u16 rsvd2; /* Reserved */
42 u16 sriv; /* Static resource information vector */
43};
44
45struct pci_3_0_ds_s{
46 u32 sig; /* Signature "PCIR" */
47 u16 vendid; /* Vendor ID */
48 u16 devid; /* Device ID */
49 u16 devlistoff; /* Device List Offset */
50 u16 len; /* PCI Data Structure Length */
51 u8 rev; /* PCI Data Structure Revision */
52 u8 clcode[3]; /* Class Code */
53 u16 imglen; /* Code image length in multiples of
54 * 512 bytes */
55 u16 coderev; /* Revision level of code/data */
56 u8 codetype; /* Code type 0x00 - BIOS */
57 u8 indr; /* Last image indicator */
58 u16 mrtimglen; /* Max Run Time Image Length */
59 u16 cuoff; /* Config Utility Code Header Offset */
60 u16 dmtfclp; /* DMTF CLP entry point offset */
61};
62
63struct pci_optrom_hdr_s{
64 u16 sig; /* Signature 0x55AA */
65 u8 len; /* Option ROM length in units of 512 bytes */
66 u8 inivec[3]; /* Initialization vector */
67 u8 rsvd[16]; /* Reserved field */
68 u16 verptr; /* Pointer to version string - private */
69 u16 pcids; /* Pointer to PCI data structure */
70 u16 pnphdr; /* Pointer to PnP expansion header */
71};
72
73#pragma pack()
74
75#endif
diff --git a/drivers/scsi/bfa/loop.c b/drivers/scsi/bfa/loop.c
index f7c7f4f3c640..f6342efb6a90 100644
--- a/drivers/scsi/bfa/loop.c
+++ b/drivers/scsi/bfa/loop.c
@@ -162,7 +162,7 @@ bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, u8 alpa)
162 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa, 162 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
163 bfa_fcs_port_get_fcid(port), 0, 163 bfa_fcs_port_get_fcid(port), 0,
164 port->port_cfg.pwwn, port->port_cfg.nwwn, 164 port->port_cfg.pwwn, port->port_cfg.nwwn,
165 bfa_pport_get_maxfrsize(port->fcs->bfa)); 165 bfa_fcport_get_maxfrsize(port->fcs->bfa));
166 166
167 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 167 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
168 FC_CLASS_3, len, &fchs, 168 FC_CLASS_3, len, &fchs,
diff --git a/drivers/scsi/bfa/lport_api.c b/drivers/scsi/bfa/lport_api.c
index 1e06792cd4c2..d3907d184e2b 100644
--- a/drivers/scsi/bfa/lport_api.c
+++ b/drivers/scsi/bfa/lport_api.c
@@ -156,7 +156,7 @@ bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port)
156 /* 156 /*
157 * Get Physical port's current speed 157 * Get Physical port's current speed
158 */ 158 */
159 bfa_pport_get_attr(port->fcs->bfa, &pport_attr); 159 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
160 pport_speed = pport_attr.speed; 160 pport_speed = pport_attr.speed;
161 bfa_trc(fcs, pport_speed); 161 bfa_trc(fcs, pport_speed);
162 162
@@ -235,7 +235,8 @@ bfa_fcs_port_get_info(struct bfa_fcs_port_s *port,
235 port_info->port_wwn = bfa_fcs_port_get_pwwn(port); 235 port_info->port_wwn = bfa_fcs_port_get_pwwn(port);
236 port_info->node_wwn = bfa_fcs_port_get_nwwn(port); 236 port_info->node_wwn = bfa_fcs_port_get_nwwn(port);
237 237
238 port_info->max_vports_supp = bfa_fcs_vport_get_max(port->fcs); 238 port_info->max_vports_supp =
239 bfa_lps_get_max_vport(port->fcs->bfa);
239 port_info->num_vports_inuse = 240 port_info->num_vports_inuse =
240 bfa_fcs_fabric_vport_count(port->fabric); 241 bfa_fcs_fabric_vport_count(port->fabric);
241 port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; 242 port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
diff --git a/drivers/scsi/bfa/ms.c b/drivers/scsi/bfa/ms.c
index c96b3ca007ae..5e8c8dee6c97 100644
--- a/drivers/scsi/bfa/ms.c
+++ b/drivers/scsi/bfa/ms.c
@@ -118,7 +118,7 @@ bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
118 break; 118 break;
119 119
120 default: 120 default:
121 bfa_assert(0); 121 bfa_sm_fault(ms->port->fcs, event);
122 } 122 }
123} 123}
124 124
@@ -141,7 +141,7 @@ bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
141 break; 141 break;
142 142
143 default: 143 default:
144 bfa_assert(0); 144 bfa_sm_fault(ms->port->fcs, event);
145 } 145 }
146} 146}
147 147
@@ -190,7 +190,7 @@ bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
190 break; 190 break;
191 191
192 default: 192 default:
193 bfa_assert(0); 193 bfa_sm_fault(ms->port->fcs, event);
194 } 194 }
195} 195}
196 196
@@ -216,7 +216,7 @@ bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
216 break; 216 break;
217 217
218 default: 218 default:
219 bfa_assert(0); 219 bfa_sm_fault(ms->port->fcs, event);
220 } 220 }
221} 221}
222 222
@@ -230,10 +230,6 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
230 switch (event) { 230 switch (event) {
231 case MSSM_EVENT_PORT_OFFLINE: 231 case MSSM_EVENT_PORT_OFFLINE:
232 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); 232 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
233 /*
234 * now invoke MS related sub-modules
235 */
236 bfa_fcs_port_fdmi_offline(ms);
237 break; 233 break;
238 234
239 case MSSM_EVENT_PORT_FABRIC_RSCN: 235 case MSSM_EVENT_PORT_FABRIC_RSCN:
@@ -243,7 +239,7 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
243 break; 239 break;
244 240
245 default: 241 default:
246 bfa_assert(0); 242 bfa_sm_fault(ms->port->fcs, event);
247 } 243 }
248} 244}
249 245
@@ -266,7 +262,7 @@ bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
266 break; 262 break;
267 263
268 default: 264 default:
269 bfa_assert(0); 265 bfa_sm_fault(ms->port->fcs, event);
270 } 266 }
271} 267}
272 268
@@ -304,7 +300,7 @@ bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
304 break; 300 break;
305 301
306 default: 302 default:
307 bfa_assert(0); 303 bfa_sm_fault(ms->port->fcs, event);
308 } 304 }
309} 305}
310 306
@@ -330,7 +326,7 @@ bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
330 break; 326 break;
331 327
332 default: 328 default:
333 bfa_assert(0); 329 bfa_sm_fault(ms->port->fcs, event);
334 } 330 }
335} 331}
336 332
@@ -466,7 +462,7 @@ bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
466 break; 462 break;
467 463
468 default: 464 default:
469 bfa_assert(0); 465 bfa_sm_fault(ms->port->fcs, event);
470 } 466 }
471} 467}
472 468
@@ -502,7 +498,7 @@ bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
502 break; 498 break;
503 499
504 default: 500 default:
505 bfa_assert(0); 501 bfa_sm_fault(ms->port->fcs, event);
506 } 502 }
507} 503}
508 504
@@ -528,7 +524,7 @@ bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
528 break; 524 break;
529 525
530 default: 526 default:
531 bfa_assert(0); 527 bfa_sm_fault(ms->port->fcs, event);
532 } 528 }
533} 529}
534 530
@@ -637,7 +633,7 @@ bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
637 bfa_os_hton3b(FC_MGMT_SERVER), 633 bfa_os_hton3b(FC_MGMT_SERVER),
638 bfa_fcs_port_get_fcid(port), 0, 634 bfa_fcs_port_get_fcid(port), 0,
639 port->port_cfg.pwwn, port->port_cfg.nwwn, 635 port->port_cfg.pwwn, port->port_cfg.nwwn,
640 bfa_pport_get_maxfrsize(port->fcs->bfa)); 636 bfa_fcport_get_maxfrsize(port->fcs->bfa));
641 637
642 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 638 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
643 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response, 639 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response,
@@ -735,6 +731,7 @@ bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port)
735 731
736 ms->port = port; 732 ms->port = port;
737 bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); 733 bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
734 bfa_fcs_port_fdmi_offline(ms);
738} 735}
739 736
740void 737void
diff --git a/drivers/scsi/bfa/ns.c b/drivers/scsi/bfa/ns.c
index 2f8b880060bb..d20dd7e15742 100644
--- a/drivers/scsi/bfa/ns.c
+++ b/drivers/scsi/bfa/ns.c
@@ -164,7 +164,7 @@ bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
164 break; 164 break;
165 165
166 default: 166 default:
167 bfa_assert(0); 167 bfa_sm_fault(ns->port->fcs, event);
168 } 168 }
169} 169}
170 170
@@ -187,7 +187,7 @@ bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
187 break; 187 break;
188 188
189 default: 189 default:
190 bfa_assert(0); 190 bfa_sm_fault(ns->port->fcs, event);
191 } 191 }
192} 192}
193 193
@@ -221,7 +221,7 @@ bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
221 break; 221 break;
222 222
223 default: 223 default:
224 bfa_assert(0); 224 bfa_sm_fault(ns->port->fcs, event);
225 } 225 }
226} 226}
227 227
@@ -247,7 +247,7 @@ bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
247 break; 247 break;
248 248
249 default: 249 default:
250 bfa_assert(0); 250 bfa_sm_fault(ns->port->fcs, event);
251 } 251 }
252} 252}
253 253
@@ -270,7 +270,7 @@ bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
270 break; 270 break;
271 271
272 default: 272 default:
273 bfa_assert(0); 273 bfa_sm_fault(ns->port->fcs, event);
274 } 274 }
275} 275}
276 276
@@ -304,7 +304,7 @@ bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
304 break; 304 break;
305 305
306 default: 306 default:
307 bfa_assert(0); 307 bfa_sm_fault(ns->port->fcs, event);
308 } 308 }
309} 309}
310 310
@@ -330,7 +330,7 @@ bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
330 break; 330 break;
331 331
332 default: 332 default:
333 bfa_assert(0); 333 bfa_sm_fault(ns->port->fcs, event);
334 } 334 }
335} 335}
336 336
@@ -353,7 +353,7 @@ bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
353 break; 353 break;
354 354
355 default: 355 default:
356 bfa_assert(0); 356 bfa_sm_fault(ns->port->fcs, event);
357 } 357 }
358} 358}
359 359
@@ -390,7 +390,7 @@ bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
390 break; 390 break;
391 391
392 default: 392 default:
393 bfa_assert(0); 393 bfa_sm_fault(ns->port->fcs, event);
394 } 394 }
395} 395}
396 396
@@ -413,7 +413,7 @@ bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
413 break; 413 break;
414 414
415 default: 415 default:
416 bfa_assert(0); 416 bfa_sm_fault(ns->port->fcs, event);
417 } 417 }
418} 418}
419 419
@@ -436,7 +436,7 @@ bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
436 break; 436 break;
437 437
438 default: 438 default:
439 bfa_assert(0); 439 bfa_sm_fault(ns->port->fcs, event);
440 } 440 }
441} 441}
442 442
@@ -494,7 +494,7 @@ bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
494 break; 494 break;
495 495
496 default: 496 default:
497 bfa_assert(0); 497 bfa_sm_fault(ns->port->fcs, event);
498 } 498 }
499} 499}
500 500
@@ -517,7 +517,7 @@ bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
517 break; 517 break;
518 518
519 default: 519 default:
520 bfa_assert(0); 520 bfa_sm_fault(ns->port->fcs, event);
521 } 521 }
522} 522}
523static void 523static void
@@ -539,7 +539,7 @@ bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
539 break; 539 break;
540 540
541 default: 541 default:
542 bfa_assert(0); 542 bfa_sm_fault(ns->port->fcs, event);
543 } 543 }
544} 544}
545 545
@@ -575,7 +575,7 @@ bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
575 break; 575 break;
576 576
577 default: 577 default:
578 bfa_assert(0); 578 bfa_sm_fault(ns->port->fcs, event);
579 } 579 }
580} 580}
581 581
@@ -598,7 +598,7 @@ bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
598 break; 598 break;
599 599
600 default: 600 default:
601 bfa_assert(0); 601 bfa_sm_fault(ns->port->fcs, event);
602 } 602 }
603} 603}
604 604
@@ -626,7 +626,7 @@ bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
626 break; 626 break;
627 627
628 default: 628 default:
629 bfa_assert(0); 629 bfa_sm_fault(ns->port->fcs, event);
630 } 630 }
631} 631}
632 632
@@ -660,7 +660,7 @@ bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
660 bfa_os_hton3b(FC_NAME_SERVER), 660 bfa_os_hton3b(FC_NAME_SERVER),
661 bfa_fcs_port_get_fcid(port), 0, 661 bfa_fcs_port_get_fcid(port), 0,
662 port->port_cfg.pwwn, port->port_cfg.nwwn, 662 port->port_cfg.pwwn, port->port_cfg.nwwn,
663 bfa_pport_get_maxfrsize(port->fcs->bfa)); 663 bfa_fcport_get_maxfrsize(port->fcs->bfa));
664 664
665 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 665 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
666 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response, 666 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response,
diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c
index 9cf58bb138dc..8e73dd9a625a 100644
--- a/drivers/scsi/bfa/rport.c
+++ b/drivers/scsi/bfa/rport.c
@@ -224,7 +224,7 @@ bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
224 break; 224 break;
225 225
226 default: 226 default:
227 bfa_assert(0); 227 bfa_sm_fault(rport->fcs, event);
228 } 228 }
229} 229}
230 230
@@ -276,7 +276,7 @@ bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
276 break; 276 break;
277 277
278 default: 278 default:
279 bfa_assert(0); 279 bfa_sm_fault(rport->fcs, event);
280 } 280 }
281} 281}
282 282
@@ -332,7 +332,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
332 break; 332 break;
333 333
334 default: 334 default:
335 bfa_assert(0); 335 bfa_sm_fault(rport->fcs, event);
336 } 336 }
337} 337}
338 338
@@ -406,7 +406,7 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
406 break; 406 break;
407 407
408 default: 408 default:
409 bfa_assert(0); 409 bfa_sm_fault(rport->fcs, event);
410 } 410 }
411} 411}
412 412
@@ -481,7 +481,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
481 break; 481 break;
482 482
483 default: 483 default:
484 bfa_assert(0); 484 bfa_sm_fault(rport->fcs, event);
485 } 485 }
486} 486}
487 487
@@ -534,7 +534,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
534 break; 534 break;
535 535
536 default: 536 default:
537 bfa_assert(0); 537 bfa_sm_fault(rport->fcs, event);
538 } 538 }
539} 539}
540 540
@@ -589,7 +589,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
589 break; 589 break;
590 590
591 default: 591 default:
592 bfa_assert(0); 592 bfa_sm_fault(rport->fcs, event);
593 } 593 }
594} 594}
595 595
@@ -646,7 +646,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
646 break; 646 break;
647 647
648 default: 648 default:
649 bfa_assert(0); 649 bfa_sm_fault(rport->fcs, event);
650 } 650 }
651} 651}
652 652
@@ -704,7 +704,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
704 break; 704 break;
705 705
706 default: 706 default:
707 bfa_assert(0); 707 bfa_sm_fault(rport->fcs, event);
708 } 708 }
709} 709}
710 710
@@ -754,7 +754,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
754 break; 754 break;
755 755
756 default: 756 default:
757 bfa_assert(0); 757 bfa_sm_fault(rport->fcs, event);
758 } 758 }
759} 759}
760 760
@@ -816,7 +816,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
816 break; 816 break;
817 817
818 default: 818 default:
819 bfa_assert(0); 819 bfa_sm_fault(rport->fcs, event);
820 } 820 }
821} 821}
822 822
@@ -846,7 +846,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
846 break; 846 break;
847 847
848 default: 848 default:
849 bfa_assert(0); 849 bfa_sm_fault(rport->fcs, event);
850 } 850 }
851} 851}
852 852
@@ -869,7 +869,7 @@ bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
869 break; 869 break;
870 870
871 default: 871 default:
872 bfa_assert(0); 872 bfa_sm_fault(rport->fcs, event);
873 } 873 }
874} 874}
875 875
@@ -905,7 +905,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
905 break; 905 break;
906 906
907 default: 907 default:
908 bfa_assert(0); 908 bfa_sm_fault(rport->fcs, event);
909 } 909 }
910} 910}
911 911
@@ -925,10 +925,17 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
925 case RPSM_EVENT_HCB_OFFLINE: 925 case RPSM_EVENT_HCB_OFFLINE:
926 case RPSM_EVENT_ADDRESS_CHANGE: 926 case RPSM_EVENT_ADDRESS_CHANGE:
927 if (bfa_fcs_port_is_online(rport->port)) { 927 if (bfa_fcs_port_is_online(rport->port)) {
928 bfa_sm_set_state(rport, 928 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
929 bfa_fcs_rport_sm_nsdisc_sending); 929 bfa_sm_set_state(rport,
930 rport->ns_retries = 0; 930 bfa_fcs_rport_sm_nsdisc_sending);
931 bfa_fcs_rport_send_gidpn(rport, NULL); 931 rport->ns_retries = 0;
932 bfa_fcs_rport_send_gidpn(rport, NULL);
933 } else {
934 bfa_sm_set_state(rport,
935 bfa_fcs_rport_sm_plogi_sending);
936 rport->plogi_retries = 0;
937 bfa_fcs_rport_send_plogi(rport, NULL);
938 }
932 } else { 939 } else {
933 rport->pid = 0; 940 rport->pid = 0;
934 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 941 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
@@ -951,7 +958,7 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
951 break; 958 break;
952 959
953 default: 960 default:
954 bfa_assert(0); 961 bfa_sm_fault(rport->fcs, event);
955 } 962 }
956} 963}
957 964
@@ -1011,7 +1018,7 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
1011 break; 1018 break;
1012 1019
1013 default: 1020 default:
1014 bfa_assert(0); 1021 bfa_sm_fault(rport->fcs, event);
1015 } 1022 }
1016} 1023}
1017 1024
@@ -1038,7 +1045,7 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1038 break; 1045 break;
1039 1046
1040 default: 1047 default:
1041 bfa_assert(0); 1048 bfa_sm_fault(rport->fcs, event);
1042 } 1049 }
1043} 1050}
1044 1051
@@ -1073,7 +1080,7 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1073 break; 1080 break;
1074 1081
1075 default: 1082 default:
1076 bfa_assert(0); 1083 bfa_sm_fault(rport->fcs, event);
1077 } 1084 }
1078} 1085}
1079 1086
@@ -1132,7 +1139,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1132 break; 1139 break;
1133 1140
1134 default: 1141 default:
1135 bfa_assert(0); 1142 bfa_sm_fault(rport->fcs, event);
1136 } 1143 }
1137} 1144}
1138 1145
@@ -1188,7 +1195,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1188 break; 1195 break;
1189 1196
1190 default: 1197 default:
1191 bfa_assert(0); 1198 bfa_sm_fault(rport->fcs, event);
1192 } 1199 }
1193} 1200}
1194 1201
@@ -1249,7 +1256,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1249 break; 1256 break;
1250 1257
1251 default: 1258 default:
1252 bfa_assert(0); 1259 bfa_sm_fault(rport->fcs, event);
1253 } 1260 }
1254} 1261}
1255 1262
@@ -1334,7 +1341,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1334 break; 1341 break;
1335 1342
1336 default: 1343 default:
1337 bfa_assert(0); 1344 bfa_sm_fault(rport->fcs, event);
1338 } 1345 }
1339} 1346}
1340 1347
@@ -1366,7 +1373,7 @@ bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1366 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 1373 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1367 bfa_fcs_port_get_fcid(port), 0, 1374 bfa_fcs_port_get_fcid(port), 0,
1368 port->port_cfg.pwwn, port->port_cfg.nwwn, 1375 port->port_cfg.pwwn, port->port_cfg.nwwn,
1369 bfa_pport_get_maxfrsize(port->fcs->bfa)); 1376 bfa_fcport_get_maxfrsize(port->fcs->bfa));
1370 1377
1371 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1378 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1372 FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response, 1379 FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
@@ -1478,7 +1485,7 @@ bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1478 len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, 1485 len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1479 bfa_fcs_port_get_fcid(port), rport->reply_oxid, 1486 bfa_fcs_port_get_fcid(port), rport->reply_oxid,
1480 port->port_cfg.pwwn, port->port_cfg.nwwn, 1487 port->port_cfg.pwwn, port->port_cfg.nwwn,
1481 bfa_pport_get_maxfrsize(port->fcs->bfa)); 1488 bfa_fcport_get_maxfrsize(port->fcs->bfa));
1482 1489
1483 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, 1490 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1484 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); 1491 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
@@ -1813,7 +1820,7 @@ bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
1813 /* 1820 /*
1814 * get curent speed from pport attributes from BFA 1821 * get curent speed from pport attributes from BFA
1815 */ 1822 */
1816 bfa_pport_get_attr(port->fcs->bfa, &pport_attr); 1823 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
1817 1824
1818 speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed); 1825 speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
1819 1826
@@ -2032,13 +2039,10 @@ bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
2032 2039
2033 switch (event) { 2040 switch (event) {
2034 case BFA_RPORT_AEN_ONLINE: 2041 case BFA_RPORT_AEN_ONLINE:
2035 bfa_log(logmod, BFA_AEN_RPORT_ONLINE, rpwwn_ptr, lpwwn_ptr);
2036 break;
2037 case BFA_RPORT_AEN_OFFLINE: 2042 case BFA_RPORT_AEN_OFFLINE:
2038 bfa_log(logmod, BFA_AEN_RPORT_OFFLINE, rpwwn_ptr, lpwwn_ptr);
2039 break;
2040 case BFA_RPORT_AEN_DISCONNECT: 2043 case BFA_RPORT_AEN_DISCONNECT:
2041 bfa_log(logmod, BFA_AEN_RPORT_DISCONNECT, rpwwn_ptr, lpwwn_ptr); 2044 bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, event),
2045 rpwwn_ptr, lpwwn_ptr);
2042 break; 2046 break;
2043 case BFA_RPORT_AEN_QOS_PRIO: 2047 case BFA_RPORT_AEN_QOS_PRIO:
2044 aen_data.rport.priv.qos = data->priv.qos; 2048 aen_data.rport.priv.qos = data->priv.qos;
@@ -2164,7 +2168,7 @@ bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2164 bfa_trc(port->fcs, port->fabric->bb_credit); 2168 bfa_trc(port->fcs, port->fabric->bb_credit);
2165 2169
2166 port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred); 2170 port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred);
2167 bfa_pport_set_tx_bbcredit(port->fcs->bfa, 2171 bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
2168 port->fabric->bb_credit); 2172 port->fabric->bb_credit);
2169 } 2173 }
2170 2174
@@ -2575,23 +2579,6 @@ bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2575} 2579}
2576 2580
2577/** 2581/**
2578 * Module initialization
2579 */
2580void
2581bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs)
2582{
2583}
2584
2585/**
2586 * Module cleanup
2587 */
2588void
2589bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs)
2590{
2591 bfa_fcs_modexit_comp(fcs);
2592}
2593
2594/**
2595 * Return state of rport. 2582 * Return state of rport.
2596 */ 2583 */
2597int 2584int
diff --git a/drivers/scsi/bfa/rport_api.c b/drivers/scsi/bfa/rport_api.c
index 3dae1774181e..a441f41d2a64 100644
--- a/drivers/scsi/bfa/rport_api.c
+++ b/drivers/scsi/bfa/rport_api.c
@@ -102,7 +102,7 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
102 rport_attr->qos_attr = qos_attr; 102 rport_attr->qos_attr = qos_attr;
103 103
104 rport_attr->trl_enforced = BFA_FALSE; 104 rport_attr->trl_enforced = BFA_FALSE;
105 if (bfa_pport_is_ratelim(port->fcs->bfa)) { 105 if (bfa_fcport_is_ratelim(port->fcs->bfa)) {
106 if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) || 106 if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) ||
107 (rport->rpf.rpsc_speed < 107 (rport->rpf.rpsc_speed <
108 bfa_fcs_port_get_rport_max_speed(port))) 108 bfa_fcs_port_get_rport_max_speed(port)))
diff --git a/drivers/scsi/bfa/rport_ftrs.c b/drivers/scsi/bfa/rport_ftrs.c
index e1932c885ac2..ae7bba67ae2a 100644
--- a/drivers/scsi/bfa/rport_ftrs.c
+++ b/drivers/scsi/bfa/rport_ftrs.c
@@ -91,7 +91,7 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
91 break; 91 break;
92 92
93 default: 93 default:
94 bfa_assert(0); 94 bfa_sm_fault(rport->fcs, event);
95 } 95 }
96} 96}
97 97
@@ -114,7 +114,7 @@ bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
114 break; 114 break;
115 115
116 default: 116 default:
117 bfa_assert(0); 117 bfa_sm_fault(rport->fcs, event);
118 } 118 }
119} 119}
120 120
@@ -160,7 +160,7 @@ bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
160 break; 160 break;
161 161
162 default: 162 default:
163 bfa_assert(0); 163 bfa_sm_fault(rport->fcs, event);
164 } 164 }
165} 165}
166 166
@@ -186,7 +186,7 @@ bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
186 break; 186 break;
187 187
188 default: 188 default:
189 bfa_assert(0); 189 bfa_sm_fault(rport->fcs, event);
190 } 190 }
191} 191}
192 192
@@ -206,7 +206,7 @@ bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
206 break; 206 break;
207 207
208 default: 208 default:
209 bfa_assert(0); 209 bfa_sm_fault(rport->fcs, event);
210 } 210 }
211} 211}
212 212
@@ -229,7 +229,7 @@ bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
229 break; 229 break;
230 230
231 default: 231 default:
232 bfa_assert(0); 232 bfa_sm_fault(rport->fcs, event);
233 } 233 }
234} 234}
235/** 235/**
diff --git a/drivers/scsi/bfa/scn.c b/drivers/scsi/bfa/scn.c
index bd4771ff62c8..8fe09ba88a91 100644
--- a/drivers/scsi/bfa/scn.c
+++ b/drivers/scsi/bfa/scn.c
@@ -90,7 +90,7 @@ bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn,
90 break; 90 break;
91 91
92 default: 92 default:
93 bfa_assert(0); 93 bfa_sm_fault(scn->port->fcs, event);
94 } 94 }
95} 95}
96 96
@@ -109,7 +109,7 @@ bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn,
109 break; 109 break;
110 110
111 default: 111 default:
112 bfa_assert(0); 112 bfa_sm_fault(scn->port->fcs, event);
113 } 113 }
114} 114}
115 115
@@ -137,7 +137,7 @@ bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn,
137 break; 137 break;
138 138
139 default: 139 default:
140 bfa_assert(0); 140 bfa_sm_fault(scn->port->fcs, event);
141 } 141 }
142} 142}
143 143
@@ -157,7 +157,7 @@ bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn,
157 break; 157 break;
158 158
159 default: 159 default:
160 bfa_assert(0); 160 bfa_sm_fault(scn->port->fcs, event);
161 } 161 }
162} 162}
163 163
@@ -171,7 +171,7 @@ bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn,
171 break; 171 break;
172 172
173 default: 173 default:
174 bfa_assert(0); 174 bfa_sm_fault(scn->port->fcs, event);
175 } 175 }
176} 176}
177 177
diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c
index e90f1e38c32d..27cd619a227a 100644
--- a/drivers/scsi/bfa/vport.c
+++ b/drivers/scsi/bfa/vport.c
@@ -122,7 +122,7 @@ bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
122 break; 122 break;
123 123
124 default: 124 default:
125 bfa_assert(0); 125 bfa_sm_fault(__vport_fcs(vport), event);
126 } 126 }
127} 127}
128 128
@@ -165,7 +165,7 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
165 break; 165 break;
166 166
167 default: 167 default:
168 bfa_assert(0); 168 bfa_sm_fault(__vport_fcs(vport), event);
169 } 169 }
170} 170}
171 171
@@ -202,7 +202,7 @@ bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
202 break; 202 break;
203 203
204 default: 204 default:
205 bfa_assert(0); 205 bfa_sm_fault(__vport_fcs(vport), event);
206 } 206 }
207} 207}
208 208
@@ -249,7 +249,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
249 break; 249 break;
250 250
251 default: 251 default:
252 bfa_assert(0); 252 bfa_sm_fault(__vport_fcs(vport), event);
253 } 253 }
254} 254}
255 255
@@ -283,7 +283,7 @@ bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
283 break; 283 break;
284 284
285 default: 285 default:
286 bfa_assert(0); 286 bfa_sm_fault(__vport_fcs(vport), event);
287 } 287 }
288} 288}
289 289
@@ -310,7 +310,7 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
310 break; 310 break;
311 311
312 default: 312 default:
313 bfa_assert(0); 313 bfa_sm_fault(__vport_fcs(vport), event);
314 } 314 }
315} 315}
316 316
@@ -339,7 +339,7 @@ bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
339 break; 339 break;
340 340
341 default: 341 default:
342 bfa_assert(0); 342 bfa_sm_fault(__vport_fcs(vport), event);
343 } 343 }
344} 344}
345 345
@@ -387,7 +387,7 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
387 break; 387 break;
388 388
389 default: 389 default:
390 bfa_assert(0); 390 bfa_sm_fault(__vport_fcs(vport), event);
391 } 391 }
392} 392}
393 393
@@ -419,7 +419,7 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
419 break; 419 break;
420 420
421 default: 421 default:
422 bfa_assert(0); 422 bfa_sm_fault(__vport_fcs(vport), event);
423 } 423 }
424} 424}
425 425
@@ -447,22 +447,8 @@ bfa_fcs_vport_aen_post(bfa_fcs_lport_t *port, enum bfa_lport_aen_event event)
447 447
448 bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); 448 bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
449 449
450 switch (event) { 450 bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
451 case BFA_LPORT_AEN_NPIV_DUP_WWN: 451 role_str[role/2]);
452 bfa_log(logmod, BFA_AEN_LPORT_NPIV_DUP_WWN, lpwwn_ptr,
453 role_str[role / 2]);
454 break;
455 case BFA_LPORT_AEN_NPIV_FABRIC_MAX:
456 bfa_log(logmod, BFA_AEN_LPORT_NPIV_FABRIC_MAX, lpwwn_ptr,
457 role_str[role / 2]);
458 break;
459 case BFA_LPORT_AEN_NPIV_UNKNOWN:
460 bfa_log(logmod, BFA_AEN_LPORT_NPIV_UNKNOWN, lpwwn_ptr,
461 role_str[role / 2]);
462 break;
463 default:
464 break;
465 }
466 452
467 aen_data.lport.vf_id = port->fabric->vf_id; 453 aen_data.lport.vf_id = port->fabric->vf_id;
468 aen_data.lport.roles = role; 454 aen_data.lport.roles = role;
@@ -478,7 +464,7 @@ static void
478bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) 464bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
479{ 465{
480 bfa_lps_fdisc(vport->lps, vport, 466 bfa_lps_fdisc(vport->lps, vport,
481 bfa_pport_get_maxfrsize(__vport_bfa(vport)), 467 bfa_fcport_get_maxfrsize(__vport_bfa(vport)),
482 __vport_pwwn(vport), __vport_nwwn(vport)); 468 __vport_pwwn(vport), __vport_nwwn(vport));
483 vport->vport_stats.fdisc_sent++; 469 vport->vport_stats.fdisc_sent++;
484} 470}
@@ -617,38 +603,6 @@ bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
617} 603}
618 604
619/** 605/**
620 * Module initialization
621 */
622void
623bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs)
624{
625}
626
627/**
628 * Module cleanup
629 */
630void
631bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs)
632{
633 bfa_fcs_modexit_comp(fcs);
634}
635
636u32
637bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs)
638{
639 struct bfa_ioc_attr_s ioc_attr;
640
641 bfa_get_attr(fcs->bfa, &ioc_attr);
642
643 if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT)
644 return BFA_FCS_MAX_VPORTS_SUPP_CT;
645 else
646 return BFA_FCS_MAX_VPORTS_SUPP_CB;
647}
648
649
650
651/**
652 * fcs_vport_api Virtual port API 606 * fcs_vport_api Virtual port API
653 */ 607 */
654 608
@@ -684,7 +638,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
684 return BFA_STATUS_VPORT_EXISTS; 638 return BFA_STATUS_VPORT_EXISTS;
685 639
686 if (bfa_fcs_fabric_vport_count(&fcs->fabric) == 640 if (bfa_fcs_fabric_vport_count(&fcs->fabric) ==
687 bfa_fcs_vport_get_max(fcs)) 641 bfa_lps_get_max_vport(fcs->bfa))
688 return BFA_STATUS_VPORT_MAX; 642 return BFA_STATUS_VPORT_MAX;
689 643
690 vport->lps = bfa_lps_alloc(fcs->bfa); 644 vport->lps = bfa_lps_alloc(fcs->bfa);
@@ -694,7 +648,8 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
694 vport->vport_drv = vport_drv; 648 vport->vport_drv = vport_drv;
695 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); 649 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
696 650
697 bfa_fcs_lport_init(&vport->lport, fcs, vf_id, vport_cfg, vport); 651 bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
652 bfa_fcs_lport_init(&vport->lport, vport_cfg);
698 653
699 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); 654 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
700 655
@@ -888,4 +843,15 @@ bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
888 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); 843 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
889} 844}
890 845
846/**
847 * Received clear virtual link
848 */
849void
850bfa_cb_lps_cvl_event(void *bfad, void *uarg)
851{
852 struct bfa_fcs_vport_s *vport = uarg;
891 853
854 /* Send an Offline followed by an ONLINE */
855 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
856 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
857}
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 1c4d1215769d..cb71dc984797 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1989,7 +1989,7 @@ static struct scsi_host_template bnx2i_host_template = {
1989 .queuecommand = iscsi_queuecommand, 1989 .queuecommand = iscsi_queuecommand,
1990 .eh_abort_handler = iscsi_eh_abort, 1990 .eh_abort_handler = iscsi_eh_abort,
1991 .eh_device_reset_handler = iscsi_eh_device_reset, 1991 .eh_device_reset_handler = iscsi_eh_device_reset,
1992 .eh_target_reset_handler = iscsi_eh_target_reset, 1992 .eh_target_reset_handler = iscsi_eh_recover_target,
1993 .change_queue_depth = iscsi_change_queue_depth, 1993 .change_queue_depth = iscsi_change_queue_depth,
1994 .can_queue = 1024, 1994 .can_queue = 1024,
1995 .max_sectors = 127, 1995 .max_sectors = 127,
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index 412853c65372..b7c30585dadd 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -915,7 +915,7 @@ static struct scsi_host_template cxgb3i_host_template = {
915 .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, 915 .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
916 .eh_abort_handler = iscsi_eh_abort, 916 .eh_abort_handler = iscsi_eh_abort,
917 .eh_device_reset_handler = iscsi_eh_device_reset, 917 .eh_device_reset_handler = iscsi_eh_device_reset,
918 .eh_target_reset_handler = iscsi_eh_target_reset, 918 .eh_target_reset_handler = iscsi_eh_recover_target,
919 .target_alloc = iscsi_target_alloc, 919 .target_alloc = iscsi_target_alloc,
920 .use_clustering = DISABLE_CLUSTERING, 920 .use_clustering = DISABLE_CLUSTERING,
921 .this_id = -1, 921 .this_id = -1,
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index 61966750bd60..63032ec3db92 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -272,7 +272,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
272 int len = 0; 272 int len = 0;
273 273
274 rq = blk_get_request(sdev->request_queue, 274 rq = blk_get_request(sdev->request_queue,
275 (cmd == MODE_SELECT) ? WRITE : READ, GFP_NOIO); 275 (cmd != INQUIRY) ? WRITE : READ, GFP_NOIO);
276 if (!rq) { 276 if (!rq) {
277 sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); 277 sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed");
278 return NULL; 278 return NULL;
@@ -286,14 +286,17 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
286 len = sizeof(short_trespass); 286 len = sizeof(short_trespass);
287 rq->cmd_flags |= REQ_RW; 287 rq->cmd_flags |= REQ_RW;
288 rq->cmd[1] = 0x10; 288 rq->cmd[1] = 0x10;
289 rq->cmd[4] = len;
289 break; 290 break;
290 case MODE_SELECT_10: 291 case MODE_SELECT_10:
291 len = sizeof(long_trespass); 292 len = sizeof(long_trespass);
292 rq->cmd_flags |= REQ_RW; 293 rq->cmd_flags |= REQ_RW;
293 rq->cmd[1] = 0x10; 294 rq->cmd[1] = 0x10;
295 rq->cmd[8] = len;
294 break; 296 break;
295 case INQUIRY: 297 case INQUIRY:
296 len = CLARIION_BUFFER_SIZE; 298 len = CLARIION_BUFFER_SIZE;
299 rq->cmd[4] = len;
297 memset(buffer, 0, len); 300 memset(buffer, 0, len);
298 break; 301 break;
299 default: 302 default:
@@ -301,7 +304,6 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
301 break; 304 break;
302 } 305 }
303 306
304 rq->cmd[4] = len;
305 rq->cmd_type = REQ_TYPE_BLOCK_PC; 307 rq->cmd_type = REQ_TYPE_BLOCK_PC;
306 rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | 308 rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
307 REQ_FAILFAST_DRIVER; 309 REQ_FAILFAST_DRIVER;
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 03697ba94251..183d3a43c280 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -43,6 +43,7 @@
43#include <scsi/scsi_cmnd.h> 43#include <scsi/scsi_cmnd.h>
44#include <scsi/scsi_device.h> 44#include <scsi/scsi_device.h>
45#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
46#include <scsi/scsi_tcq.h>
46#include <linux/cciss_ioctl.h> 47#include <linux/cciss_ioctl.h>
47#include <linux/string.h> 48#include <linux/string.h>
48#include <linux/bitmap.h> 49#include <linux/bitmap.h>
@@ -52,7 +53,7 @@
52#include "hpsa.h" 53#include "hpsa.h"
53 54
54/* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */ 55/* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
55#define HPSA_DRIVER_VERSION "2.0.1-3" 56#define HPSA_DRIVER_VERSION "2.0.2-1"
56#define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")" 57#define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
57 58
58/* How long to wait (in milliseconds) for board to go into simple mode */ 59/* How long to wait (in milliseconds) for board to go into simple mode */
@@ -134,6 +135,8 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
134static void hpsa_scan_start(struct Scsi_Host *); 135static void hpsa_scan_start(struct Scsi_Host *);
135static int hpsa_scan_finished(struct Scsi_Host *sh, 136static int hpsa_scan_finished(struct Scsi_Host *sh,
136 unsigned long elapsed_time); 137 unsigned long elapsed_time);
138static int hpsa_change_queue_depth(struct scsi_device *sdev,
139 int qdepth, int reason);
137 140
138static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd); 141static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
139static int hpsa_slave_alloc(struct scsi_device *sdev); 142static int hpsa_slave_alloc(struct scsi_device *sdev);
@@ -182,8 +185,8 @@ static struct scsi_host_template hpsa_driver_template = {
182 .queuecommand = hpsa_scsi_queue_command, 185 .queuecommand = hpsa_scsi_queue_command,
183 .scan_start = hpsa_scan_start, 186 .scan_start = hpsa_scan_start,
184 .scan_finished = hpsa_scan_finished, 187 .scan_finished = hpsa_scan_finished,
188 .change_queue_depth = hpsa_change_queue_depth,
185 .this_id = -1, 189 .this_id = -1,
186 .sg_tablesize = MAXSGENTRIES,
187 .use_clustering = ENABLE_CLUSTERING, 190 .use_clustering = ENABLE_CLUSTERING,
188 .eh_device_reset_handler = hpsa_eh_device_reset_handler, 191 .eh_device_reset_handler = hpsa_eh_device_reset_handler,
189 .ioctl = hpsa_ioctl, 192 .ioctl = hpsa_ioctl,
@@ -208,133 +211,6 @@ static inline struct ctlr_info *shost_to_hba(struct Scsi_Host *sh)
208 return (struct ctlr_info *) *priv; 211 return (struct ctlr_info *) *priv;
209} 212}
210 213
211static struct task_struct *hpsa_scan_thread;
212static DEFINE_MUTEX(hpsa_scan_mutex);
213static LIST_HEAD(hpsa_scan_q);
214static int hpsa_scan_func(void *data);
215
216/**
217 * add_to_scan_list() - add controller to rescan queue
218 * @h: Pointer to the controller.
219 *
220 * Adds the controller to the rescan queue if not already on the queue.
221 *
222 * returns 1 if added to the queue, 0 if skipped (could be on the
223 * queue already, or the controller could be initializing or shutting
224 * down).
225 **/
226static int add_to_scan_list(struct ctlr_info *h)
227{
228 struct ctlr_info *test_h;
229 int found = 0;
230 int ret = 0;
231
232 if (h->busy_initializing)
233 return 0;
234
235 /*
236 * If we don't get the lock, it means the driver is unloading
237 * and there's no point in scheduling a new scan.
238 */
239 if (!mutex_trylock(&h->busy_shutting_down))
240 return 0;
241
242 mutex_lock(&hpsa_scan_mutex);
243 list_for_each_entry(test_h, &hpsa_scan_q, scan_list) {
244 if (test_h == h) {
245 found = 1;
246 break;
247 }
248 }
249 if (!found && !h->busy_scanning) {
250 INIT_COMPLETION(h->scan_wait);
251 list_add_tail(&h->scan_list, &hpsa_scan_q);
252 ret = 1;
253 }
254 mutex_unlock(&hpsa_scan_mutex);
255 mutex_unlock(&h->busy_shutting_down);
256
257 return ret;
258}
259
260/**
261 * remove_from_scan_list() - remove controller from rescan queue
262 * @h: Pointer to the controller.
263 *
264 * Removes the controller from the rescan queue if present. Blocks if
265 * the controller is currently conducting a rescan. The controller
266 * can be in one of three states:
267 * 1. Doesn't need a scan
268 * 2. On the scan list, but not scanning yet (we remove it)
269 * 3. Busy scanning (and not on the list). In this case we want to wait for
270 * the scan to complete to make sure the scanning thread for this
271 * controller is completely idle.
272 **/
273static void remove_from_scan_list(struct ctlr_info *h)
274{
275 struct ctlr_info *test_h, *tmp_h;
276
277 mutex_lock(&hpsa_scan_mutex);
278 list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) {
279 if (test_h == h) { /* state 2. */
280 list_del(&h->scan_list);
281 complete_all(&h->scan_wait);
282 mutex_unlock(&hpsa_scan_mutex);
283 return;
284 }
285 }
286 if (h->busy_scanning) { /* state 3. */
287 mutex_unlock(&hpsa_scan_mutex);
288 wait_for_completion(&h->scan_wait);
289 } else { /* state 1, nothing to do. */
290 mutex_unlock(&hpsa_scan_mutex);
291 }
292}
293
294/* hpsa_scan_func() - kernel thread used to rescan controllers
295 * @data: Ignored.
296 *
297 * A kernel thread used scan for drive topology changes on
298 * controllers. The thread processes only one controller at a time
299 * using a queue. Controllers are added to the queue using
300 * add_to_scan_list() and removed from the queue either after done
301 * processing or using remove_from_scan_list().
302 *
303 * returns 0.
304 **/
305static int hpsa_scan_func(__attribute__((unused)) void *data)
306{
307 struct ctlr_info *h;
308 int host_no;
309
310 while (1) {
311 set_current_state(TASK_INTERRUPTIBLE);
312 schedule();
313 if (kthread_should_stop())
314 break;
315
316 while (1) {
317 mutex_lock(&hpsa_scan_mutex);
318 if (list_empty(&hpsa_scan_q)) {
319 mutex_unlock(&hpsa_scan_mutex);
320 break;
321 }
322 h = list_entry(hpsa_scan_q.next, struct ctlr_info,
323 scan_list);
324 list_del(&h->scan_list);
325 h->busy_scanning = 1;
326 mutex_unlock(&hpsa_scan_mutex);
327 host_no = h->scsi_host ? h->scsi_host->host_no : -1;
328 hpsa_scan_start(h->scsi_host);
329 complete_all(&h->scan_wait);
330 mutex_lock(&hpsa_scan_mutex);
331 h->busy_scanning = 0;
332 mutex_unlock(&hpsa_scan_mutex);
333 }
334 }
335 return 0;
336}
337
338static int check_for_unit_attention(struct ctlr_info *h, 214static int check_for_unit_attention(struct ctlr_info *h,
339 struct CommandList *c) 215 struct CommandList *c)
340{ 216{
@@ -352,21 +228,8 @@ static int check_for_unit_attention(struct ctlr_info *h,
352 break; 228 break;
353 case REPORT_LUNS_CHANGED: 229 case REPORT_LUNS_CHANGED:
354 dev_warn(&h->pdev->dev, "hpsa%d: report LUN data " 230 dev_warn(&h->pdev->dev, "hpsa%d: report LUN data "
355 "changed\n", h->ctlr); 231 "changed, action required\n", h->ctlr);
356 /* 232 /*
357 * Here, we could call add_to_scan_list and wake up the scan thread,
358 * except that it's quite likely that we will get more than one
359 * REPORT_LUNS_CHANGED condition in quick succession, which means
360 * that those which occur after the first one will likely happen
361 * *during* the hpsa_scan_thread's rescan. And the rescan code is not
362 * robust enough to restart in the middle, undoing what it has already
363 * done, and it's not clear that it's even possible to do this, since
364 * part of what it does is notify the SCSI mid layer, which starts
365 * doing it's own i/o to read partition tables and so on, and the
366 * driver doesn't have visibility to know what might need undoing.
367 * In any event, if possible, it is horribly complicated to get right
368 * so we just don't do it for now.
369 *
370 * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012. 233 * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012.
371 */ 234 */
372 break; 235 break;
@@ -393,10 +256,7 @@ static ssize_t host_store_rescan(struct device *dev,
393 struct ctlr_info *h; 256 struct ctlr_info *h;
394 struct Scsi_Host *shost = class_to_shost(dev); 257 struct Scsi_Host *shost = class_to_shost(dev);
395 h = shost_to_hba(shost); 258 h = shost_to_hba(shost);
396 if (add_to_scan_list(h)) { 259 hpsa_scan_start(h->scsi_host);
397 wake_up_process(hpsa_scan_thread);
398 wait_for_completion_interruptible(&h->scan_wait);
399 }
400 return count; 260 return count;
401} 261}
402 262
@@ -983,6 +843,76 @@ static void hpsa_scsi_setup(struct ctlr_info *h)
983 spin_lock_init(&h->devlock); 843 spin_lock_init(&h->devlock);
984} 844}
985 845
846static void hpsa_free_sg_chain_blocks(struct ctlr_info *h)
847{
848 int i;
849
850 if (!h->cmd_sg_list)
851 return;
852 for (i = 0; i < h->nr_cmds; i++) {
853 kfree(h->cmd_sg_list[i]);
854 h->cmd_sg_list[i] = NULL;
855 }
856 kfree(h->cmd_sg_list);
857 h->cmd_sg_list = NULL;
858}
859
860static int hpsa_allocate_sg_chain_blocks(struct ctlr_info *h)
861{
862 int i;
863
864 if (h->chainsize <= 0)
865 return 0;
866
867 h->cmd_sg_list = kzalloc(sizeof(*h->cmd_sg_list) * h->nr_cmds,
868 GFP_KERNEL);
869 if (!h->cmd_sg_list)
870 return -ENOMEM;
871 for (i = 0; i < h->nr_cmds; i++) {
872 h->cmd_sg_list[i] = kmalloc(sizeof(*h->cmd_sg_list[i]) *
873 h->chainsize, GFP_KERNEL);
874 if (!h->cmd_sg_list[i])
875 goto clean;
876 }
877 return 0;
878
879clean:
880 hpsa_free_sg_chain_blocks(h);
881 return -ENOMEM;
882}
883
884static void hpsa_map_sg_chain_block(struct ctlr_info *h,
885 struct CommandList *c)
886{
887 struct SGDescriptor *chain_sg, *chain_block;
888 u64 temp64;
889
890 chain_sg = &c->SG[h->max_cmd_sg_entries - 1];
891 chain_block = h->cmd_sg_list[c->cmdindex];
892 chain_sg->Ext = HPSA_SG_CHAIN;
893 chain_sg->Len = sizeof(*chain_sg) *
894 (c->Header.SGTotal - h->max_cmd_sg_entries);
895 temp64 = pci_map_single(h->pdev, chain_block, chain_sg->Len,
896 PCI_DMA_TODEVICE);
897 chain_sg->Addr.lower = (u32) (temp64 & 0x0FFFFFFFFULL);
898 chain_sg->Addr.upper = (u32) ((temp64 >> 32) & 0x0FFFFFFFFULL);
899}
900
901static void hpsa_unmap_sg_chain_block(struct ctlr_info *h,
902 struct CommandList *c)
903{
904 struct SGDescriptor *chain_sg;
905 union u64bit temp64;
906
907 if (c->Header.SGTotal <= h->max_cmd_sg_entries)
908 return;
909
910 chain_sg = &c->SG[h->max_cmd_sg_entries - 1];
911 temp64.val32.lower = chain_sg->Addr.lower;
912 temp64.val32.upper = chain_sg->Addr.upper;
913 pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE);
914}
915
986static void complete_scsi_command(struct CommandList *cp, 916static void complete_scsi_command(struct CommandList *cp,
987 int timeout, u32 tag) 917 int timeout, u32 tag)
988{ 918{
@@ -999,10 +929,12 @@ static void complete_scsi_command(struct CommandList *cp,
999 h = cp->h; 929 h = cp->h;
1000 930
1001 scsi_dma_unmap(cmd); /* undo the DMA mappings */ 931 scsi_dma_unmap(cmd); /* undo the DMA mappings */
932 if (cp->Header.SGTotal > h->max_cmd_sg_entries)
933 hpsa_unmap_sg_chain_block(h, cp);
1002 934
1003 cmd->result = (DID_OK << 16); /* host byte */ 935 cmd->result = (DID_OK << 16); /* host byte */
1004 cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ 936 cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
1005 cmd->result |= (ei->ScsiStatus << 1); 937 cmd->result |= ei->ScsiStatus;
1006 938
1007 /* copy the sense data whether we need to or not. */ 939 /* copy the sense data whether we need to or not. */
1008 memcpy(cmd->sense_buffer, ei->SenseInfo, 940 memcpy(cmd->sense_buffer, ei->SenseInfo,
@@ -1203,6 +1135,7 @@ static int hpsa_scsi_detect(struct ctlr_info *h)
1203 sh->max_id = HPSA_MAX_LUN; 1135 sh->max_id = HPSA_MAX_LUN;
1204 sh->can_queue = h->nr_cmds; 1136 sh->can_queue = h->nr_cmds;
1205 sh->cmd_per_lun = h->nr_cmds; 1137 sh->cmd_per_lun = h->nr_cmds;
1138 sh->sg_tablesize = h->maxsgentries;
1206 h->scsi_host = sh; 1139 h->scsi_host = sh;
1207 sh->hostdata[0] = (unsigned long) h; 1140 sh->hostdata[0] = (unsigned long) h;
1208 sh->irq = h->intr[PERF_MODE_INT]; 1141 sh->irq = h->intr[PERF_MODE_INT];
@@ -1382,7 +1315,7 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr)
1382 1315
1383 if (c == NULL) { /* trouble... */ 1316 if (c == NULL) { /* trouble... */
1384 dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); 1317 dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
1385 return -1; 1318 return -ENOMEM;
1386 } 1319 }
1387 1320
1388 fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG); 1321 fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG);
@@ -1904,16 +1837,17 @@ out:
1904 * dma mapping and fills in the scatter gather entries of the 1837 * dma mapping and fills in the scatter gather entries of the
1905 * hpsa command, cp. 1838 * hpsa command, cp.
1906 */ 1839 */
1907static int hpsa_scatter_gather(struct pci_dev *pdev, 1840static int hpsa_scatter_gather(struct ctlr_info *h,
1908 struct CommandList *cp, 1841 struct CommandList *cp,
1909 struct scsi_cmnd *cmd) 1842 struct scsi_cmnd *cmd)
1910{ 1843{
1911 unsigned int len; 1844 unsigned int len;
1912 struct scatterlist *sg; 1845 struct scatterlist *sg;
1913 u64 addr64; 1846 u64 addr64;
1914 int use_sg, i; 1847 int use_sg, i, sg_index, chained;
1848 struct SGDescriptor *curr_sg;
1915 1849
1916 BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES); 1850 BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
1917 1851
1918 use_sg = scsi_dma_map(cmd); 1852 use_sg = scsi_dma_map(cmd);
1919 if (use_sg < 0) 1853 if (use_sg < 0)
@@ -1922,15 +1856,33 @@ static int hpsa_scatter_gather(struct pci_dev *pdev,
1922 if (!use_sg) 1856 if (!use_sg)
1923 goto sglist_finished; 1857 goto sglist_finished;
1924 1858
1859 curr_sg = cp->SG;
1860 chained = 0;
1861 sg_index = 0;
1925 scsi_for_each_sg(cmd, sg, use_sg, i) { 1862 scsi_for_each_sg(cmd, sg, use_sg, i) {
1863 if (i == h->max_cmd_sg_entries - 1 &&
1864 use_sg > h->max_cmd_sg_entries) {
1865 chained = 1;
1866 curr_sg = h->cmd_sg_list[cp->cmdindex];
1867 sg_index = 0;
1868 }
1926 addr64 = (u64) sg_dma_address(sg); 1869 addr64 = (u64) sg_dma_address(sg);
1927 len = sg_dma_len(sg); 1870 len = sg_dma_len(sg);
1928 cp->SG[i].Addr.lower = 1871 curr_sg->Addr.lower = (u32) (addr64 & 0x0FFFFFFFFULL);
1929 (u32) (addr64 & (u64) 0x00000000FFFFFFFF); 1872 curr_sg->Addr.upper = (u32) ((addr64 >> 32) & 0x0FFFFFFFFULL);
1930 cp->SG[i].Addr.upper = 1873 curr_sg->Len = len;
1931 (u32) ((addr64 >> 32) & (u64) 0x00000000FFFFFFFF); 1874 curr_sg->Ext = 0; /* we are not chaining */
1932 cp->SG[i].Len = len; 1875 curr_sg++;
1933 cp->SG[i].Ext = 0; /* we are not chaining */ 1876 }
1877
1878 if (use_sg + chained > h->maxSG)
1879 h->maxSG = use_sg + chained;
1880
1881 if (chained) {
1882 cp->Header.SGList = h->max_cmd_sg_entries;
1883 cp->Header.SGTotal = (u16) (use_sg + 1);
1884 hpsa_map_sg_chain_block(h, cp);
1885 return 0;
1934 } 1886 }
1935 1887
1936sglist_finished: 1888sglist_finished:
@@ -2026,7 +1978,7 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
2026 break; 1978 break;
2027 } 1979 }
2028 1980
2029 if (hpsa_scatter_gather(h->pdev, c, cmd) < 0) { /* Fill SG list */ 1981 if (hpsa_scatter_gather(h, c, cmd) < 0) { /* Fill SG list */
2030 cmd_free(h, c); 1982 cmd_free(h, c);
2031 return SCSI_MLQUEUE_HOST_BUSY; 1983 return SCSI_MLQUEUE_HOST_BUSY;
2032 } 1984 }
@@ -2077,6 +2029,23 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
2077 return finished; 2029 return finished;
2078} 2030}
2079 2031
2032static int hpsa_change_queue_depth(struct scsi_device *sdev,
2033 int qdepth, int reason)
2034{
2035 struct ctlr_info *h = sdev_to_hba(sdev);
2036
2037 if (reason != SCSI_QDEPTH_DEFAULT)
2038 return -ENOTSUPP;
2039
2040 if (qdepth < 1)
2041 qdepth = 1;
2042 else
2043 if (qdepth > h->nr_cmds)
2044 qdepth = h->nr_cmds;
2045 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
2046 return sdev->queue_depth;
2047}
2048
2080static void hpsa_unregister_scsi(struct ctlr_info *h) 2049static void hpsa_unregister_scsi(struct ctlr_info *h)
2081{ 2050{
2082 /* we are being forcibly unloaded, and may not refuse. */ 2051 /* we are being forcibly unloaded, and may not refuse. */
@@ -2961,7 +2930,7 @@ static irqreturn_t do_hpsa_intr(int irq, void *dev_id)
2961 return IRQ_HANDLED; 2930 return IRQ_HANDLED;
2962} 2931}
2963 2932
2964/* Send a message CDB to the firmwart. */ 2933/* Send a message CDB to the firmware. */
2965static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode, 2934static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
2966 unsigned char type) 2935 unsigned char type)
2967{ 2936{
@@ -3296,7 +3265,7 @@ default_int_mode:
3296 h->intr[PERF_MODE_INT] = pdev->irq; 3265 h->intr[PERF_MODE_INT] = pdev->irq;
3297} 3266}
3298 3267
3299static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) 3268static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
3300{ 3269{
3301 ushort subsystem_vendor_id, subsystem_device_id, command; 3270 ushort subsystem_vendor_id, subsystem_device_id, command;
3302 u32 board_id, scratchpad = 0; 3271 u32 board_id, scratchpad = 0;
@@ -3405,6 +3374,23 @@ static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
3405 3374
3406 h->board_id = board_id; 3375 h->board_id = board_id;
3407 h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); 3376 h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
3377 h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements));
3378
3379 /*
3380 * Limit in-command s/g elements to 32 save dma'able memory.
3381 * Howvever spec says if 0, use 31
3382 */
3383
3384 h->max_cmd_sg_entries = 31;
3385 if (h->maxsgentries > 512) {
3386 h->max_cmd_sg_entries = 32;
3387 h->chainsize = h->maxsgentries - h->max_cmd_sg_entries + 1;
3388 h->maxsgentries--; /* save one for chain pointer */
3389 } else {
3390 h->maxsgentries = 31; /* default to traditional values */
3391 h->chainsize = 0;
3392 }
3393
3408 h->product_name = products[prod_index].product_name; 3394 h->product_name = products[prod_index].product_name;
3409 h->access = *(products[prod_index].access); 3395 h->access = *(products[prod_index].access);
3410 /* Allow room for some ioctls */ 3396 /* Allow room for some ioctls */
@@ -3532,8 +3518,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
3532 h->busy_initializing = 1; 3518 h->busy_initializing = 1;
3533 INIT_HLIST_HEAD(&h->cmpQ); 3519 INIT_HLIST_HEAD(&h->cmpQ);
3534 INIT_HLIST_HEAD(&h->reqQ); 3520 INIT_HLIST_HEAD(&h->reqQ);
3535 mutex_init(&h->busy_shutting_down);
3536 init_completion(&h->scan_wait);
3537 rc = hpsa_pci_init(h, pdev); 3521 rc = hpsa_pci_init(h, pdev);
3538 if (rc != 0) 3522 if (rc != 0)
3539 goto clean1; 3523 goto clean1;
@@ -3587,6 +3571,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
3587 rc = -ENOMEM; 3571 rc = -ENOMEM;
3588 goto clean4; 3572 goto clean4;
3589 } 3573 }
3574 if (hpsa_allocate_sg_chain_blocks(h))
3575 goto clean4;
3590 spin_lock_init(&h->lock); 3576 spin_lock_init(&h->lock);
3591 spin_lock_init(&h->scan_lock); 3577 spin_lock_init(&h->scan_lock);
3592 init_waitqueue_head(&h->scan_wait_queue); 3578 init_waitqueue_head(&h->scan_wait_queue);
@@ -3609,6 +3595,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
3609 return 1; 3595 return 1;
3610 3596
3611clean4: 3597clean4:
3598 hpsa_free_sg_chain_blocks(h);
3612 kfree(h->cmd_pool_bits); 3599 kfree(h->cmd_pool_bits);
3613 if (h->cmd_pool) 3600 if (h->cmd_pool)
3614 pci_free_consistent(h->pdev, 3601 pci_free_consistent(h->pdev,
@@ -3681,11 +3668,10 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
3681 return; 3668 return;
3682 } 3669 }
3683 h = pci_get_drvdata(pdev); 3670 h = pci_get_drvdata(pdev);
3684 mutex_lock(&h->busy_shutting_down);
3685 remove_from_scan_list(h);
3686 hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ 3671 hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */
3687 hpsa_shutdown(pdev); 3672 hpsa_shutdown(pdev);
3688 iounmap(h->vaddr); 3673 iounmap(h->vaddr);
3674 hpsa_free_sg_chain_blocks(h);
3689 pci_free_consistent(h->pdev, 3675 pci_free_consistent(h->pdev,
3690 h->nr_cmds * sizeof(struct CommandList), 3676 h->nr_cmds * sizeof(struct CommandList),
3691 h->cmd_pool, h->cmd_pool_dhandle); 3677 h->cmd_pool, h->cmd_pool_dhandle);
@@ -3703,7 +3689,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
3703 */ 3689 */
3704 pci_release_regions(pdev); 3690 pci_release_regions(pdev);
3705 pci_set_drvdata(pdev, NULL); 3691 pci_set_drvdata(pdev, NULL);
3706 mutex_unlock(&h->busy_shutting_down);
3707 kfree(h); 3692 kfree(h);
3708} 3693}
3709 3694
@@ -3857,23 +3842,12 @@ clean_up:
3857 */ 3842 */
3858static int __init hpsa_init(void) 3843static int __init hpsa_init(void)
3859{ 3844{
3860 int err; 3845 return pci_register_driver(&hpsa_pci_driver);
3861 /* Start the scan thread */
3862 hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan");
3863 if (IS_ERR(hpsa_scan_thread)) {
3864 err = PTR_ERR(hpsa_scan_thread);
3865 return -ENODEV;
3866 }
3867 err = pci_register_driver(&hpsa_pci_driver);
3868 if (err)
3869 kthread_stop(hpsa_scan_thread);
3870 return err;
3871} 3846}
3872 3847
3873static void __exit hpsa_cleanup(void) 3848static void __exit hpsa_cleanup(void)
3874{ 3849{
3875 pci_unregister_driver(&hpsa_pci_driver); 3850 pci_unregister_driver(&hpsa_pci_driver);
3876 kthread_stop(hpsa_scan_thread);
3877} 3851}
3878 3852
3879module_init(hpsa_init); 3853module_init(hpsa_init);
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index a0502b3ac17e..1bb5233b09a0 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -83,6 +83,10 @@ struct ctlr_info {
83 unsigned int maxQsinceinit; 83 unsigned int maxQsinceinit;
84 unsigned int maxSG; 84 unsigned int maxSG;
85 spinlock_t lock; 85 spinlock_t lock;
86 int maxsgentries;
87 u8 max_cmd_sg_entries;
88 int chainsize;
89 struct SGDescriptor **cmd_sg_list;
86 90
87 /* pointers to command and error info pool */ 91 /* pointers to command and error info pool */
88 struct CommandList *cmd_pool; 92 struct CommandList *cmd_pool;
@@ -97,9 +101,6 @@ struct ctlr_info {
97 int scan_finished; 101 int scan_finished;
98 spinlock_t scan_lock; 102 spinlock_t scan_lock;
99 wait_queue_head_t scan_wait_queue; 103 wait_queue_head_t scan_wait_queue;
100 struct mutex busy_shutting_down;
101 struct list_head scan_list;
102 struct completion scan_wait;
103 104
104 struct Scsi_Host *scsi_host; 105 struct Scsi_Host *scsi_host;
105 spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */ 106 spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 3e0abdf76689..56fb9827681e 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -23,7 +23,8 @@
23 23
24/* general boundary defintions */ 24/* general boundary defintions */
25#define SENSEINFOBYTES 32 /* may vary between hbas */ 25#define SENSEINFOBYTES 32 /* may vary between hbas */
26#define MAXSGENTRIES 31 26#define MAXSGENTRIES 32
27#define HPSA_SG_CHAIN 0x80000000
27#define MAXREPLYQS 256 28#define MAXREPLYQS 256
28 29
29/* Command Status value */ 30/* Command Status value */
@@ -305,20 +306,23 @@ struct CommandList {
305 int cmd_type; 306 int cmd_type;
306 long cmdindex; 307 long cmdindex;
307 struct hlist_node list; 308 struct hlist_node list;
308 struct CommandList *prev;
309 struct CommandList *next;
310 struct request *rq; 309 struct request *rq;
311 struct completion *waiting; 310 struct completion *waiting;
312 int retry_count;
313 void *scsi_cmd; 311 void *scsi_cmd;
314 312
315/* on 64 bit architectures, to get this to be 32-byte-aligned 313/* on 64 bit architectures, to get this to be 32-byte-aligned
316 * it so happens we need no padding, on 32 bit systems, 314 * it so happens we need PAD_64 bytes of padding, on 32 bit systems,
317 * we need 8 bytes of padding. This does that. 315 * we need PAD_32 bytes of padding (see below). This does that.
316 * If it happens that 64 bit and 32 bit systems need different
317 * padding, PAD_32 and PAD_64 can be set independently, and.
318 * the code below will do the right thing.
318 */ 319 */
319#define COMMANDLIST_PAD ((8 - sizeof(long))/4 * 8) 320#define IS_32_BIT ((8 - sizeof(long))/4)
321#define IS_64_BIT (!IS_32_BIT)
322#define PAD_32 (4)
323#define PAD_64 (4)
324#define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64)
320 u8 pad[COMMANDLIST_PAD]; 325 u8 pad[COMMANDLIST_PAD];
321
322}; 326};
323 327
324/* Configuration Table Structure */ 328/* Configuration Table Structure */
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 732f6d35b4a8..4e577e2fee38 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -29,6 +29,7 @@
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/kthread.h> 30#include <linux/kthread.h>
31#include <linux/of.h> 31#include <linux/of.h>
32#include <linux/pm.h>
32#include <linux/stringify.h> 33#include <linux/stringify.h>
33#include <asm/firmware.h> 34#include <asm/firmware.h>
34#include <asm/irq.h> 35#include <asm/irq.h>
@@ -4736,6 +4737,27 @@ static int ibmvfc_remove(struct vio_dev *vdev)
4736} 4737}
4737 4738
4738/** 4739/**
4740 * ibmvfc_resume - Resume from suspend
4741 * @dev: device struct
4742 *
4743 * We may have lost an interrupt across suspend/resume, so kick the
4744 * interrupt handler
4745 *
4746 */
4747static int ibmvfc_resume(struct device *dev)
4748{
4749 unsigned long flags;
4750 struct ibmvfc_host *vhost = dev_get_drvdata(dev);
4751 struct vio_dev *vdev = to_vio_dev(dev);
4752
4753 spin_lock_irqsave(vhost->host->host_lock, flags);
4754 vio_disable_interrupts(vdev);
4755 tasklet_schedule(&vhost->tasklet);
4756 spin_unlock_irqrestore(vhost->host->host_lock, flags);
4757 return 0;
4758}
4759
4760/**
4739 * ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver 4761 * ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver
4740 * @vdev: vio device struct 4762 * @vdev: vio device struct
4741 * 4763 *
@@ -4755,6 +4777,10 @@ static struct vio_device_id ibmvfc_device_table[] __devinitdata = {
4755}; 4777};
4756MODULE_DEVICE_TABLE(vio, ibmvfc_device_table); 4778MODULE_DEVICE_TABLE(vio, ibmvfc_device_table);
4757 4779
4780static struct dev_pm_ops ibmvfc_pm_ops = {
4781 .resume = ibmvfc_resume
4782};
4783
4758static struct vio_driver ibmvfc_driver = { 4784static struct vio_driver ibmvfc_driver = {
4759 .id_table = ibmvfc_device_table, 4785 .id_table = ibmvfc_device_table,
4760 .probe = ibmvfc_probe, 4786 .probe = ibmvfc_probe,
@@ -4763,6 +4789,7 @@ static struct vio_driver ibmvfc_driver = {
4763 .driver = { 4789 .driver = {
4764 .name = IBMVFC_NAME, 4790 .name = IBMVFC_NAME,
4765 .owner = THIS_MODULE, 4791 .owner = THIS_MODULE,
4792 .pm = &ibmvfc_pm_ops,
4766 } 4793 }
4767}; 4794};
4768 4795
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index e3a18e0ef276..dc1bcbe3b176 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -71,6 +71,7 @@
71#include <linux/dma-mapping.h> 71#include <linux/dma-mapping.h>
72#include <linux/delay.h> 72#include <linux/delay.h>
73#include <linux/of.h> 73#include <linux/of.h>
74#include <linux/pm.h>
74#include <asm/firmware.h> 75#include <asm/firmware.h>
75#include <asm/vio.h> 76#include <asm/vio.h>
76#include <scsi/scsi.h> 77#include <scsi/scsi.h>
@@ -1991,6 +1992,19 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
1991} 1992}
1992 1993
1993/** 1994/**
1995 * ibmvscsi_resume: Resume from suspend
1996 * @dev: device struct
1997 *
1998 * We may have lost an interrupt across suspend/resume, so kick the
1999 * interrupt handler
2000 */
2001static int ibmvscsi_resume(struct device *dev)
2002{
2003 struct ibmvscsi_host_data *hostdata = dev_get_drvdata(dev);
2004 return ibmvscsi_ops->resume(hostdata);
2005}
2006
2007/**
1994 * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we 2008 * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we
1995 * support. 2009 * support.
1996 */ 2010 */
@@ -2000,6 +2014,10 @@ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = {
2000}; 2014};
2001MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table); 2015MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table);
2002 2016
2017static struct dev_pm_ops ibmvscsi_pm_ops = {
2018 .resume = ibmvscsi_resume
2019};
2020
2003static struct vio_driver ibmvscsi_driver = { 2021static struct vio_driver ibmvscsi_driver = {
2004 .id_table = ibmvscsi_device_table, 2022 .id_table = ibmvscsi_device_table,
2005 .probe = ibmvscsi_probe, 2023 .probe = ibmvscsi_probe,
@@ -2008,6 +2026,7 @@ static struct vio_driver ibmvscsi_driver = {
2008 .driver = { 2026 .driver = {
2009 .name = "ibmvscsi", 2027 .name = "ibmvscsi",
2010 .owner = THIS_MODULE, 2028 .owner = THIS_MODULE,
2029 .pm = &ibmvscsi_pm_ops,
2011 } 2030 }
2012}; 2031};
2013 2032
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h
index 76425303def0..9cb7c6a773e1 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.h
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.h
@@ -120,6 +120,7 @@ struct ibmvscsi_ops {
120 struct ibmvscsi_host_data *hostdata); 120 struct ibmvscsi_host_data *hostdata);
121 int (*send_crq)(struct ibmvscsi_host_data *hostdata, 121 int (*send_crq)(struct ibmvscsi_host_data *hostdata,
122 u64 word1, u64 word2); 122 u64 word1, u64 word2);
123 int (*resume) (struct ibmvscsi_host_data *hostdata);
123}; 124};
124 125
125extern struct ibmvscsi_ops iseriesvscsi_ops; 126extern struct ibmvscsi_ops iseriesvscsi_ops;
diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c
index 0775fdee5fa8..f4776451a754 100644
--- a/drivers/scsi/ibmvscsi/iseries_vscsi.c
+++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c
@@ -158,10 +158,16 @@ static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
158 0); 158 0);
159} 159}
160 160
161static int iseriesvscsi_resume(struct ibmvscsi_host_data *hostdata)
162{
163 return 0;
164}
165
161struct ibmvscsi_ops iseriesvscsi_ops = { 166struct ibmvscsi_ops iseriesvscsi_ops = {
162 .init_crq_queue = iseriesvscsi_init_crq_queue, 167 .init_crq_queue = iseriesvscsi_init_crq_queue,
163 .release_crq_queue = iseriesvscsi_release_crq_queue, 168 .release_crq_queue = iseriesvscsi_release_crq_queue,
164 .reset_crq_queue = iseriesvscsi_reset_crq_queue, 169 .reset_crq_queue = iseriesvscsi_reset_crq_queue,
165 .reenable_crq_queue = iseriesvscsi_reenable_crq_queue, 170 .reenable_crq_queue = iseriesvscsi_reenable_crq_queue,
166 .send_crq = iseriesvscsi_send_crq, 171 .send_crq = iseriesvscsi_send_crq,
172 .resume = iseriesvscsi_resume,
167}; 173};
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index 462a8574dad9..63a30cbbf9de 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -334,10 +334,23 @@ static int rpavscsi_reenable_crq_queue(struct crq_queue *queue,
334 return rc; 334 return rc;
335} 335}
336 336
337/**
338 * rpavscsi_resume: - resume after suspend
339 * @hostdata: ibmvscsi_host_data of host
340 *
341 */
342static int rpavscsi_resume(struct ibmvscsi_host_data *hostdata)
343{
344 vio_disable_interrupts(to_vio_dev(hostdata->dev));
345 tasklet_schedule(&hostdata->srp_task);
346 return 0;
347}
348
337struct ibmvscsi_ops rpavscsi_ops = { 349struct ibmvscsi_ops rpavscsi_ops = {
338 .init_crq_queue = rpavscsi_init_crq_queue, 350 .init_crq_queue = rpavscsi_init_crq_queue,
339 .release_crq_queue = rpavscsi_release_crq_queue, 351 .release_crq_queue = rpavscsi_release_crq_queue,
340 .reset_crq_queue = rpavscsi_reset_crq_queue, 352 .reset_crq_queue = rpavscsi_reset_crq_queue,
341 .reenable_crq_queue = rpavscsi_reenable_crq_queue, 353 .reenable_crq_queue = rpavscsi_reenable_crq_queue,
342 .send_crq = rpavscsi_send_crq, 354 .send_crq = rpavscsi_send_crq,
355 .resume = rpavscsi_resume,
343}; 356};
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 032f0d0e6cb4..c79cd98eb6bf 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -72,6 +72,8 @@
72#include <linux/moduleparam.h> 72#include <linux/moduleparam.h>
73#include <linux/libata.h> 73#include <linux/libata.h>
74#include <linux/hdreg.h> 74#include <linux/hdreg.h>
75#include <linux/reboot.h>
76#include <linux/stringify.h>
75#include <asm/io.h> 77#include <asm/io.h>
76#include <asm/irq.h> 78#include <asm/irq.h>
77#include <asm/processor.h> 79#include <asm/processor.h>
@@ -91,8 +93,8 @@ static unsigned int ipr_max_speed = 1;
91static int ipr_testmode = 0; 93static int ipr_testmode = 0;
92static unsigned int ipr_fastfail = 0; 94static unsigned int ipr_fastfail = 0;
93static unsigned int ipr_transop_timeout = 0; 95static unsigned int ipr_transop_timeout = 0;
94static unsigned int ipr_enable_cache = 1;
95static unsigned int ipr_debug = 0; 96static unsigned int ipr_debug = 0;
97static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS;
96static unsigned int ipr_dual_ioa_raid = 1; 98static unsigned int ipr_dual_ioa_raid = 1;
97static DEFINE_SPINLOCK(ipr_driver_lock); 99static DEFINE_SPINLOCK(ipr_driver_lock);
98 100
@@ -104,13 +106,20 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
104 { 106 {
105 .set_interrupt_mask_reg = 0x0022C, 107 .set_interrupt_mask_reg = 0x0022C,
106 .clr_interrupt_mask_reg = 0x00230, 108 .clr_interrupt_mask_reg = 0x00230,
109 .clr_interrupt_mask_reg32 = 0x00230,
107 .sense_interrupt_mask_reg = 0x0022C, 110 .sense_interrupt_mask_reg = 0x0022C,
111 .sense_interrupt_mask_reg32 = 0x0022C,
108 .clr_interrupt_reg = 0x00228, 112 .clr_interrupt_reg = 0x00228,
113 .clr_interrupt_reg32 = 0x00228,
109 .sense_interrupt_reg = 0x00224, 114 .sense_interrupt_reg = 0x00224,
115 .sense_interrupt_reg32 = 0x00224,
110 .ioarrin_reg = 0x00404, 116 .ioarrin_reg = 0x00404,
111 .sense_uproc_interrupt_reg = 0x00214, 117 .sense_uproc_interrupt_reg = 0x00214,
118 .sense_uproc_interrupt_reg32 = 0x00214,
112 .set_uproc_interrupt_reg = 0x00214, 119 .set_uproc_interrupt_reg = 0x00214,
113 .clr_uproc_interrupt_reg = 0x00218 120 .set_uproc_interrupt_reg32 = 0x00214,
121 .clr_uproc_interrupt_reg = 0x00218,
122 .clr_uproc_interrupt_reg32 = 0x00218
114 } 123 }
115 }, 124 },
116 { /* Snipe and Scamp */ 125 { /* Snipe and Scamp */
@@ -119,25 +128,59 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
119 { 128 {
120 .set_interrupt_mask_reg = 0x00288, 129 .set_interrupt_mask_reg = 0x00288,
121 .clr_interrupt_mask_reg = 0x0028C, 130 .clr_interrupt_mask_reg = 0x0028C,
131 .clr_interrupt_mask_reg32 = 0x0028C,
122 .sense_interrupt_mask_reg = 0x00288, 132 .sense_interrupt_mask_reg = 0x00288,
133 .sense_interrupt_mask_reg32 = 0x00288,
123 .clr_interrupt_reg = 0x00284, 134 .clr_interrupt_reg = 0x00284,
135 .clr_interrupt_reg32 = 0x00284,
124 .sense_interrupt_reg = 0x00280, 136 .sense_interrupt_reg = 0x00280,
137 .sense_interrupt_reg32 = 0x00280,
125 .ioarrin_reg = 0x00504, 138 .ioarrin_reg = 0x00504,
126 .sense_uproc_interrupt_reg = 0x00290, 139 .sense_uproc_interrupt_reg = 0x00290,
140 .sense_uproc_interrupt_reg32 = 0x00290,
127 .set_uproc_interrupt_reg = 0x00290, 141 .set_uproc_interrupt_reg = 0x00290,
128 .clr_uproc_interrupt_reg = 0x00294 142 .set_uproc_interrupt_reg32 = 0x00290,
143 .clr_uproc_interrupt_reg = 0x00294,
144 .clr_uproc_interrupt_reg32 = 0x00294
145 }
146 },
147 { /* CRoC */
148 .mailbox = 0x00040,
149 .cache_line_size = 0x20,
150 {
151 .set_interrupt_mask_reg = 0x00010,
152 .clr_interrupt_mask_reg = 0x00018,
153 .clr_interrupt_mask_reg32 = 0x0001C,
154 .sense_interrupt_mask_reg = 0x00010,
155 .sense_interrupt_mask_reg32 = 0x00014,
156 .clr_interrupt_reg = 0x00008,
157 .clr_interrupt_reg32 = 0x0000C,
158 .sense_interrupt_reg = 0x00000,
159 .sense_interrupt_reg32 = 0x00004,
160 .ioarrin_reg = 0x00070,
161 .sense_uproc_interrupt_reg = 0x00020,
162 .sense_uproc_interrupt_reg32 = 0x00024,
163 .set_uproc_interrupt_reg = 0x00020,
164 .set_uproc_interrupt_reg32 = 0x00024,
165 .clr_uproc_interrupt_reg = 0x00028,
166 .clr_uproc_interrupt_reg32 = 0x0002C,
167 .init_feedback_reg = 0x0005C,
168 .dump_addr_reg = 0x00064,
169 .dump_data_reg = 0x00068
129 } 170 }
130 }, 171 },
131}; 172};
132 173
133static const struct ipr_chip_t ipr_chip[] = { 174static const struct ipr_chip_t ipr_chip[] = {
134 { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, &ipr_chip_cfg[0] }, 175 { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
135 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, &ipr_chip_cfg[0] }, 176 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
136 { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] }, 177 { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
137 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] }, 178 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
138 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, &ipr_chip_cfg[0] }, 179 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, IPR_SIS32, &ipr_chip_cfg[0] },
139 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, &ipr_chip_cfg[1] }, 180 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] },
140 { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, &ipr_chip_cfg[1] } 181 { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] },
182 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] },
183 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] }
141}; 184};
142 185
143static int ipr_max_bus_speeds [] = { 186static int ipr_max_bus_speeds [] = {
@@ -156,12 +199,13 @@ module_param_named(fastfail, ipr_fastfail, int, S_IRUGO | S_IWUSR);
156MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries"); 199MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries");
157module_param_named(transop_timeout, ipr_transop_timeout, int, 0); 200module_param_named(transop_timeout, ipr_transop_timeout, int, 0);
158MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)"); 201MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)");
159module_param_named(enable_cache, ipr_enable_cache, int, 0);
160MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)");
161module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR); 202module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR);
162MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); 203MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)");
163module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); 204module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0);
164MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)"); 205MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)");
206module_param_named(max_devs, ipr_max_devs, int, 0);
207MODULE_PARM_DESC(max_devs, "Specify the maximum number of physical devices. "
208 "[Default=" __stringify(IPR_DEFAULT_SIS64_DEVS) "]");
165MODULE_LICENSE("GPL"); 209MODULE_LICENSE("GPL");
166MODULE_VERSION(IPR_DRIVER_VERSION); 210MODULE_VERSION(IPR_DRIVER_VERSION);
167 211
@@ -180,6 +224,20 @@ struct ipr_error_table_t ipr_error_table[] = {
180 "FFFE: Soft device bus error recovered by the IOA"}, 224 "FFFE: Soft device bus error recovered by the IOA"},
181 {0x01088100, 0, IPR_DEFAULT_LOG_LEVEL, 225 {0x01088100, 0, IPR_DEFAULT_LOG_LEVEL,
182 "4101: Soft device bus fabric error"}, 226 "4101: Soft device bus fabric error"},
227 {0x01100100, 0, IPR_DEFAULT_LOG_LEVEL,
228 "FFFC: Logical block guard error recovered by the device"},
229 {0x01100300, 0, IPR_DEFAULT_LOG_LEVEL,
230 "FFFC: Logical block reference tag error recovered by the device"},
231 {0x01108300, 0, IPR_DEFAULT_LOG_LEVEL,
232 "4171: Recovered scatter list tag / sequence number error"},
233 {0x01109000, 0, IPR_DEFAULT_LOG_LEVEL,
234 "FF3D: Recovered logical block CRC error on IOA to Host transfer"},
235 {0x01109200, 0, IPR_DEFAULT_LOG_LEVEL,
236 "4171: Recovered logical block sequence number error on IOA to Host transfer"},
237 {0x0110A000, 0, IPR_DEFAULT_LOG_LEVEL,
238 "FFFD: Recovered logical block reference tag error detected by the IOA"},
239 {0x0110A100, 0, IPR_DEFAULT_LOG_LEVEL,
240 "FFFD: Logical block guard error recovered by the IOA"},
183 {0x01170600, 0, IPR_DEFAULT_LOG_LEVEL, 241 {0x01170600, 0, IPR_DEFAULT_LOG_LEVEL,
184 "FFF9: Device sector reassign successful"}, 242 "FFF9: Device sector reassign successful"},
185 {0x01170900, 0, IPR_DEFAULT_LOG_LEVEL, 243 {0x01170900, 0, IPR_DEFAULT_LOG_LEVEL,
@@ -236,12 +294,28 @@ struct ipr_error_table_t ipr_error_table[] = {
236 "3120: SCSI bus is not operational"}, 294 "3120: SCSI bus is not operational"},
237 {0x04088100, 0, IPR_DEFAULT_LOG_LEVEL, 295 {0x04088100, 0, IPR_DEFAULT_LOG_LEVEL,
238 "4100: Hard device bus fabric error"}, 296 "4100: Hard device bus fabric error"},
297 {0x04100100, 0, IPR_DEFAULT_LOG_LEVEL,
298 "310C: Logical block guard error detected by the device"},
299 {0x04100300, 0, IPR_DEFAULT_LOG_LEVEL,
300 "310C: Logical block reference tag error detected by the device"},
301 {0x04108300, 1, IPR_DEFAULT_LOG_LEVEL,
302 "4170: Scatter list tag / sequence number error"},
303 {0x04109000, 1, IPR_DEFAULT_LOG_LEVEL,
304 "8150: Logical block CRC error on IOA to Host transfer"},
305 {0x04109200, 1, IPR_DEFAULT_LOG_LEVEL,
306 "4170: Logical block sequence number error on IOA to Host transfer"},
307 {0x0410A000, 0, IPR_DEFAULT_LOG_LEVEL,
308 "310D: Logical block reference tag error detected by the IOA"},
309 {0x0410A100, 0, IPR_DEFAULT_LOG_LEVEL,
310 "310D: Logical block guard error detected by the IOA"},
239 {0x04118000, 0, IPR_DEFAULT_LOG_LEVEL, 311 {0x04118000, 0, IPR_DEFAULT_LOG_LEVEL,
240 "9000: IOA reserved area data check"}, 312 "9000: IOA reserved area data check"},
241 {0x04118100, 0, IPR_DEFAULT_LOG_LEVEL, 313 {0x04118100, 0, IPR_DEFAULT_LOG_LEVEL,
242 "9001: IOA reserved area invalid data pattern"}, 314 "9001: IOA reserved area invalid data pattern"},
243 {0x04118200, 0, IPR_DEFAULT_LOG_LEVEL, 315 {0x04118200, 0, IPR_DEFAULT_LOG_LEVEL,
244 "9002: IOA reserved area LRC error"}, 316 "9002: IOA reserved area LRC error"},
317 {0x04118300, 1, IPR_DEFAULT_LOG_LEVEL,
318 "Hardware Error, IOA metadata access error"},
245 {0x04320000, 0, IPR_DEFAULT_LOG_LEVEL, 319 {0x04320000, 0, IPR_DEFAULT_LOG_LEVEL,
246 "102E: Out of alternate sectors for disk storage"}, 320 "102E: Out of alternate sectors for disk storage"},
247 {0x04330000, 1, IPR_DEFAULT_LOG_LEVEL, 321 {0x04330000, 1, IPR_DEFAULT_LOG_LEVEL,
@@ -306,6 +380,8 @@ struct ipr_error_table_t ipr_error_table[] = {
306 "Illegal request, commands not allowed to this device"}, 380 "Illegal request, commands not allowed to this device"},
307 {0x05258100, 0, 0, 381 {0x05258100, 0, 0,
308 "Illegal request, command not allowed to a secondary adapter"}, 382 "Illegal request, command not allowed to a secondary adapter"},
383 {0x05258200, 0, 0,
384 "Illegal request, command not allowed to a non-optimized resource"},
309 {0x05260000, 0, 0, 385 {0x05260000, 0, 0,
310 "Illegal request, invalid field in parameter list"}, 386 "Illegal request, invalid field in parameter list"},
311 {0x05260100, 0, 0, 387 {0x05260100, 0, 0,
@@ -468,7 +544,10 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd,
468 trace_entry->time = jiffies; 544 trace_entry->time = jiffies;
469 trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0]; 545 trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0];
470 trace_entry->type = type; 546 trace_entry->type = type;
471 trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command; 547 if (ipr_cmd->ioa_cfg->sis64)
548 trace_entry->ata_op_code = ipr_cmd->i.ata_ioadl.regs.command;
549 else
550 trace_entry->ata_op_code = ipr_cmd->ioarcb.u.add_data.u.regs.command;
472 trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff; 551 trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff;
473 trace_entry->res_handle = ipr_cmd->ioarcb.res_handle; 552 trace_entry->res_handle = ipr_cmd->ioarcb.res_handle;
474 trace_entry->u.add_data = add_data; 553 trace_entry->u.add_data = add_data;
@@ -488,16 +567,23 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
488{ 567{
489 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 568 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
490 struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; 569 struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
491 dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); 570 dma_addr_t dma_addr = ipr_cmd->dma_addr;
492 571
493 memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); 572 memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
494 ioarcb->write_data_transfer_length = 0; 573 ioarcb->data_transfer_length = 0;
495 ioarcb->read_data_transfer_length = 0; 574 ioarcb->read_data_transfer_length = 0;
496 ioarcb->write_ioadl_len = 0; 575 ioarcb->ioadl_len = 0;
497 ioarcb->read_ioadl_len = 0; 576 ioarcb->read_ioadl_len = 0;
498 ioarcb->write_ioadl_addr = 577
499 cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); 578 if (ipr_cmd->ioa_cfg->sis64)
500 ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; 579 ioarcb->u.sis64_addr_data.data_ioadl_addr =
580 cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
581 else {
582 ioarcb->write_ioadl_addr =
583 cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
584 ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
585 }
586
501 ioasa->ioasc = 0; 587 ioasa->ioasc = 0;
502 ioasa->residual_data_len = 0; 588 ioasa->residual_data_len = 0;
503 ioasa->u.gata.status = 0; 589 ioasa->u.gata.status = 0;
@@ -562,10 +648,15 @@ static void ipr_mask_and_clear_interrupts(struct ipr_ioa_cfg *ioa_cfg,
562 ioa_cfg->allow_interrupts = 0; 648 ioa_cfg->allow_interrupts = 0;
563 649
564 /* Set interrupt mask to stop all new interrupts */ 650 /* Set interrupt mask to stop all new interrupts */
565 writel(~0, ioa_cfg->regs.set_interrupt_mask_reg); 651 if (ioa_cfg->sis64)
652 writeq(~0, ioa_cfg->regs.set_interrupt_mask_reg);
653 else
654 writel(~0, ioa_cfg->regs.set_interrupt_mask_reg);
566 655
567 /* Clear any pending interrupts */ 656 /* Clear any pending interrupts */
568 writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg); 657 if (ioa_cfg->sis64)
658 writel(~0, ioa_cfg->regs.clr_interrupt_reg);
659 writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg32);
569 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); 660 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
570} 661}
571 662
@@ -693,6 +784,35 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg)
693} 784}
694 785
695/** 786/**
787 * ipr_send_command - Send driver initiated requests.
788 * @ipr_cmd: ipr command struct
789 *
790 * This function sends a command to the adapter using the correct write call.
791 * In the case of sis64, calculate the ioarcb size required. Then or in the
792 * appropriate bits.
793 *
794 * Return value:
795 * none
796 **/
797static void ipr_send_command(struct ipr_cmnd *ipr_cmd)
798{
799 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
800 dma_addr_t send_dma_addr = ipr_cmd->dma_addr;
801
802 if (ioa_cfg->sis64) {
803 /* The default size is 256 bytes */
804 send_dma_addr |= 0x1;
805
806 /* If the number of ioadls * size of ioadl > 128 bytes,
807 then use a 512 byte ioarcb */
808 if (ipr_cmd->dma_use_sg * sizeof(struct ipr_ioadl64_desc) > 128 )
809 send_dma_addr |= 0x4;
810 writeq(send_dma_addr, ioa_cfg->regs.ioarrin_reg);
811 } else
812 writel(send_dma_addr, ioa_cfg->regs.ioarrin_reg);
813}
814
815/**
696 * ipr_do_req - Send driver initiated requests. 816 * ipr_do_req - Send driver initiated requests.
697 * @ipr_cmd: ipr command struct 817 * @ipr_cmd: ipr command struct
698 * @done: done function 818 * @done: done function
@@ -724,8 +844,8 @@ static void ipr_do_req(struct ipr_cmnd *ipr_cmd,
724 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0); 844 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0);
725 845
726 mb(); 846 mb();
727 writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), 847
728 ioa_cfg->regs.ioarrin_reg); 848 ipr_send_command(ipr_cmd);
729} 849}
730 850
731/** 851/**
@@ -747,6 +867,51 @@ static void ipr_internal_cmd_done(struct ipr_cmnd *ipr_cmd)
747} 867}
748 868
749/** 869/**
870 * ipr_init_ioadl - initialize the ioadl for the correct SIS type
871 * @ipr_cmd: ipr command struct
872 * @dma_addr: dma address
873 * @len: transfer length
874 * @flags: ioadl flag value
875 *
876 * This function initializes an ioadl in the case where there is only a single
877 * descriptor.
878 *
879 * Return value:
880 * nothing
881 **/
882static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr,
883 u32 len, int flags)
884{
885 struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
886 struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
887
888 ipr_cmd->dma_use_sg = 1;
889
890 if (ipr_cmd->ioa_cfg->sis64) {
891 ioadl64->flags = cpu_to_be32(flags);
892 ioadl64->data_len = cpu_to_be32(len);
893 ioadl64->address = cpu_to_be64(dma_addr);
894
895 ipr_cmd->ioarcb.ioadl_len =
896 cpu_to_be32(sizeof(struct ipr_ioadl64_desc));
897 ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len);
898 } else {
899 ioadl->flags_and_data_len = cpu_to_be32(flags | len);
900 ioadl->address = cpu_to_be32(dma_addr);
901
902 if (flags == IPR_IOADL_FLAGS_READ_LAST) {
903 ipr_cmd->ioarcb.read_ioadl_len =
904 cpu_to_be32(sizeof(struct ipr_ioadl_desc));
905 ipr_cmd->ioarcb.read_data_transfer_length = cpu_to_be32(len);
906 } else {
907 ipr_cmd->ioarcb.ioadl_len =
908 cpu_to_be32(sizeof(struct ipr_ioadl_desc));
909 ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len);
910 }
911 }
912}
913
914/**
750 * ipr_send_blocking_cmd - Send command and sleep on its completion. 915 * ipr_send_blocking_cmd - Send command and sleep on its completion.
751 * @ipr_cmd: ipr command struct 916 * @ipr_cmd: ipr command struct
752 * @timeout_func: function to invoke if command times out 917 * @timeout_func: function to invoke if command times out
@@ -803,11 +968,8 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type,
803 ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff; 968 ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff;
804 ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff; 969 ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff;
805 970
806 ioarcb->read_data_transfer_length = cpu_to_be32(sizeof(hostrcb->hcam)); 971 ipr_init_ioadl(ipr_cmd, hostrcb->hostrcb_dma,
807 ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); 972 sizeof(hostrcb->hcam), IPR_IOADL_FLAGS_READ_LAST);
808 ipr_cmd->ioadl[0].flags_and_data_len =
809 cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(hostrcb->hcam));
810 ipr_cmd->ioadl[0].address = cpu_to_be32(hostrcb->hostrcb_dma);
811 973
812 if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE) 974 if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE)
813 ipr_cmd->done = ipr_process_ccn; 975 ipr_cmd->done = ipr_process_ccn;
@@ -817,22 +979,54 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type,
817 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR); 979 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR);
818 980
819 mb(); 981 mb();
820 writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), 982
821 ioa_cfg->regs.ioarrin_reg); 983 ipr_send_command(ipr_cmd);
822 } else { 984 } else {
823 list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); 985 list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q);
824 } 986 }
825} 987}
826 988
827/** 989/**
990 * ipr_update_ata_class - Update the ata class in the resource entry
991 * @res: resource entry struct
992 * @proto: cfgte device bus protocol value
993 *
994 * Return value:
995 * none
996 **/
997static void ipr_update_ata_class(struct ipr_resource_entry *res, unsigned int proto)
998{
999 switch(proto) {
1000 case IPR_PROTO_SATA:
1001 case IPR_PROTO_SAS_STP:
1002 res->ata_class = ATA_DEV_ATA;
1003 break;
1004 case IPR_PROTO_SATA_ATAPI:
1005 case IPR_PROTO_SAS_STP_ATAPI:
1006 res->ata_class = ATA_DEV_ATAPI;
1007 break;
1008 default:
1009 res->ata_class = ATA_DEV_UNKNOWN;
1010 break;
1011 };
1012}
1013
1014/**
828 * ipr_init_res_entry - Initialize a resource entry struct. 1015 * ipr_init_res_entry - Initialize a resource entry struct.
829 * @res: resource entry struct 1016 * @res: resource entry struct
1017 * @cfgtew: config table entry wrapper struct
830 * 1018 *
831 * Return value: 1019 * Return value:
832 * none 1020 * none
833 **/ 1021 **/
834static void ipr_init_res_entry(struct ipr_resource_entry *res) 1022static void ipr_init_res_entry(struct ipr_resource_entry *res,
1023 struct ipr_config_table_entry_wrapper *cfgtew)
835{ 1024{
1025 int found = 0;
1026 unsigned int proto;
1027 struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg;
1028 struct ipr_resource_entry *gscsi_res = NULL;
1029
836 res->needs_sync_complete = 0; 1030 res->needs_sync_complete = 0;
837 res->in_erp = 0; 1031 res->in_erp = 0;
838 res->add_to_ml = 0; 1032 res->add_to_ml = 0;
@@ -840,6 +1034,205 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res)
840 res->resetting_device = 0; 1034 res->resetting_device = 0;
841 res->sdev = NULL; 1035 res->sdev = NULL;
842 res->sata_port = NULL; 1036 res->sata_port = NULL;
1037
1038 if (ioa_cfg->sis64) {
1039 proto = cfgtew->u.cfgte64->proto;
1040 res->res_flags = cfgtew->u.cfgte64->res_flags;
1041 res->qmodel = IPR_QUEUEING_MODEL64(res);
1042 res->type = cfgtew->u.cfgte64->res_type & 0x0f;
1043
1044 memcpy(res->res_path, &cfgtew->u.cfgte64->res_path,
1045 sizeof(res->res_path));
1046
1047 res->bus = 0;
1048 res->lun = scsilun_to_int(&res->dev_lun);
1049
1050 if (res->type == IPR_RES_TYPE_GENERIC_SCSI) {
1051 list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue) {
1052 if (gscsi_res->dev_id == cfgtew->u.cfgte64->dev_id) {
1053 found = 1;
1054 res->target = gscsi_res->target;
1055 break;
1056 }
1057 }
1058 if (!found) {
1059 res->target = find_first_zero_bit(ioa_cfg->target_ids,
1060 ioa_cfg->max_devs_supported);
1061 set_bit(res->target, ioa_cfg->target_ids);
1062 }
1063
1064 memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
1065 sizeof(res->dev_lun.scsi_lun));
1066 } else if (res->type == IPR_RES_TYPE_IOAFP) {
1067 res->bus = IPR_IOAFP_VIRTUAL_BUS;
1068 res->target = 0;
1069 } else if (res->type == IPR_RES_TYPE_ARRAY) {
1070 res->bus = IPR_ARRAY_VIRTUAL_BUS;
1071 res->target = find_first_zero_bit(ioa_cfg->array_ids,
1072 ioa_cfg->max_devs_supported);
1073 set_bit(res->target, ioa_cfg->array_ids);
1074 } else if (res->type == IPR_RES_TYPE_VOLUME_SET) {
1075 res->bus = IPR_VSET_VIRTUAL_BUS;
1076 res->target = find_first_zero_bit(ioa_cfg->vset_ids,
1077 ioa_cfg->max_devs_supported);
1078 set_bit(res->target, ioa_cfg->vset_ids);
1079 } else {
1080 res->target = find_first_zero_bit(ioa_cfg->target_ids,
1081 ioa_cfg->max_devs_supported);
1082 set_bit(res->target, ioa_cfg->target_ids);
1083 }
1084 } else {
1085 proto = cfgtew->u.cfgte->proto;
1086 res->qmodel = IPR_QUEUEING_MODEL(res);
1087 res->flags = cfgtew->u.cfgte->flags;
1088 if (res->flags & IPR_IS_IOA_RESOURCE)
1089 res->type = IPR_RES_TYPE_IOAFP;
1090 else
1091 res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f;
1092
1093 res->bus = cfgtew->u.cfgte->res_addr.bus;
1094 res->target = cfgtew->u.cfgte->res_addr.target;
1095 res->lun = cfgtew->u.cfgte->res_addr.lun;
1096 }
1097
1098 ipr_update_ata_class(res, proto);
1099}
1100
1101/**
1102 * ipr_is_same_device - Determine if two devices are the same.
1103 * @res: resource entry struct
1104 * @cfgtew: config table entry wrapper struct
1105 *
1106 * Return value:
1107 * 1 if the devices are the same / 0 otherwise
1108 **/
1109static int ipr_is_same_device(struct ipr_resource_entry *res,
1110 struct ipr_config_table_entry_wrapper *cfgtew)
1111{
1112 if (res->ioa_cfg->sis64) {
1113 if (!memcmp(&res->dev_id, &cfgtew->u.cfgte64->dev_id,
1114 sizeof(cfgtew->u.cfgte64->dev_id)) &&
1115 !memcmp(&res->lun, &cfgtew->u.cfgte64->lun,
1116 sizeof(cfgtew->u.cfgte64->lun))) {
1117 return 1;
1118 }
1119 } else {
1120 if (res->bus == cfgtew->u.cfgte->res_addr.bus &&
1121 res->target == cfgtew->u.cfgte->res_addr.target &&
1122 res->lun == cfgtew->u.cfgte->res_addr.lun)
1123 return 1;
1124 }
1125
1126 return 0;
1127}
1128
1129/**
1130 * ipr_format_resource_path - Format the resource path for printing.
1131 * @res_path: resource path
1132 * @buf: buffer
1133 *
1134 * Return value:
1135 * pointer to buffer
1136 **/
1137static char *ipr_format_resource_path(u8 *res_path, char *buffer)
1138{
1139 int i;
1140
1141 sprintf(buffer, "%02X", res_path[0]);
1142 for (i=1; res_path[i] != 0xff; i++)
1143 sprintf(buffer, "%s-%02X", buffer, res_path[i]);
1144
1145 return buffer;
1146}
1147
1148/**
1149 * ipr_update_res_entry - Update the resource entry.
1150 * @res: resource entry struct
1151 * @cfgtew: config table entry wrapper struct
1152 *
1153 * Return value:
1154 * none
1155 **/
1156static void ipr_update_res_entry(struct ipr_resource_entry *res,
1157 struct ipr_config_table_entry_wrapper *cfgtew)
1158{
1159 char buffer[IPR_MAX_RES_PATH_LENGTH];
1160 unsigned int proto;
1161 int new_path = 0;
1162
1163 if (res->ioa_cfg->sis64) {
1164 res->flags = cfgtew->u.cfgte64->flags;
1165 res->res_flags = cfgtew->u.cfgte64->res_flags;
1166 res->type = cfgtew->u.cfgte64->res_type & 0x0f;
1167
1168 memcpy(&res->std_inq_data, &cfgtew->u.cfgte64->std_inq_data,
1169 sizeof(struct ipr_std_inq_data));
1170
1171 res->qmodel = IPR_QUEUEING_MODEL64(res);
1172 proto = cfgtew->u.cfgte64->proto;
1173 res->res_handle = cfgtew->u.cfgte64->res_handle;
1174 res->dev_id = cfgtew->u.cfgte64->dev_id;
1175
1176 memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
1177 sizeof(res->dev_lun.scsi_lun));
1178
1179 if (memcmp(res->res_path, &cfgtew->u.cfgte64->res_path,
1180 sizeof(res->res_path))) {
1181 memcpy(res->res_path, &cfgtew->u.cfgte64->res_path,
1182 sizeof(res->res_path));
1183 new_path = 1;
1184 }
1185
1186 if (res->sdev && new_path)
1187 sdev_printk(KERN_INFO, res->sdev, "Resource path: %s\n",
1188 ipr_format_resource_path(&res->res_path[0], &buffer[0]));
1189 } else {
1190 res->flags = cfgtew->u.cfgte->flags;
1191 if (res->flags & IPR_IS_IOA_RESOURCE)
1192 res->type = IPR_RES_TYPE_IOAFP;
1193 else
1194 res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f;
1195
1196 memcpy(&res->std_inq_data, &cfgtew->u.cfgte->std_inq_data,
1197 sizeof(struct ipr_std_inq_data));
1198
1199 res->qmodel = IPR_QUEUEING_MODEL(res);
1200 proto = cfgtew->u.cfgte->proto;
1201 res->res_handle = cfgtew->u.cfgte->res_handle;
1202 }
1203
1204 ipr_update_ata_class(res, proto);
1205}
1206
1207/**
1208 * ipr_clear_res_target - Clear the bit in the bit map representing the target
1209 * for the resource.
1210 * @res: resource entry struct
1211 * @cfgtew: config table entry wrapper struct
1212 *
1213 * Return value:
1214 * none
1215 **/
1216static void ipr_clear_res_target(struct ipr_resource_entry *res)
1217{
1218 struct ipr_resource_entry *gscsi_res = NULL;
1219 struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg;
1220
1221 if (!ioa_cfg->sis64)
1222 return;
1223
1224 if (res->bus == IPR_ARRAY_VIRTUAL_BUS)
1225 clear_bit(res->target, ioa_cfg->array_ids);
1226 else if (res->bus == IPR_VSET_VIRTUAL_BUS)
1227 clear_bit(res->target, ioa_cfg->vset_ids);
1228 else if (res->bus == 0 && res->type == IPR_RES_TYPE_GENERIC_SCSI) {
1229 list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue)
1230 if (gscsi_res->dev_id == res->dev_id && gscsi_res != res)
1231 return;
1232 clear_bit(res->target, ioa_cfg->target_ids);
1233
1234 } else if (res->bus == 0)
1235 clear_bit(res->target, ioa_cfg->target_ids);
843} 1236}
844 1237
845/** 1238/**
@@ -851,17 +1244,24 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res)
851 * none 1244 * none
852 **/ 1245 **/
853static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, 1246static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg,
854 struct ipr_hostrcb *hostrcb) 1247 struct ipr_hostrcb *hostrcb)
855{ 1248{
856 struct ipr_resource_entry *res = NULL; 1249 struct ipr_resource_entry *res = NULL;
857 struct ipr_config_table_entry *cfgte; 1250 struct ipr_config_table_entry_wrapper cfgtew;
1251 __be32 cc_res_handle;
1252
858 u32 is_ndn = 1; 1253 u32 is_ndn = 1;
859 1254
860 cfgte = &hostrcb->hcam.u.ccn.cfgte; 1255 if (ioa_cfg->sis64) {
1256 cfgtew.u.cfgte64 = &hostrcb->hcam.u.ccn.u.cfgte64;
1257 cc_res_handle = cfgtew.u.cfgte64->res_handle;
1258 } else {
1259 cfgtew.u.cfgte = &hostrcb->hcam.u.ccn.u.cfgte;
1260 cc_res_handle = cfgtew.u.cfgte->res_handle;
1261 }
861 1262
862 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 1263 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
863 if (!memcmp(&res->cfgte.res_addr, &cfgte->res_addr, 1264 if (res->res_handle == cc_res_handle) {
864 sizeof(cfgte->res_addr))) {
865 is_ndn = 0; 1265 is_ndn = 0;
866 break; 1266 break;
867 } 1267 }
@@ -879,20 +1279,22 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg,
879 struct ipr_resource_entry, queue); 1279 struct ipr_resource_entry, queue);
880 1280
881 list_del(&res->queue); 1281 list_del(&res->queue);
882 ipr_init_res_entry(res); 1282 ipr_init_res_entry(res, &cfgtew);
883 list_add_tail(&res->queue, &ioa_cfg->used_res_q); 1283 list_add_tail(&res->queue, &ioa_cfg->used_res_q);
884 } 1284 }
885 1285
886 memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry)); 1286 ipr_update_res_entry(res, &cfgtew);
887 1287
888 if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) { 1288 if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) {
889 if (res->sdev) { 1289 if (res->sdev) {
890 res->del_from_ml = 1; 1290 res->del_from_ml = 1;
891 res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; 1291 res->res_handle = IPR_INVALID_RES_HANDLE;
892 if (ioa_cfg->allow_ml_add_del) 1292 if (ioa_cfg->allow_ml_add_del)
893 schedule_work(&ioa_cfg->work_q); 1293 schedule_work(&ioa_cfg->work_q);
894 } else 1294 } else {
1295 ipr_clear_res_target(res);
895 list_move_tail(&res->queue, &ioa_cfg->free_res_q); 1296 list_move_tail(&res->queue, &ioa_cfg->free_res_q);
1297 }
896 } else if (!res->sdev) { 1298 } else if (!res->sdev) {
897 res->add_to_ml = 1; 1299 res->add_to_ml = 1;
898 if (ioa_cfg->allow_ml_add_del) 1300 if (ioa_cfg->allow_ml_add_del)
@@ -1044,8 +1446,12 @@ static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd)
1044static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg, 1446static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg,
1045 struct ipr_hostrcb *hostrcb) 1447 struct ipr_hostrcb *hostrcb)
1046{ 1448{
1047 struct ipr_hostrcb_type_12_error *error = 1449 struct ipr_hostrcb_type_12_error *error;
1048 &hostrcb->hcam.u.error.u.type_12_error; 1450
1451 if (ioa_cfg->sis64)
1452 error = &hostrcb->hcam.u.error64.u.type_12_error;
1453 else
1454 error = &hostrcb->hcam.u.error.u.type_12_error;
1049 1455
1050 ipr_err("-----Current Configuration-----\n"); 1456 ipr_err("-----Current Configuration-----\n");
1051 ipr_err("Cache Directory Card Information:\n"); 1457 ipr_err("Cache Directory Card Information:\n");
@@ -1138,6 +1544,48 @@ static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg,
1138} 1544}
1139 1545
1140/** 1546/**
1547 * ipr_log_sis64_config_error - Log a device error.
1548 * @ioa_cfg: ioa config struct
1549 * @hostrcb: hostrcb struct
1550 *
1551 * Return value:
1552 * none
1553 **/
1554static void ipr_log_sis64_config_error(struct ipr_ioa_cfg *ioa_cfg,
1555 struct ipr_hostrcb *hostrcb)
1556{
1557 int errors_logged, i;
1558 struct ipr_hostrcb64_device_data_entry_enhanced *dev_entry;
1559 struct ipr_hostrcb_type_23_error *error;
1560 char buffer[IPR_MAX_RES_PATH_LENGTH];
1561
1562 error = &hostrcb->hcam.u.error64.u.type_23_error;
1563 errors_logged = be32_to_cpu(error->errors_logged);
1564
1565 ipr_err("Device Errors Detected/Logged: %d/%d\n",
1566 be32_to_cpu(error->errors_detected), errors_logged);
1567
1568 dev_entry = error->dev;
1569
1570 for (i = 0; i < errors_logged; i++, dev_entry++) {
1571 ipr_err_separator;
1572
1573 ipr_err("Device %d : %s", i + 1,
1574 ipr_format_resource_path(&dev_entry->res_path[0], &buffer[0]));
1575 ipr_log_ext_vpd(&dev_entry->vpd);
1576
1577 ipr_err("-----New Device Information-----\n");
1578 ipr_log_ext_vpd(&dev_entry->new_vpd);
1579
1580 ipr_err("Cache Directory Card Information:\n");
1581 ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd);
1582
1583 ipr_err("Adapter Card Information:\n");
1584 ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd);
1585 }
1586}
1587
1588/**
1141 * ipr_log_config_error - Log a configuration error. 1589 * ipr_log_config_error - Log a configuration error.
1142 * @ioa_cfg: ioa config struct 1590 * @ioa_cfg: ioa config struct
1143 * @hostrcb: hostrcb struct 1591 * @hostrcb: hostrcb struct
@@ -1331,7 +1779,11 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
1331{ 1779{
1332 struct ipr_hostrcb_type_17_error *error; 1780 struct ipr_hostrcb_type_17_error *error;
1333 1781
1334 error = &hostrcb->hcam.u.error.u.type_17_error; 1782 if (ioa_cfg->sis64)
1783 error = &hostrcb->hcam.u.error64.u.type_17_error;
1784 else
1785 error = &hostrcb->hcam.u.error.u.type_17_error;
1786
1335 error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; 1787 error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
1336 strim(error->failure_reason); 1788 strim(error->failure_reason);
1337 1789
@@ -1438,6 +1890,42 @@ static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb,
1438 fabric->ioa_port, fabric->cascaded_expander, fabric->phy); 1890 fabric->ioa_port, fabric->cascaded_expander, fabric->phy);
1439} 1891}
1440 1892
1893/**
1894 * ipr_log64_fabric_path - Log a fabric path error
1895 * @hostrcb: hostrcb struct
1896 * @fabric: fabric descriptor
1897 *
1898 * Return value:
1899 * none
1900 **/
1901static void ipr_log64_fabric_path(struct ipr_hostrcb *hostrcb,
1902 struct ipr_hostrcb64_fabric_desc *fabric)
1903{
1904 int i, j;
1905 u8 path_state = fabric->path_state;
1906 u8 active = path_state & IPR_PATH_ACTIVE_MASK;
1907 u8 state = path_state & IPR_PATH_STATE_MASK;
1908 char buffer[IPR_MAX_RES_PATH_LENGTH];
1909
1910 for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) {
1911 if (path_active_desc[i].active != active)
1912 continue;
1913
1914 for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) {
1915 if (path_state_desc[j].state != state)
1916 continue;
1917
1918 ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s\n",
1919 path_active_desc[i].desc, path_state_desc[j].desc,
1920 ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
1921 return;
1922 }
1923 }
1924
1925 ipr_err("Path state=%02X Resource Path=%s\n", path_state,
1926 ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
1927}
1928
1441static const struct { 1929static const struct {
1442 u8 type; 1930 u8 type;
1443 char *desc; 1931 char *desc;
@@ -1547,6 +2035,49 @@ static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb,
1547} 2035}
1548 2036
1549/** 2037/**
2038 * ipr_log64_path_elem - Log a fabric path element.
2039 * @hostrcb: hostrcb struct
2040 * @cfg: fabric path element struct
2041 *
2042 * Return value:
2043 * none
2044 **/
2045static void ipr_log64_path_elem(struct ipr_hostrcb *hostrcb,
2046 struct ipr_hostrcb64_config_element *cfg)
2047{
2048 int i, j;
2049 u8 desc_id = cfg->descriptor_id & IPR_DESCRIPTOR_MASK;
2050 u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK;
2051 u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK;
2052 char buffer[IPR_MAX_RES_PATH_LENGTH];
2053
2054 if (type == IPR_PATH_CFG_NOT_EXIST || desc_id != IPR_DESCRIPTOR_SIS64)
2055 return;
2056
2057 for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) {
2058 if (path_type_desc[i].type != type)
2059 continue;
2060
2061 for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) {
2062 if (path_status_desc[j].status != status)
2063 continue;
2064
2065 ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s, Link rate=%s, WWN=%08X%08X\n",
2066 path_status_desc[j].desc, path_type_desc[i].desc,
2067 ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
2068 link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
2069 be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
2070 return;
2071 }
2072 }
2073 ipr_hcam_err(hostrcb, "Path element=%02X: Resource Path=%s, Link rate=%s "
2074 "WWN=%08X%08X\n", cfg->type_status,
2075 ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
2076 link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
2077 be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
2078}
2079
2080/**
1550 * ipr_log_fabric_error - Log a fabric error. 2081 * ipr_log_fabric_error - Log a fabric error.
1551 * @ioa_cfg: ioa config struct 2082 * @ioa_cfg: ioa config struct
1552 * @hostrcb: hostrcb struct 2083 * @hostrcb: hostrcb struct
@@ -1584,6 +2115,96 @@ static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
1584} 2115}
1585 2116
1586/** 2117/**
2118 * ipr_log_sis64_array_error - Log a sis64 array error.
2119 * @ioa_cfg: ioa config struct
2120 * @hostrcb: hostrcb struct
2121 *
2122 * Return value:
2123 * none
2124 **/
2125static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg,
2126 struct ipr_hostrcb *hostrcb)
2127{
2128 int i, num_entries;
2129 struct ipr_hostrcb_type_24_error *error;
2130 struct ipr_hostrcb64_array_data_entry *array_entry;
2131 char buffer[IPR_MAX_RES_PATH_LENGTH];
2132 const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' };
2133
2134 error = &hostrcb->hcam.u.error64.u.type_24_error;
2135
2136 ipr_err_separator;
2137
2138 ipr_err("RAID %s Array Configuration: %s\n",
2139 error->protection_level,
2140 ipr_format_resource_path(&error->last_res_path[0], &buffer[0]));
2141
2142 ipr_err_separator;
2143
2144 array_entry = error->array_member;
2145 num_entries = min_t(u32, be32_to_cpu(error->num_entries),
2146 sizeof(error->array_member));
2147
2148 for (i = 0; i < num_entries; i++, array_entry++) {
2149
2150 if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN))
2151 continue;
2152
2153 if (error->exposed_mode_adn == i)
2154 ipr_err("Exposed Array Member %d:\n", i);
2155 else
2156 ipr_err("Array Member %d:\n", i);
2157
2158 ipr_err("Array Member %d:\n", i);
2159 ipr_log_ext_vpd(&array_entry->vpd);
2160 ipr_err("Current Location: %s",
2161 ipr_format_resource_path(&array_entry->res_path[0], &buffer[0]));
2162 ipr_err("Expected Location: %s",
2163 ipr_format_resource_path(&array_entry->expected_res_path[0], &buffer[0]));
2164
2165 ipr_err_separator;
2166 }
2167}
2168
2169/**
2170 * ipr_log_sis64_fabric_error - Log a sis64 fabric error.
2171 * @ioa_cfg: ioa config struct
2172 * @hostrcb: hostrcb struct
2173 *
2174 * Return value:
2175 * none
2176 **/
2177static void ipr_log_sis64_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
2178 struct ipr_hostrcb *hostrcb)
2179{
2180 struct ipr_hostrcb_type_30_error *error;
2181 struct ipr_hostrcb64_fabric_desc *fabric;
2182 struct ipr_hostrcb64_config_element *cfg;
2183 int i, add_len;
2184
2185 error = &hostrcb->hcam.u.error64.u.type_30_error;
2186
2187 error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
2188 ipr_hcam_err(hostrcb, "%s\n", error->failure_reason);
2189
2190 add_len = be32_to_cpu(hostrcb->hcam.length) -
2191 (offsetof(struct ipr_hostrcb64_error, u) +
2192 offsetof(struct ipr_hostrcb_type_30_error, desc));
2193
2194 for (i = 0, fabric = error->desc; i < error->num_entries; i++) {
2195 ipr_log64_fabric_path(hostrcb, fabric);
2196 for_each_fabric_cfg(fabric, cfg)
2197 ipr_log64_path_elem(hostrcb, cfg);
2198
2199 add_len -= be16_to_cpu(fabric->length);
2200 fabric = (struct ipr_hostrcb64_fabric_desc *)
2201 ((unsigned long)fabric + be16_to_cpu(fabric->length));
2202 }
2203
2204 ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len);
2205}
2206
2207/**
1587 * ipr_log_generic_error - Log an adapter error. 2208 * ipr_log_generic_error - Log an adapter error.
1588 * @ioa_cfg: ioa config struct 2209 * @ioa_cfg: ioa config struct
1589 * @hostrcb: hostrcb struct 2210 * @hostrcb: hostrcb struct
@@ -1642,13 +2263,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
1642 if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST) 2263 if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST)
1643 dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n"); 2264 dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n");
1644 2265
1645 ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); 2266 if (ioa_cfg->sis64)
2267 ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc);
2268 else
2269 ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
1646 2270
1647 if (ioasc == IPR_IOASC_BUS_WAS_RESET || 2271 if (!ioa_cfg->sis64 && (ioasc == IPR_IOASC_BUS_WAS_RESET ||
1648 ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER) { 2272 ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER)) {
1649 /* Tell the midlayer we had a bus reset so it will handle the UA properly */ 2273 /* Tell the midlayer we had a bus reset so it will handle the UA properly */
1650 scsi_report_bus_reset(ioa_cfg->host, 2274 scsi_report_bus_reset(ioa_cfg->host,
1651 hostrcb->hcam.u.error.failing_dev_res_addr.bus); 2275 hostrcb->hcam.u.error.fd_res_addr.bus);
1652 } 2276 }
1653 2277
1654 error_index = ipr_get_error(ioasc); 2278 error_index = ipr_get_error(ioasc);
@@ -1696,6 +2320,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
1696 case IPR_HOST_RCB_OVERLAY_ID_20: 2320 case IPR_HOST_RCB_OVERLAY_ID_20:
1697 ipr_log_fabric_error(ioa_cfg, hostrcb); 2321 ipr_log_fabric_error(ioa_cfg, hostrcb);
1698 break; 2322 break;
2323 case IPR_HOST_RCB_OVERLAY_ID_23:
2324 ipr_log_sis64_config_error(ioa_cfg, hostrcb);
2325 break;
2326 case IPR_HOST_RCB_OVERLAY_ID_24:
2327 case IPR_HOST_RCB_OVERLAY_ID_26:
2328 ipr_log_sis64_array_error(ioa_cfg, hostrcb);
2329 break;
2330 case IPR_HOST_RCB_OVERLAY_ID_30:
2331 ipr_log_sis64_fabric_error(ioa_cfg, hostrcb);
2332 break;
1699 case IPR_HOST_RCB_OVERLAY_ID_1: 2333 case IPR_HOST_RCB_OVERLAY_ID_1:
1700 case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: 2334 case IPR_HOST_RCB_OVERLAY_ID_DEFAULT:
1701 default: 2335 default:
@@ -1720,7 +2354,12 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd)
1720 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 2354 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
1721 struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; 2355 struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb;
1722 u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); 2356 u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
1723 u32 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); 2357 u32 fd_ioasc;
2358
2359 if (ioa_cfg->sis64)
2360 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc);
2361 else
2362 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
1724 2363
1725 list_del(&hostrcb->queue); 2364 list_del(&hostrcb->queue);
1726 list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); 2365 list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
@@ -1845,12 +2484,14 @@ static const struct ipr_ses_table_entry *
1845ipr_find_ses_entry(struct ipr_resource_entry *res) 2484ipr_find_ses_entry(struct ipr_resource_entry *res)
1846{ 2485{
1847 int i, j, matches; 2486 int i, j, matches;
2487 struct ipr_std_inq_vpids *vpids;
1848 const struct ipr_ses_table_entry *ste = ipr_ses_table; 2488 const struct ipr_ses_table_entry *ste = ipr_ses_table;
1849 2489
1850 for (i = 0; i < ARRAY_SIZE(ipr_ses_table); i++, ste++) { 2490 for (i = 0; i < ARRAY_SIZE(ipr_ses_table); i++, ste++) {
1851 for (j = 0, matches = 0; j < IPR_PROD_ID_LEN; j++) { 2491 for (j = 0, matches = 0; j < IPR_PROD_ID_LEN; j++) {
1852 if (ste->compare_product_id_byte[j] == 'X') { 2492 if (ste->compare_product_id_byte[j] == 'X') {
1853 if (res->cfgte.std_inq_data.vpids.product_id[j] == ste->product_id[j]) 2493 vpids = &res->std_inq_data.vpids;
2494 if (vpids->product_id[j] == ste->product_id[j])
1854 matches++; 2495 matches++;
1855 else 2496 else
1856 break; 2497 break;
@@ -1885,10 +2526,10 @@ static u32 ipr_get_max_scsi_speed(struct ipr_ioa_cfg *ioa_cfg, u8 bus, u8 bus_wi
1885 2526
1886 /* Loop through each config table entry in the config table buffer */ 2527 /* Loop through each config table entry in the config table buffer */
1887 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 2528 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
1888 if (!(IPR_IS_SES_DEVICE(res->cfgte.std_inq_data))) 2529 if (!(IPR_IS_SES_DEVICE(res->std_inq_data)))
1889 continue; 2530 continue;
1890 2531
1891 if (bus != res->cfgte.res_addr.bus) 2532 if (bus != res->bus)
1892 continue; 2533 continue;
1893 2534
1894 if (!(ste = ipr_find_ses_entry(res))) 2535 if (!(ste = ipr_find_ses_entry(res)))
@@ -1934,6 +2575,31 @@ static int ipr_wait_iodbg_ack(struct ipr_ioa_cfg *ioa_cfg, int max_delay)
1934} 2575}
1935 2576
1936/** 2577/**
2578 * ipr_get_sis64_dump_data_section - Dump IOA memory
2579 * @ioa_cfg: ioa config struct
2580 * @start_addr: adapter address to dump
2581 * @dest: destination kernel buffer
2582 * @length_in_words: length to dump in 4 byte words
2583 *
2584 * Return value:
2585 * 0 on success
2586 **/
2587static int ipr_get_sis64_dump_data_section(struct ipr_ioa_cfg *ioa_cfg,
2588 u32 start_addr,
2589 __be32 *dest, u32 length_in_words)
2590{
2591 int i;
2592
2593 for (i = 0; i < length_in_words; i++) {
2594 writel(start_addr+(i*4), ioa_cfg->regs.dump_addr_reg);
2595 *dest = cpu_to_be32(readl(ioa_cfg->regs.dump_data_reg));
2596 dest++;
2597 }
2598
2599 return 0;
2600}
2601
2602/**
1937 * ipr_get_ldump_data_section - Dump IOA memory 2603 * ipr_get_ldump_data_section - Dump IOA memory
1938 * @ioa_cfg: ioa config struct 2604 * @ioa_cfg: ioa config struct
1939 * @start_addr: adapter address to dump 2605 * @start_addr: adapter address to dump
@@ -1950,9 +2616,13 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
1950 volatile u32 temp_pcii_reg; 2616 volatile u32 temp_pcii_reg;
1951 int i, delay = 0; 2617 int i, delay = 0;
1952 2618
2619 if (ioa_cfg->sis64)
2620 return ipr_get_sis64_dump_data_section(ioa_cfg, start_addr,
2621 dest, length_in_words);
2622
1953 /* Write IOA interrupt reg starting LDUMP state */ 2623 /* Write IOA interrupt reg starting LDUMP state */
1954 writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT), 2624 writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT),
1955 ioa_cfg->regs.set_uproc_interrupt_reg); 2625 ioa_cfg->regs.set_uproc_interrupt_reg32);
1956 2626
1957 /* Wait for IO debug acknowledge */ 2627 /* Wait for IO debug acknowledge */
1958 if (ipr_wait_iodbg_ack(ioa_cfg, 2628 if (ipr_wait_iodbg_ack(ioa_cfg,
@@ -1971,7 +2641,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
1971 2641
1972 /* Signal address valid - clear IOA Reset alert */ 2642 /* Signal address valid - clear IOA Reset alert */
1973 writel(IPR_UPROCI_RESET_ALERT, 2643 writel(IPR_UPROCI_RESET_ALERT,
1974 ioa_cfg->regs.clr_uproc_interrupt_reg); 2644 ioa_cfg->regs.clr_uproc_interrupt_reg32);
1975 2645
1976 for (i = 0; i < length_in_words; i++) { 2646 for (i = 0; i < length_in_words; i++) {
1977 /* Wait for IO debug acknowledge */ 2647 /* Wait for IO debug acknowledge */
@@ -1996,10 +2666,10 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
1996 2666
1997 /* Signal end of block transfer. Set reset alert then clear IO debug ack */ 2667 /* Signal end of block transfer. Set reset alert then clear IO debug ack */
1998 writel(IPR_UPROCI_RESET_ALERT, 2668 writel(IPR_UPROCI_RESET_ALERT,
1999 ioa_cfg->regs.set_uproc_interrupt_reg); 2669 ioa_cfg->regs.set_uproc_interrupt_reg32);
2000 2670
2001 writel(IPR_UPROCI_IO_DEBUG_ALERT, 2671 writel(IPR_UPROCI_IO_DEBUG_ALERT,
2002 ioa_cfg->regs.clr_uproc_interrupt_reg); 2672 ioa_cfg->regs.clr_uproc_interrupt_reg32);
2003 2673
2004 /* Signal dump data received - Clear IO debug Ack */ 2674 /* Signal dump data received - Clear IO debug Ack */
2005 writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, 2675 writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE,
@@ -2008,7 +2678,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
2008 /* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */ 2678 /* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */
2009 while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) { 2679 while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) {
2010 temp_pcii_reg = 2680 temp_pcii_reg =
2011 readl(ioa_cfg->regs.sense_uproc_interrupt_reg); 2681 readl(ioa_cfg->regs.sense_uproc_interrupt_reg32);
2012 2682
2013 if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT)) 2683 if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT))
2014 return 0; 2684 return 0;
@@ -2207,6 +2877,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
2207 u32 num_entries, start_off, end_off; 2877 u32 num_entries, start_off, end_off;
2208 u32 bytes_to_copy, bytes_copied, rc; 2878 u32 bytes_to_copy, bytes_copied, rc;
2209 struct ipr_sdt *sdt; 2879 struct ipr_sdt *sdt;
2880 int valid = 1;
2210 int i; 2881 int i;
2211 2882
2212 ENTER; 2883 ENTER;
@@ -2220,7 +2891,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
2220 2891
2221 start_addr = readl(ioa_cfg->ioa_mailbox); 2892 start_addr = readl(ioa_cfg->ioa_mailbox);
2222 2893
2223 if (!ipr_sdt_is_fmt2(start_addr)) { 2894 if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) {
2224 dev_err(&ioa_cfg->pdev->dev, 2895 dev_err(&ioa_cfg->pdev->dev,
2225 "Invalid dump table format: %lx\n", start_addr); 2896 "Invalid dump table format: %lx\n", start_addr);
2226 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 2897 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -2249,7 +2920,6 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
2249 2920
2250 /* IOA Dump entry */ 2921 /* IOA Dump entry */
2251 ipr_init_dump_entry_hdr(&ioa_dump->hdr); 2922 ipr_init_dump_entry_hdr(&ioa_dump->hdr);
2252 ioa_dump->format = IPR_SDT_FMT2;
2253 ioa_dump->hdr.len = 0; 2923 ioa_dump->hdr.len = 0;
2254 ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY; 2924 ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY;
2255 ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID; 2925 ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID;
@@ -2264,7 +2934,8 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
2264 sizeof(struct ipr_sdt) / sizeof(__be32)); 2934 sizeof(struct ipr_sdt) / sizeof(__be32));
2265 2935
2266 /* Smart Dump table is ready to use and the first entry is valid */ 2936 /* Smart Dump table is ready to use and the first entry is valid */
2267 if (rc || (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE)) { 2937 if (rc || ((be32_to_cpu(sdt->hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
2938 (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) {
2268 dev_err(&ioa_cfg->pdev->dev, 2939 dev_err(&ioa_cfg->pdev->dev,
2269 "Dump of IOA failed. Dump table not valid: %d, %X.\n", 2940 "Dump of IOA failed. Dump table not valid: %d, %X.\n",
2270 rc, be32_to_cpu(sdt->hdr.state)); 2941 rc, be32_to_cpu(sdt->hdr.state));
@@ -2288,12 +2959,19 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
2288 } 2959 }
2289 2960
2290 if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) { 2961 if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) {
2291 sdt_word = be32_to_cpu(sdt->entry[i].bar_str_offset); 2962 sdt_word = be32_to_cpu(sdt->entry[i].start_token);
2292 start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK; 2963 if (ioa_cfg->sis64)
2293 end_off = be32_to_cpu(sdt->entry[i].end_offset); 2964 bytes_to_copy = be32_to_cpu(sdt->entry[i].end_token);
2294 2965 else {
2295 if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) { 2966 start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK;
2296 bytes_to_copy = end_off - start_off; 2967 end_off = be32_to_cpu(sdt->entry[i].end_token);
2968
2969 if (ipr_sdt_is_fmt2(sdt_word) && sdt_word)
2970 bytes_to_copy = end_off - start_off;
2971 else
2972 valid = 0;
2973 }
2974 if (valid) {
2297 if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) { 2975 if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) {
2298 sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY; 2976 sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY;
2299 continue; 2977 continue;
@@ -2422,9 +3100,9 @@ restart:
2422 3100
2423 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 3101 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
2424 if (res->add_to_ml) { 3102 if (res->add_to_ml) {
2425 bus = res->cfgte.res_addr.bus; 3103 bus = res->bus;
2426 target = res->cfgte.res_addr.target; 3104 target = res->target;
2427 lun = res->cfgte.res_addr.lun; 3105 lun = res->lun;
2428 res->add_to_ml = 0; 3106 res->add_to_ml = 0;
2429 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3107 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
2430 scsi_add_device(ioa_cfg->host, bus, target, lun); 3108 scsi_add_device(ioa_cfg->host, bus, target, lun);
@@ -2478,105 +3156,6 @@ static struct bin_attribute ipr_trace_attr = {
2478}; 3156};
2479#endif 3157#endif
2480 3158
2481static const struct {
2482 enum ipr_cache_state state;
2483 char *name;
2484} cache_state [] = {
2485 { CACHE_NONE, "none" },
2486 { CACHE_DISABLED, "disabled" },
2487 { CACHE_ENABLED, "enabled" }
2488};
2489
2490/**
2491 * ipr_show_write_caching - Show the write caching attribute
2492 * @dev: device struct
2493 * @buf: buffer
2494 *
2495 * Return value:
2496 * number of bytes printed to buffer
2497 **/
2498static ssize_t ipr_show_write_caching(struct device *dev,
2499 struct device_attribute *attr, char *buf)
2500{
2501 struct Scsi_Host *shost = class_to_shost(dev);
2502 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
2503 unsigned long lock_flags = 0;
2504 int i, len = 0;
2505
2506 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
2507 for (i = 0; i < ARRAY_SIZE(cache_state); i++) {
2508 if (cache_state[i].state == ioa_cfg->cache_state) {
2509 len = snprintf(buf, PAGE_SIZE, "%s\n", cache_state[i].name);
2510 break;
2511 }
2512 }
2513 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
2514 return len;
2515}
2516
2517
2518/**
2519 * ipr_store_write_caching - Enable/disable adapter write cache
2520 * @dev: device struct
2521 * @buf: buffer
2522 * @count: buffer size
2523 *
2524 * This function will enable/disable adapter write cache.
2525 *
2526 * Return value:
2527 * count on success / other on failure
2528 **/
2529static ssize_t ipr_store_write_caching(struct device *dev,
2530 struct device_attribute *attr,
2531 const char *buf, size_t count)
2532{
2533 struct Scsi_Host *shost = class_to_shost(dev);
2534 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
2535 unsigned long lock_flags = 0;
2536 enum ipr_cache_state new_state = CACHE_INVALID;
2537 int i;
2538
2539 if (!capable(CAP_SYS_ADMIN))
2540 return -EACCES;
2541 if (ioa_cfg->cache_state == CACHE_NONE)
2542 return -EINVAL;
2543
2544 for (i = 0; i < ARRAY_SIZE(cache_state); i++) {
2545 if (!strncmp(cache_state[i].name, buf, strlen(cache_state[i].name))) {
2546 new_state = cache_state[i].state;
2547 break;
2548 }
2549 }
2550
2551 if (new_state != CACHE_DISABLED && new_state != CACHE_ENABLED)
2552 return -EINVAL;
2553
2554 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
2555 if (ioa_cfg->cache_state == new_state) {
2556 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
2557 return count;
2558 }
2559
2560 ioa_cfg->cache_state = new_state;
2561 dev_info(&ioa_cfg->pdev->dev, "%s adapter write cache.\n",
2562 new_state == CACHE_ENABLED ? "Enabling" : "Disabling");
2563 if (!ioa_cfg->in_reset_reload)
2564 ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL);
2565 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
2566 wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
2567
2568 return count;
2569}
2570
2571static struct device_attribute ipr_ioa_cache_attr = {
2572 .attr = {
2573 .name = "write_cache",
2574 .mode = S_IRUGO | S_IWUSR,
2575 },
2576 .show = ipr_show_write_caching,
2577 .store = ipr_store_write_caching
2578};
2579
2580/** 3159/**
2581 * ipr_show_fw_version - Show the firmware version 3160 * ipr_show_fw_version - Show the firmware version
2582 * @dev: class device struct 3161 * @dev: class device struct
@@ -2976,6 +3555,37 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
2976} 3555}
2977 3556
2978/** 3557/**
3558 * ipr_build_ucode_ioadl64 - Build a microcode download IOADL
3559 * @ipr_cmd: ipr command struct
3560 * @sglist: scatter/gather list
3561 *
3562 * Builds a microcode download IOA data list (IOADL).
3563 *
3564 **/
3565static void ipr_build_ucode_ioadl64(struct ipr_cmnd *ipr_cmd,
3566 struct ipr_sglist *sglist)
3567{
3568 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
3569 struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
3570 struct scatterlist *scatterlist = sglist->scatterlist;
3571 int i;
3572
3573 ipr_cmd->dma_use_sg = sglist->num_dma_sg;
3574 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
3575 ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len);
3576
3577 ioarcb->ioadl_len =
3578 cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg);
3579 for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
3580 ioadl64[i].flags = cpu_to_be32(IPR_IOADL_FLAGS_WRITE);
3581 ioadl64[i].data_len = cpu_to_be32(sg_dma_len(&scatterlist[i]));
3582 ioadl64[i].address = cpu_to_be64(sg_dma_address(&scatterlist[i]));
3583 }
3584
3585 ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
3586}
3587
3588/**
2979 * ipr_build_ucode_ioadl - Build a microcode download IOADL 3589 * ipr_build_ucode_ioadl - Build a microcode download IOADL
2980 * @ipr_cmd: ipr command struct 3590 * @ipr_cmd: ipr command struct
2981 * @sglist: scatter/gather list 3591 * @sglist: scatter/gather list
@@ -2987,14 +3597,15 @@ static void ipr_build_ucode_ioadl(struct ipr_cmnd *ipr_cmd,
2987 struct ipr_sglist *sglist) 3597 struct ipr_sglist *sglist)
2988{ 3598{
2989 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 3599 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
2990 struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; 3600 struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
2991 struct scatterlist *scatterlist = sglist->scatterlist; 3601 struct scatterlist *scatterlist = sglist->scatterlist;
2992 int i; 3602 int i;
2993 3603
2994 ipr_cmd->dma_use_sg = sglist->num_dma_sg; 3604 ipr_cmd->dma_use_sg = sglist->num_dma_sg;
2995 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; 3605 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
2996 ioarcb->write_data_transfer_length = cpu_to_be32(sglist->buffer_len); 3606 ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len);
2997 ioarcb->write_ioadl_len = 3607
3608 ioarcb->ioadl_len =
2998 cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); 3609 cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
2999 3610
3000 for (i = 0; i < ipr_cmd->dma_use_sg; i++) { 3611 for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
@@ -3146,7 +3757,6 @@ static struct device_attribute *ipr_ioa_attrs[] = {
3146 &ipr_ioa_state_attr, 3757 &ipr_ioa_state_attr,
3147 &ipr_ioa_reset_attr, 3758 &ipr_ioa_reset_attr,
3148 &ipr_update_fw_attr, 3759 &ipr_update_fw_attr,
3149 &ipr_ioa_cache_attr,
3150 NULL, 3760 NULL,
3151}; 3761};
3152 3762
@@ -3450,7 +4060,7 @@ static ssize_t ipr_show_adapter_handle(struct device *dev, struct device_attribu
3450 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); 4060 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
3451 res = (struct ipr_resource_entry *)sdev->hostdata; 4061 res = (struct ipr_resource_entry *)sdev->hostdata;
3452 if (res) 4062 if (res)
3453 len = snprintf(buf, PAGE_SIZE, "%08X\n", res->cfgte.res_handle); 4063 len = snprintf(buf, PAGE_SIZE, "%08X\n", res->res_handle);
3454 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 4064 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3455 return len; 4065 return len;
3456} 4066}
@@ -3463,8 +4073,43 @@ static struct device_attribute ipr_adapter_handle_attr = {
3463 .show = ipr_show_adapter_handle 4073 .show = ipr_show_adapter_handle
3464}; 4074};
3465 4075
4076/**
4077 * ipr_show_resource_path - Show the resource path for this device.
4078 * @dev: device struct
4079 * @buf: buffer
4080 *
4081 * Return value:
4082 * number of bytes printed to buffer
4083 **/
4084static ssize_t ipr_show_resource_path(struct device *dev, struct device_attribute *attr, char *buf)
4085{
4086 struct scsi_device *sdev = to_scsi_device(dev);
4087 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
4088 struct ipr_resource_entry *res;
4089 unsigned long lock_flags = 0;
4090 ssize_t len = -ENXIO;
4091 char buffer[IPR_MAX_RES_PATH_LENGTH];
4092
4093 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
4094 res = (struct ipr_resource_entry *)sdev->hostdata;
4095 if (res)
4096 len = snprintf(buf, PAGE_SIZE, "%s\n",
4097 ipr_format_resource_path(&res->res_path[0], &buffer[0]));
4098 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
4099 return len;
4100}
4101
4102static struct device_attribute ipr_resource_path_attr = {
4103 .attr = {
4104 .name = "resource_path",
4105 .mode = S_IRUSR,
4106 },
4107 .show = ipr_show_resource_path
4108};
4109
3466static struct device_attribute *ipr_dev_attrs[] = { 4110static struct device_attribute *ipr_dev_attrs[] = {
3467 &ipr_adapter_handle_attr, 4111 &ipr_adapter_handle_attr,
4112 &ipr_resource_path_attr,
3468 NULL, 4113 NULL,
3469}; 4114};
3470 4115
@@ -3517,9 +4162,9 @@ static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget)
3517 struct ipr_resource_entry *res; 4162 struct ipr_resource_entry *res;
3518 4163
3519 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 4164 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
3520 if ((res->cfgte.res_addr.bus == starget->channel) && 4165 if ((res->bus == starget->channel) &&
3521 (res->cfgte.res_addr.target == starget->id) && 4166 (res->target == starget->id) &&
3522 (res->cfgte.res_addr.lun == 0)) { 4167 (res->lun == 0)) {
3523 return res; 4168 return res;
3524 } 4169 }
3525 } 4170 }
@@ -3589,6 +4234,17 @@ static int ipr_target_alloc(struct scsi_target *starget)
3589static void ipr_target_destroy(struct scsi_target *starget) 4234static void ipr_target_destroy(struct scsi_target *starget)
3590{ 4235{
3591 struct ipr_sata_port *sata_port = starget->hostdata; 4236 struct ipr_sata_port *sata_port = starget->hostdata;
4237 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
4238 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
4239
4240 if (ioa_cfg->sis64) {
4241 if (starget->channel == IPR_ARRAY_VIRTUAL_BUS)
4242 clear_bit(starget->id, ioa_cfg->array_ids);
4243 else if (starget->channel == IPR_VSET_VIRTUAL_BUS)
4244 clear_bit(starget->id, ioa_cfg->vset_ids);
4245 else if (starget->channel == 0)
4246 clear_bit(starget->id, ioa_cfg->target_ids);
4247 }
3592 4248
3593 if (sata_port) { 4249 if (sata_port) {
3594 starget->hostdata = NULL; 4250 starget->hostdata = NULL;
@@ -3610,9 +4266,9 @@ static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev)
3610 struct ipr_resource_entry *res; 4266 struct ipr_resource_entry *res;
3611 4267
3612 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 4268 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
3613 if ((res->cfgte.res_addr.bus == sdev->channel) && 4269 if ((res->bus == sdev->channel) &&
3614 (res->cfgte.res_addr.target == sdev->id) && 4270 (res->target == sdev->id) &&
3615 (res->cfgte.res_addr.lun == sdev->lun)) 4271 (res->lun == sdev->lun))
3616 return res; 4272 return res;
3617 } 4273 }
3618 4274
@@ -3661,6 +4317,7 @@ static int ipr_slave_configure(struct scsi_device *sdev)
3661 struct ipr_resource_entry *res; 4317 struct ipr_resource_entry *res;
3662 struct ata_port *ap = NULL; 4318 struct ata_port *ap = NULL;
3663 unsigned long lock_flags = 0; 4319 unsigned long lock_flags = 0;
4320 char buffer[IPR_MAX_RES_PATH_LENGTH];
3664 4321
3665 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); 4322 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
3666 res = sdev->hostdata; 4323 res = sdev->hostdata;
@@ -3687,6 +4344,9 @@ static int ipr_slave_configure(struct scsi_device *sdev)
3687 ata_sas_slave_configure(sdev, ap); 4344 ata_sas_slave_configure(sdev, ap);
3688 } else 4345 } else
3689 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); 4346 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
4347 if (ioa_cfg->sis64)
4348 sdev_printk(KERN_INFO, sdev, "Resource path: %s\n",
4349 ipr_format_resource_path(&res->res_path[0], &buffer[0]));
3690 return 0; 4350 return 0;
3691 } 4351 }
3692 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 4352 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -3828,14 +4488,19 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
3828 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); 4488 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
3829 ioarcb = &ipr_cmd->ioarcb; 4489 ioarcb = &ipr_cmd->ioarcb;
3830 cmd_pkt = &ioarcb->cmd_pkt; 4490 cmd_pkt = &ioarcb->cmd_pkt;
3831 regs = &ioarcb->add_data.u.regs;
3832 4491
3833 ioarcb->res_handle = res->cfgte.res_handle; 4492 if (ipr_cmd->ioa_cfg->sis64) {
4493 regs = &ipr_cmd->i.ata_ioadl.regs;
4494 ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb));
4495 } else
4496 regs = &ioarcb->u.add_data.u.regs;
4497
4498 ioarcb->res_handle = res->res_handle;
3834 cmd_pkt->request_type = IPR_RQTYPE_IOACMD; 4499 cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
3835 cmd_pkt->cdb[0] = IPR_RESET_DEVICE; 4500 cmd_pkt->cdb[0] = IPR_RESET_DEVICE;
3836 if (ipr_is_gata(res)) { 4501 if (ipr_is_gata(res)) {
3837 cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET; 4502 cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET;
3838 ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags)); 4503 ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(regs->flags));
3839 regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; 4504 regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
3840 } 4505 }
3841 4506
@@ -3880,19 +4545,7 @@ static int ipr_sata_reset(struct ata_link *link, unsigned int *classes,
3880 res = sata_port->res; 4545 res = sata_port->res;
3881 if (res) { 4546 if (res) {
3882 rc = ipr_device_reset(ioa_cfg, res); 4547 rc = ipr_device_reset(ioa_cfg, res);
3883 switch(res->cfgte.proto) { 4548 *classes = res->ata_class;
3884 case IPR_PROTO_SATA:
3885 case IPR_PROTO_SAS_STP:
3886 *classes = ATA_DEV_ATA;
3887 break;
3888 case IPR_PROTO_SATA_ATAPI:
3889 case IPR_PROTO_SAS_STP_ATAPI:
3890 *classes = ATA_DEV_ATAPI;
3891 break;
3892 default:
3893 *classes = ATA_DEV_UNKNOWN;
3894 break;
3895 };
3896 } 4549 }
3897 4550
3898 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 4551 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -3937,7 +4590,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
3937 return FAILED; 4590 return FAILED;
3938 4591
3939 list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { 4592 list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
3940 if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { 4593 if (ipr_cmd->ioarcb.res_handle == res->res_handle) {
3941 if (ipr_cmd->scsi_cmd) 4594 if (ipr_cmd->scsi_cmd)
3942 ipr_cmd->done = ipr_scsi_eh_done; 4595 ipr_cmd->done = ipr_scsi_eh_done;
3943 if (ipr_cmd->qc) 4596 if (ipr_cmd->qc)
@@ -3959,7 +4612,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
3959 spin_lock_irq(scsi_cmd->device->host->host_lock); 4612 spin_lock_irq(scsi_cmd->device->host->host_lock);
3960 4613
3961 list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { 4614 list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
3962 if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { 4615 if (ipr_cmd->ioarcb.res_handle == res->res_handle) {
3963 rc = -EIO; 4616 rc = -EIO;
3964 break; 4617 break;
3965 } 4618 }
@@ -3998,13 +4651,13 @@ static void ipr_bus_reset_done(struct ipr_cmnd *ipr_cmd)
3998 struct ipr_resource_entry *res; 4651 struct ipr_resource_entry *res;
3999 4652
4000 ENTER; 4653 ENTER;
4001 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 4654 if (!ioa_cfg->sis64)
4002 if (!memcmp(&res->cfgte.res_handle, &ipr_cmd->ioarcb.res_handle, 4655 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
4003 sizeof(res->cfgte.res_handle))) { 4656 if (res->res_handle == ipr_cmd->ioarcb.res_handle) {
4004 scsi_report_bus_reset(ioa_cfg->host, res->cfgte.res_addr.bus); 4657 scsi_report_bus_reset(ioa_cfg->host, res->bus);
4005 break; 4658 break;
4659 }
4006 } 4660 }
4007 }
4008 4661
4009 /* 4662 /*
4010 * If abort has not completed, indicate the reset has, else call the 4663 * If abort has not completed, indicate the reset has, else call the
@@ -4102,7 +4755,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd)
4102 return SUCCESS; 4755 return SUCCESS;
4103 4756
4104 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); 4757 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
4105 ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; 4758 ipr_cmd->ioarcb.res_handle = res->res_handle;
4106 cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; 4759 cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
4107 cmd_pkt->request_type = IPR_RQTYPE_IOACMD; 4760 cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
4108 cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS; 4761 cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS;
@@ -4239,11 +4892,29 @@ static irqreturn_t ipr_isr(int irq, void *devp)
4239 return IRQ_NONE; 4892 return IRQ_NONE;
4240 } 4893 }
4241 4894
4242 int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); 4895 int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
4243 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; 4896 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
4244 4897
4245 /* If an interrupt on the adapter did not occur, ignore it */ 4898 /* If an interrupt on the adapter did not occur, ignore it.
4899 * Or in the case of SIS 64, check for a stage change interrupt.
4900 */
4246 if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) { 4901 if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) {
4902 if (ioa_cfg->sis64) {
4903 int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
4904 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
4905 if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) {
4906
4907 /* clear stage change */
4908 writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg);
4909 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
4910 list_del(&ioa_cfg->reset_cmd->queue);
4911 del_timer(&ioa_cfg->reset_cmd->timer);
4912 ipr_reset_ioa_job(ioa_cfg->reset_cmd);
4913 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
4914 return IRQ_HANDLED;
4915 }
4916 }
4917
4247 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 4918 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
4248 return IRQ_NONE; 4919 return IRQ_NONE;
4249 } 4920 }
@@ -4286,8 +4957,8 @@ static irqreturn_t ipr_isr(int irq, void *devp)
4286 if (ipr_cmd != NULL) { 4957 if (ipr_cmd != NULL) {
4287 /* Clear the PCI interrupt */ 4958 /* Clear the PCI interrupt */
4288 do { 4959 do {
4289 writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg); 4960 writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
4290 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; 4961 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
4291 } while (int_reg & IPR_PCII_HRRQ_UPDATED && 4962 } while (int_reg & IPR_PCII_HRRQ_UPDATED &&
4292 num_hrrq++ < IPR_MAX_HRRQ_RETRIES); 4963 num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
4293 4964
@@ -4309,6 +4980,53 @@ static irqreturn_t ipr_isr(int irq, void *devp)
4309} 4980}
4310 4981
4311/** 4982/**
4983 * ipr_build_ioadl64 - Build a scatter/gather list and map the buffer
4984 * @ioa_cfg: ioa config struct
4985 * @ipr_cmd: ipr command struct
4986 *
4987 * Return value:
4988 * 0 on success / -1 on failure
4989 **/
4990static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg,
4991 struct ipr_cmnd *ipr_cmd)
4992{
4993 int i, nseg;
4994 struct scatterlist *sg;
4995 u32 length;
4996 u32 ioadl_flags = 0;
4997 struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
4998 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
4999 struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
5000
5001 length = scsi_bufflen(scsi_cmd);
5002 if (!length)
5003 return 0;
5004
5005 nseg = scsi_dma_map(scsi_cmd);
5006 if (nseg < 0) {
5007 dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
5008 return -1;
5009 }
5010
5011 ipr_cmd->dma_use_sg = nseg;
5012
5013 if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
5014 ioadl_flags = IPR_IOADL_FLAGS_WRITE;
5015 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
5016 } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE)
5017 ioadl_flags = IPR_IOADL_FLAGS_READ;
5018
5019 scsi_for_each_sg(scsi_cmd, sg, ipr_cmd->dma_use_sg, i) {
5020 ioadl64[i].flags = cpu_to_be32(ioadl_flags);
5021 ioadl64[i].data_len = cpu_to_be32(sg_dma_len(sg));
5022 ioadl64[i].address = cpu_to_be64(sg_dma_address(sg));
5023 }
5024
5025 ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
5026 return 0;
5027}
5028
5029/**
4312 * ipr_build_ioadl - Build a scatter/gather list and map the buffer 5030 * ipr_build_ioadl - Build a scatter/gather list and map the buffer
4313 * @ioa_cfg: ioa config struct 5031 * @ioa_cfg: ioa config struct
4314 * @ipr_cmd: ipr command struct 5032 * @ipr_cmd: ipr command struct
@@ -4325,7 +5043,7 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
4325 u32 ioadl_flags = 0; 5043 u32 ioadl_flags = 0;
4326 struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; 5044 struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
4327 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 5045 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
4328 struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; 5046 struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
4329 5047
4330 length = scsi_bufflen(scsi_cmd); 5048 length = scsi_bufflen(scsi_cmd);
4331 if (!length) 5049 if (!length)
@@ -4342,8 +5060,8 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
4342 if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { 5060 if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
4343 ioadl_flags = IPR_IOADL_FLAGS_WRITE; 5061 ioadl_flags = IPR_IOADL_FLAGS_WRITE;
4344 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; 5062 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
4345 ioarcb->write_data_transfer_length = cpu_to_be32(length); 5063 ioarcb->data_transfer_length = cpu_to_be32(length);
4346 ioarcb->write_ioadl_len = 5064 ioarcb->ioadl_len =
4347 cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); 5065 cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
4348 } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) { 5066 } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) {
4349 ioadl_flags = IPR_IOADL_FLAGS_READ; 5067 ioadl_flags = IPR_IOADL_FLAGS_READ;
@@ -4352,11 +5070,10 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
4352 cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); 5070 cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
4353 } 5071 }
4354 5072
4355 if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) { 5073 if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->u.add_data.u.ioadl)) {
4356 ioadl = ioarcb->add_data.u.ioadl; 5074 ioadl = ioarcb->u.add_data.u.ioadl;
4357 ioarcb->write_ioadl_addr = 5075 ioarcb->write_ioadl_addr = cpu_to_be32((ipr_cmd->dma_addr) +
4358 cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) + 5076 offsetof(struct ipr_ioarcb, u.add_data));
4359 offsetof(struct ipr_ioarcb, add_data));
4360 ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; 5077 ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
4361 } 5078 }
4362 5079
@@ -4446,18 +5163,24 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd)
4446{ 5163{
4447 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 5164 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
4448 struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; 5165 struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
4449 dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); 5166 dma_addr_t dma_addr = ipr_cmd->dma_addr;
4450 5167
4451 memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); 5168 memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
4452 ioarcb->write_data_transfer_length = 0; 5169 ioarcb->data_transfer_length = 0;
4453 ioarcb->read_data_transfer_length = 0; 5170 ioarcb->read_data_transfer_length = 0;
4454 ioarcb->write_ioadl_len = 0; 5171 ioarcb->ioadl_len = 0;
4455 ioarcb->read_ioadl_len = 0; 5172 ioarcb->read_ioadl_len = 0;
4456 ioasa->ioasc = 0; 5173 ioasa->ioasc = 0;
4457 ioasa->residual_data_len = 0; 5174 ioasa->residual_data_len = 0;
4458 ioarcb->write_ioadl_addr = 5175
4459 cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); 5176 if (ipr_cmd->ioa_cfg->sis64)
4460 ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; 5177 ioarcb->u.sis64_addr_data.data_ioadl_addr =
5178 cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
5179 else {
5180 ioarcb->write_ioadl_addr =
5181 cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
5182 ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
5183 }
4461} 5184}
4462 5185
4463/** 5186/**
@@ -4489,15 +5212,8 @@ static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd)
4489 cmd_pkt->flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; 5212 cmd_pkt->flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
4490 cmd_pkt->timeout = cpu_to_be16(IPR_REQUEST_SENSE_TIMEOUT / HZ); 5213 cmd_pkt->timeout = cpu_to_be16(IPR_REQUEST_SENSE_TIMEOUT / HZ);
4491 5214
4492 ipr_cmd->ioadl[0].flags_and_data_len = 5215 ipr_init_ioadl(ipr_cmd, ipr_cmd->sense_buffer_dma,
4493 cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | SCSI_SENSE_BUFFERSIZE); 5216 SCSI_SENSE_BUFFERSIZE, IPR_IOADL_FLAGS_READ_LAST);
4494 ipr_cmd->ioadl[0].address =
4495 cpu_to_be32(ipr_cmd->sense_buffer_dma);
4496
4497 ipr_cmd->ioarcb.read_ioadl_len =
4498 cpu_to_be32(sizeof(struct ipr_ioadl_desc));
4499 ipr_cmd->ioarcb.read_data_transfer_length =
4500 cpu_to_be32(SCSI_SENSE_BUFFERSIZE);
4501 5217
4502 ipr_do_req(ipr_cmd, ipr_erp_done, ipr_timeout, 5218 ipr_do_req(ipr_cmd, ipr_erp_done, ipr_timeout,
4503 IPR_REQUEST_SENSE_TIMEOUT * 2); 5219 IPR_REQUEST_SENSE_TIMEOUT * 2);
@@ -4893,9 +5609,9 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
4893 5609
4894 memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len); 5610 memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len);
4895 ipr_cmd->scsi_cmd = scsi_cmd; 5611 ipr_cmd->scsi_cmd = scsi_cmd;
4896 ioarcb->res_handle = res->cfgte.res_handle; 5612 ioarcb->res_handle = res->res_handle;
4897 ipr_cmd->done = ipr_scsi_done; 5613 ipr_cmd->done = ipr_scsi_done;
4898 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr)); 5614 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res));
4899 5615
4900 if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) { 5616 if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) {
4901 if (scsi_cmd->underflow == 0) 5617 if (scsi_cmd->underflow == 0)
@@ -4916,13 +5632,16 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
4916 (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) 5632 (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
4917 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; 5633 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
4918 5634
4919 if (likely(rc == 0)) 5635 if (likely(rc == 0)) {
4920 rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); 5636 if (ioa_cfg->sis64)
5637 rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd);
5638 else
5639 rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
5640 }
4921 5641
4922 if (likely(rc == 0)) { 5642 if (likely(rc == 0)) {
4923 mb(); 5643 mb();
4924 writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), 5644 ipr_send_command(ipr_cmd);
4925 ioa_cfg->regs.ioarrin_reg);
4926 } else { 5645 } else {
4927 list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q); 5646 list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
4928 return SCSI_MLQUEUE_HOST_BUSY; 5647 return SCSI_MLQUEUE_HOST_BUSY;
@@ -5035,20 +5754,9 @@ static void ipr_ata_phy_reset(struct ata_port *ap)
5035 goto out_unlock; 5754 goto out_unlock;
5036 } 5755 }
5037 5756
5038 switch(res->cfgte.proto) { 5757 ap->link.device[0].class = res->ata_class;
5039 case IPR_PROTO_SATA: 5758 if (ap->link.device[0].class == ATA_DEV_UNKNOWN)
5040 case IPR_PROTO_SAS_STP:
5041 ap->link.device[0].class = ATA_DEV_ATA;
5042 break;
5043 case IPR_PROTO_SATA_ATAPI:
5044 case IPR_PROTO_SAS_STP_ATAPI:
5045 ap->link.device[0].class = ATA_DEV_ATAPI;
5046 break;
5047 default:
5048 ap->link.device[0].class = ATA_DEV_UNKNOWN;
5049 ata_port_disable(ap); 5759 ata_port_disable(ap);
5050 break;
5051 };
5052 5760
5053out_unlock: 5761out_unlock:
5054 spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); 5762 spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
@@ -5134,8 +5842,7 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd)
5134 ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); 5842 ipr_dump_ioasa(ioa_cfg, ipr_cmd, res);
5135 5843
5136 if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) 5844 if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET)
5137 scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus, 5845 scsi_report_device_reset(ioa_cfg->host, res->bus, res->target);
5138 res->cfgte.res_addr.target);
5139 5846
5140 if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) 5847 if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)
5141 qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status); 5848 qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status);
@@ -5146,6 +5853,52 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd)
5146} 5853}
5147 5854
5148/** 5855/**
5856 * ipr_build_ata_ioadl64 - Build an ATA scatter/gather list
5857 * @ipr_cmd: ipr command struct
5858 * @qc: ATA queued command
5859 *
5860 **/
5861static void ipr_build_ata_ioadl64(struct ipr_cmnd *ipr_cmd,
5862 struct ata_queued_cmd *qc)
5863{
5864 u32 ioadl_flags = 0;
5865 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
5866 struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
5867 struct ipr_ioadl64_desc *last_ioadl64 = NULL;
5868 int len = qc->nbytes;
5869 struct scatterlist *sg;
5870 unsigned int si;
5871 dma_addr_t dma_addr = ipr_cmd->dma_addr;
5872
5873 if (len == 0)
5874 return;
5875
5876 if (qc->dma_dir == DMA_TO_DEVICE) {
5877 ioadl_flags = IPR_IOADL_FLAGS_WRITE;
5878 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
5879 } else if (qc->dma_dir == DMA_FROM_DEVICE)
5880 ioadl_flags = IPR_IOADL_FLAGS_READ;
5881
5882 ioarcb->data_transfer_length = cpu_to_be32(len);
5883 ioarcb->ioadl_len =
5884 cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg);
5885 ioarcb->u.sis64_addr_data.data_ioadl_addr =
5886 cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ata_ioadl));
5887
5888 for_each_sg(qc->sg, sg, qc->n_elem, si) {
5889 ioadl64->flags = cpu_to_be32(ioadl_flags);
5890 ioadl64->data_len = cpu_to_be32(sg_dma_len(sg));
5891 ioadl64->address = cpu_to_be64(sg_dma_address(sg));
5892
5893 last_ioadl64 = ioadl64;
5894 ioadl64++;
5895 }
5896
5897 if (likely(last_ioadl64))
5898 last_ioadl64->flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
5899}
5900
5901/**
5149 * ipr_build_ata_ioadl - Build an ATA scatter/gather list 5902 * ipr_build_ata_ioadl - Build an ATA scatter/gather list
5150 * @ipr_cmd: ipr command struct 5903 * @ipr_cmd: ipr command struct
5151 * @qc: ATA queued command 5904 * @qc: ATA queued command
@@ -5156,7 +5909,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
5156{ 5909{
5157 u32 ioadl_flags = 0; 5910 u32 ioadl_flags = 0;
5158 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 5911 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
5159 struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; 5912 struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
5160 struct ipr_ioadl_desc *last_ioadl = NULL; 5913 struct ipr_ioadl_desc *last_ioadl = NULL;
5161 int len = qc->nbytes; 5914 int len = qc->nbytes;
5162 struct scatterlist *sg; 5915 struct scatterlist *sg;
@@ -5168,8 +5921,8 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
5168 if (qc->dma_dir == DMA_TO_DEVICE) { 5921 if (qc->dma_dir == DMA_TO_DEVICE) {
5169 ioadl_flags = IPR_IOADL_FLAGS_WRITE; 5922 ioadl_flags = IPR_IOADL_FLAGS_WRITE;
5170 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; 5923 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
5171 ioarcb->write_data_transfer_length = cpu_to_be32(len); 5924 ioarcb->data_transfer_length = cpu_to_be32(len);
5172 ioarcb->write_ioadl_len = 5925 ioarcb->ioadl_len =
5173 cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); 5926 cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
5174 } else if (qc->dma_dir == DMA_FROM_DEVICE) { 5927 } else if (qc->dma_dir == DMA_FROM_DEVICE) {
5175 ioadl_flags = IPR_IOADL_FLAGS_READ; 5928 ioadl_flags = IPR_IOADL_FLAGS_READ;
@@ -5212,25 +5965,34 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
5212 5965
5213 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); 5966 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
5214 ioarcb = &ipr_cmd->ioarcb; 5967 ioarcb = &ipr_cmd->ioarcb;
5215 regs = &ioarcb->add_data.u.regs;
5216 5968
5217 memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data)); 5969 if (ioa_cfg->sis64) {
5218 ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs)); 5970 regs = &ipr_cmd->i.ata_ioadl.regs;
5971 ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb));
5972 } else
5973 regs = &ioarcb->u.add_data.u.regs;
5974
5975 memset(regs, 0, sizeof(*regs));
5976 ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(*regs));
5219 5977
5220 list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); 5978 list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
5221 ipr_cmd->qc = qc; 5979 ipr_cmd->qc = qc;
5222 ipr_cmd->done = ipr_sata_done; 5980 ipr_cmd->done = ipr_sata_done;
5223 ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; 5981 ipr_cmd->ioarcb.res_handle = res->res_handle;
5224 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU; 5982 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU;
5225 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC; 5983 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
5226 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; 5984 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
5227 ipr_cmd->dma_use_sg = qc->n_elem; 5985 ipr_cmd->dma_use_sg = qc->n_elem;
5228 5986
5229 ipr_build_ata_ioadl(ipr_cmd, qc); 5987 if (ioa_cfg->sis64)
5988 ipr_build_ata_ioadl64(ipr_cmd, qc);
5989 else
5990 ipr_build_ata_ioadl(ipr_cmd, qc);
5991
5230 regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; 5992 regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
5231 ipr_copy_sata_tf(regs, &qc->tf); 5993 ipr_copy_sata_tf(regs, &qc->tf);
5232 memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN); 5994 memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN);
5233 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr)); 5995 ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res));
5234 5996
5235 switch (qc->tf.protocol) { 5997 switch (qc->tf.protocol) {
5236 case ATA_PROT_NODATA: 5998 case ATA_PROT_NODATA:
@@ -5257,8 +6019,9 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
5257 } 6019 }
5258 6020
5259 mb(); 6021 mb();
5260 writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr), 6022
5261 ioa_cfg->regs.ioarrin_reg); 6023 ipr_send_command(ipr_cmd);
6024
5262 return 0; 6025 return 0;
5263} 6026}
5264 6027
@@ -5459,7 +6222,7 @@ static void ipr_set_sup_dev_dflt(struct ipr_supported_device *supported_dev,
5459 * ipr_set_supported_devs - Send Set Supported Devices for a device 6222 * ipr_set_supported_devs - Send Set Supported Devices for a device
5460 * @ipr_cmd: ipr command struct 6223 * @ipr_cmd: ipr command struct
5461 * 6224 *
5462 * This function send a Set Supported Devices to the adapter 6225 * This function sends a Set Supported Devices to the adapter
5463 * 6226 *
5464 * Return value: 6227 * Return value:
5465 * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN 6228 * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
@@ -5468,7 +6231,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd)
5468{ 6231{
5469 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 6232 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
5470 struct ipr_supported_device *supp_dev = &ioa_cfg->vpd_cbs->supp_dev; 6233 struct ipr_supported_device *supp_dev = &ioa_cfg->vpd_cbs->supp_dev;
5471 struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
5472 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 6234 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
5473 struct ipr_resource_entry *res = ipr_cmd->u.res; 6235 struct ipr_resource_entry *res = ipr_cmd->u.res;
5474 6236
@@ -5479,28 +6241,28 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd)
5479 continue; 6241 continue;
5480 6242
5481 ipr_cmd->u.res = res; 6243 ipr_cmd->u.res = res;
5482 ipr_set_sup_dev_dflt(supp_dev, &res->cfgte.std_inq_data.vpids); 6244 ipr_set_sup_dev_dflt(supp_dev, &res->std_inq_data.vpids);
5483 6245
5484 ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); 6246 ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
5485 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; 6247 ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
5486 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; 6248 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
5487 6249
5488 ioarcb->cmd_pkt.cdb[0] = IPR_SET_SUPPORTED_DEVICES; 6250 ioarcb->cmd_pkt.cdb[0] = IPR_SET_SUPPORTED_DEVICES;
6251 ioarcb->cmd_pkt.cdb[1] = IPR_SET_ALL_SUPPORTED_DEVICES;
5489 ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff; 6252 ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff;
5490 ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff; 6253 ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff;
5491 6254
5492 ioadl->flags_and_data_len = cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | 6255 ipr_init_ioadl(ipr_cmd,
5493 sizeof(struct ipr_supported_device)); 6256 ioa_cfg->vpd_cbs_dma +
5494 ioadl->address = cpu_to_be32(ioa_cfg->vpd_cbs_dma + 6257 offsetof(struct ipr_misc_cbs, supp_dev),
5495 offsetof(struct ipr_misc_cbs, supp_dev)); 6258 sizeof(struct ipr_supported_device),
5496 ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); 6259 IPR_IOADL_FLAGS_WRITE_LAST);
5497 ioarcb->write_data_transfer_length =
5498 cpu_to_be32(sizeof(struct ipr_supported_device));
5499 6260
5500 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, 6261 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
5501 IPR_SET_SUP_DEVICE_TIMEOUT); 6262 IPR_SET_SUP_DEVICE_TIMEOUT);
5502 6263
5503 ipr_cmd->job_step = ipr_set_supported_devs; 6264 if (!ioa_cfg->sis64)
6265 ipr_cmd->job_step = ipr_set_supported_devs;
5504 return IPR_RC_JOB_RETURN; 6266 return IPR_RC_JOB_RETURN;
5505 } 6267 }
5506 6268
@@ -5508,36 +6270,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd)
5508} 6270}
5509 6271
5510/** 6272/**
5511 * ipr_setup_write_cache - Disable write cache if needed
5512 * @ipr_cmd: ipr command struct
5513 *
5514 * This function sets up adapters write cache to desired setting
5515 *
5516 * Return value:
5517 * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
5518 **/
5519static int ipr_setup_write_cache(struct ipr_cmnd *ipr_cmd)
5520{
5521 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
5522
5523 ipr_cmd->job_step = ipr_set_supported_devs;
5524 ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
5525 struct ipr_resource_entry, queue);
5526
5527 if (ioa_cfg->cache_state != CACHE_DISABLED)
5528 return IPR_RC_JOB_CONTINUE;
5529
5530 ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
5531 ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
5532 ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN;
5533 ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL;
5534
5535 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
5536
5537 return IPR_RC_JOB_RETURN;
5538}
5539
5540/**
5541 * ipr_get_mode_page - Locate specified mode page 6273 * ipr_get_mode_page - Locate specified mode page
5542 * @mode_pages: mode page buffer 6274 * @mode_pages: mode page buffer
5543 * @page_code: page code to find 6275 * @page_code: page code to find
@@ -5695,10 +6427,9 @@ static void ipr_modify_ioafp_mode_page_28(struct ipr_ioa_cfg *ioa_cfg,
5695 * none 6427 * none
5696 **/ 6428 **/
5697static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd, 6429static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd,
5698 __be32 res_handle, u8 parm, u32 dma_addr, 6430 __be32 res_handle, u8 parm,
5699 u8 xfer_len) 6431 dma_addr_t dma_addr, u8 xfer_len)
5700{ 6432{
5701 struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
5702 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 6433 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
5703 6434
5704 ioarcb->res_handle = res_handle; 6435 ioarcb->res_handle = res_handle;
@@ -5708,11 +6439,7 @@ static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd,
5708 ioarcb->cmd_pkt.cdb[1] = parm; 6439 ioarcb->cmd_pkt.cdb[1] = parm;
5709 ioarcb->cmd_pkt.cdb[4] = xfer_len; 6440 ioarcb->cmd_pkt.cdb[4] = xfer_len;
5710 6441
5711 ioadl->flags_and_data_len = 6442 ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_WRITE_LAST);
5712 cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | xfer_len);
5713 ioadl->address = cpu_to_be32(dma_addr);
5714 ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
5715 ioarcb->write_data_transfer_length = cpu_to_be32(xfer_len);
5716} 6443}
5717 6444
5718/** 6445/**
@@ -5742,7 +6469,9 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
5742 ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), 6469 ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages),
5743 length); 6470 length);
5744 6471
5745 ipr_cmd->job_step = ipr_setup_write_cache; 6472 ipr_cmd->job_step = ipr_set_supported_devs;
6473 ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
6474 struct ipr_resource_entry, queue);
5746 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); 6475 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
5747 6476
5748 LEAVE; 6477 LEAVE;
@@ -5762,9 +6491,8 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
5762 **/ 6491 **/
5763static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, 6492static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd,
5764 __be32 res_handle, 6493 __be32 res_handle,
5765 u8 parm, u32 dma_addr, u8 xfer_len) 6494 u8 parm, dma_addr_t dma_addr, u8 xfer_len)
5766{ 6495{
5767 struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
5768 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 6496 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
5769 6497
5770 ioarcb->res_handle = res_handle; 6498 ioarcb->res_handle = res_handle;
@@ -5773,11 +6501,7 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd,
5773 ioarcb->cmd_pkt.cdb[4] = xfer_len; 6501 ioarcb->cmd_pkt.cdb[4] = xfer_len;
5774 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; 6502 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB;
5775 6503
5776 ioadl->flags_and_data_len = 6504 ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST);
5777 cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len);
5778 ioadl->address = cpu_to_be32(dma_addr);
5779 ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
5780 ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len);
5781} 6505}
5782 6506
5783/** 6507/**
@@ -5815,10 +6539,13 @@ static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd)
5815 **/ 6539 **/
5816static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) 6540static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd)
5817{ 6541{
6542 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
5818 u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); 6543 u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
5819 6544
5820 if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { 6545 if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) {
5821 ipr_cmd->job_step = ipr_setup_write_cache; 6546 ipr_cmd->job_step = ipr_set_supported_devs;
6547 ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
6548 struct ipr_resource_entry, queue);
5822 return IPR_RC_JOB_CONTINUE; 6549 return IPR_RC_JOB_CONTINUE;
5823 } 6550 }
5824 6551
@@ -5958,24 +6685,36 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd)
5958{ 6685{
5959 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 6686 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
5960 struct ipr_resource_entry *res, *temp; 6687 struct ipr_resource_entry *res, *temp;
5961 struct ipr_config_table_entry *cfgte; 6688 struct ipr_config_table_entry_wrapper cfgtew;
5962 int found, i; 6689 int entries, found, flag, i;
5963 LIST_HEAD(old_res); 6690 LIST_HEAD(old_res);
5964 6691
5965 ENTER; 6692 ENTER;
5966 if (ioa_cfg->cfg_table->hdr.flags & IPR_UCODE_DOWNLOAD_REQ) 6693 if (ioa_cfg->sis64)
6694 flag = ioa_cfg->u.cfg_table64->hdr64.flags;
6695 else
6696 flag = ioa_cfg->u.cfg_table->hdr.flags;
6697
6698 if (flag & IPR_UCODE_DOWNLOAD_REQ)
5967 dev_err(&ioa_cfg->pdev->dev, "Microcode download required\n"); 6699 dev_err(&ioa_cfg->pdev->dev, "Microcode download required\n");
5968 6700
5969 list_for_each_entry_safe(res, temp, &ioa_cfg->used_res_q, queue) 6701 list_for_each_entry_safe(res, temp, &ioa_cfg->used_res_q, queue)
5970 list_move_tail(&res->queue, &old_res); 6702 list_move_tail(&res->queue, &old_res);
5971 6703
5972 for (i = 0; i < ioa_cfg->cfg_table->hdr.num_entries; i++) { 6704 if (ioa_cfg->sis64)
5973 cfgte = &ioa_cfg->cfg_table->dev[i]; 6705 entries = ioa_cfg->u.cfg_table64->hdr64.num_entries;
6706 else
6707 entries = ioa_cfg->u.cfg_table->hdr.num_entries;
6708
6709 for (i = 0; i < entries; i++) {
6710 if (ioa_cfg->sis64)
6711 cfgtew.u.cfgte64 = &ioa_cfg->u.cfg_table64->dev[i];
6712 else
6713 cfgtew.u.cfgte = &ioa_cfg->u.cfg_table->dev[i];
5974 found = 0; 6714 found = 0;
5975 6715
5976 list_for_each_entry_safe(res, temp, &old_res, queue) { 6716 list_for_each_entry_safe(res, temp, &old_res, queue) {
5977 if (!memcmp(&res->cfgte.res_addr, 6717 if (ipr_is_same_device(res, &cfgtew)) {
5978 &cfgte->res_addr, sizeof(cfgte->res_addr))) {
5979 list_move_tail(&res->queue, &ioa_cfg->used_res_q); 6718 list_move_tail(&res->queue, &ioa_cfg->used_res_q);
5980 found = 1; 6719 found = 1;
5981 break; 6720 break;
@@ -5992,24 +6731,27 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd)
5992 res = list_entry(ioa_cfg->free_res_q.next, 6731 res = list_entry(ioa_cfg->free_res_q.next,
5993 struct ipr_resource_entry, queue); 6732 struct ipr_resource_entry, queue);
5994 list_move_tail(&res->queue, &ioa_cfg->used_res_q); 6733 list_move_tail(&res->queue, &ioa_cfg->used_res_q);
5995 ipr_init_res_entry(res); 6734 ipr_init_res_entry(res, &cfgtew);
5996 res->add_to_ml = 1; 6735 res->add_to_ml = 1;
5997 } 6736 }
5998 6737
5999 if (found) 6738 if (found)
6000 memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry)); 6739 ipr_update_res_entry(res, &cfgtew);
6001 } 6740 }
6002 6741
6003 list_for_each_entry_safe(res, temp, &old_res, queue) { 6742 list_for_each_entry_safe(res, temp, &old_res, queue) {
6004 if (res->sdev) { 6743 if (res->sdev) {
6005 res->del_from_ml = 1; 6744 res->del_from_ml = 1;
6006 res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; 6745 res->res_handle = IPR_INVALID_RES_HANDLE;
6007 list_move_tail(&res->queue, &ioa_cfg->used_res_q); 6746 list_move_tail(&res->queue, &ioa_cfg->used_res_q);
6008 } else {
6009 list_move_tail(&res->queue, &ioa_cfg->free_res_q);
6010 } 6747 }
6011 } 6748 }
6012 6749
6750 list_for_each_entry_safe(res, temp, &old_res, queue) {
6751 ipr_clear_res_target(res);
6752 list_move_tail(&res->queue, &ioa_cfg->free_res_q);
6753 }
6754
6013 if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) 6755 if (ioa_cfg->dual_raid && ipr_dual_ioa_raid)
6014 ipr_cmd->job_step = ipr_ioafp_mode_sense_page24; 6756 ipr_cmd->job_step = ipr_ioafp_mode_sense_page24;
6015 else 6757 else
@@ -6033,7 +6775,6 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
6033{ 6775{
6034 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 6776 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
6035 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 6777 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
6036 struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
6037 struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data; 6778 struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data;
6038 struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; 6779 struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap;
6039 6780
@@ -6047,16 +6788,11 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
6047 ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); 6788 ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
6048 6789
6049 ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG; 6790 ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG;
6050 ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_config_table) >> 8) & 0xff; 6791 ioarcb->cmd_pkt.cdb[7] = (ioa_cfg->cfg_table_size >> 8) & 0xff;
6051 ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_config_table) & 0xff; 6792 ioarcb->cmd_pkt.cdb[8] = ioa_cfg->cfg_table_size & 0xff;
6052 6793
6053 ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); 6794 ipr_init_ioadl(ipr_cmd, ioa_cfg->cfg_table_dma, ioa_cfg->cfg_table_size,
6054 ioarcb->read_data_transfer_length = 6795 IPR_IOADL_FLAGS_READ_LAST);
6055 cpu_to_be32(sizeof(struct ipr_config_table));
6056
6057 ioadl->address = cpu_to_be32(ioa_cfg->cfg_table_dma);
6058 ioadl->flags_and_data_len =
6059 cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(struct ipr_config_table));
6060 6796
6061 ipr_cmd->job_step = ipr_init_res_table; 6797 ipr_cmd->job_step = ipr_init_res_table;
6062 6798
@@ -6076,10 +6812,9 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
6076 * none 6812 * none
6077 **/ 6813 **/
6078static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, 6814static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page,
6079 u32 dma_addr, u8 xfer_len) 6815 dma_addr_t dma_addr, u8 xfer_len)
6080{ 6816{
6081 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 6817 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
6082 struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
6083 6818
6084 ENTER; 6819 ENTER;
6085 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; 6820 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB;
@@ -6090,12 +6825,7 @@ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page,
6090 ioarcb->cmd_pkt.cdb[2] = page; 6825 ioarcb->cmd_pkt.cdb[2] = page;
6091 ioarcb->cmd_pkt.cdb[4] = xfer_len; 6826 ioarcb->cmd_pkt.cdb[4] = xfer_len;
6092 6827
6093 ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); 6828 ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST);
6094 ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len);
6095
6096 ioadl->address = cpu_to_be32(dma_addr);
6097 ioadl->flags_and_data_len =
6098 cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len);
6099 6829
6100 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); 6830 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
6101 LEAVE; 6831 LEAVE;
@@ -6166,13 +6896,9 @@ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd)
6166static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) 6896static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd)
6167{ 6897{
6168 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 6898 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
6169 struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data;
6170 6899
6171 ENTER; 6900 ENTER;
6172 6901
6173 if (!ipr_inquiry_page_supported(page0, 1))
6174 ioa_cfg->cache_state = CACHE_NONE;
6175
6176 ipr_cmd->job_step = ipr_ioafp_cap_inquiry; 6902 ipr_cmd->job_step = ipr_ioafp_cap_inquiry;
6177 6903
6178 ipr_ioafp_inquiry(ipr_cmd, 1, 3, 6904 ipr_ioafp_inquiry(ipr_cmd, 1, 3,
@@ -6240,7 +6966,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd)
6240} 6966}
6241 6967
6242/** 6968/**
6243 * ipr_ioafp_indentify_hrrq - Send Identify Host RRQ. 6969 * ipr_ioafp_identify_hrrq - Send Identify Host RRQ.
6244 * @ipr_cmd: ipr command struct 6970 * @ipr_cmd: ipr command struct
6245 * 6971 *
6246 * This function send an Identify Host Request Response Queue 6972 * This function send an Identify Host Request Response Queue
@@ -6249,7 +6975,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd)
6249 * Return value: 6975 * Return value:
6250 * IPR_RC_JOB_RETURN 6976 * IPR_RC_JOB_RETURN
6251 **/ 6977 **/
6252static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd) 6978static int ipr_ioafp_identify_hrrq(struct ipr_cmnd *ipr_cmd)
6253{ 6979{
6254 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 6980 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
6255 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; 6981 struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
@@ -6261,19 +6987,32 @@ static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd)
6261 ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); 6987 ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
6262 6988
6263 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; 6989 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
6990 if (ioa_cfg->sis64)
6991 ioarcb->cmd_pkt.cdb[1] = 0x1;
6264 ioarcb->cmd_pkt.cdb[2] = 6992 ioarcb->cmd_pkt.cdb[2] =
6265 ((u32) ioa_cfg->host_rrq_dma >> 24) & 0xff; 6993 ((u64) ioa_cfg->host_rrq_dma >> 24) & 0xff;
6266 ioarcb->cmd_pkt.cdb[3] = 6994 ioarcb->cmd_pkt.cdb[3] =
6267 ((u32) ioa_cfg->host_rrq_dma >> 16) & 0xff; 6995 ((u64) ioa_cfg->host_rrq_dma >> 16) & 0xff;
6268 ioarcb->cmd_pkt.cdb[4] = 6996 ioarcb->cmd_pkt.cdb[4] =
6269 ((u32) ioa_cfg->host_rrq_dma >> 8) & 0xff; 6997 ((u64) ioa_cfg->host_rrq_dma >> 8) & 0xff;
6270 ioarcb->cmd_pkt.cdb[5] = 6998 ioarcb->cmd_pkt.cdb[5] =
6271 ((u32) ioa_cfg->host_rrq_dma) & 0xff; 6999 ((u64) ioa_cfg->host_rrq_dma) & 0xff;
6272 ioarcb->cmd_pkt.cdb[7] = 7000 ioarcb->cmd_pkt.cdb[7] =
6273 ((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff; 7001 ((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff;
6274 ioarcb->cmd_pkt.cdb[8] = 7002 ioarcb->cmd_pkt.cdb[8] =
6275 (sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff; 7003 (sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff;
6276 7004
7005 if (ioa_cfg->sis64) {
7006 ioarcb->cmd_pkt.cdb[10] =
7007 ((u64) ioa_cfg->host_rrq_dma >> 56) & 0xff;
7008 ioarcb->cmd_pkt.cdb[11] =
7009 ((u64) ioa_cfg->host_rrq_dma >> 48) & 0xff;
7010 ioarcb->cmd_pkt.cdb[12] =
7011 ((u64) ioa_cfg->host_rrq_dma >> 40) & 0xff;
7012 ioarcb->cmd_pkt.cdb[13] =
7013 ((u64) ioa_cfg->host_rrq_dma >> 32) & 0xff;
7014 }
7015
6277 ipr_cmd->job_step = ipr_ioafp_std_inquiry; 7016 ipr_cmd->job_step = ipr_ioafp_std_inquiry;
6278 7017
6279 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); 7018 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
@@ -6354,7 +7093,58 @@ static void ipr_init_ioa_mem(struct ipr_ioa_cfg *ioa_cfg)
6354 ioa_cfg->toggle_bit = 1; 7093 ioa_cfg->toggle_bit = 1;
6355 7094
6356 /* Zero out config table */ 7095 /* Zero out config table */
6357 memset(ioa_cfg->cfg_table, 0, sizeof(struct ipr_config_table)); 7096 memset(ioa_cfg->u.cfg_table, 0, ioa_cfg->cfg_table_size);
7097}
7098
7099/**
7100 * ipr_reset_next_stage - Process IPL stage change based on feedback register.
7101 * @ipr_cmd: ipr command struct
7102 *
7103 * Return value:
7104 * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
7105 **/
7106static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd)
7107{
7108 unsigned long stage, stage_time;
7109 u32 feedback;
7110 volatile u32 int_reg;
7111 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
7112 u64 maskval = 0;
7113
7114 feedback = readl(ioa_cfg->regs.init_feedback_reg);
7115 stage = feedback & IPR_IPL_INIT_STAGE_MASK;
7116 stage_time = feedback & IPR_IPL_INIT_STAGE_TIME_MASK;
7117
7118 ipr_dbg("IPL stage = 0x%lx, IPL stage time = %ld\n", stage, stage_time);
7119
7120 /* sanity check the stage_time value */
7121 if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME)
7122 stage_time = IPR_IPL_INIT_MIN_STAGE_TIME;
7123 else if (stage_time > IPR_LONG_OPERATIONAL_TIMEOUT)
7124 stage_time = IPR_LONG_OPERATIONAL_TIMEOUT;
7125
7126 if (stage == IPR_IPL_INIT_STAGE_UNKNOWN) {
7127 writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.set_interrupt_mask_reg);
7128 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
7129 stage_time = ioa_cfg->transop_timeout;
7130 ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
7131 } else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) {
7132 ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
7133 maskval = IPR_PCII_IPL_STAGE_CHANGE;
7134 maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER;
7135 writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg);
7136 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
7137 return IPR_RC_JOB_CONTINUE;
7138 }
7139
7140 ipr_cmd->timer.data = (unsigned long) ipr_cmd;
7141 ipr_cmd->timer.expires = jiffies + stage_time * HZ;
7142 ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout;
7143 ipr_cmd->done = ipr_reset_ioa_job;
7144 add_timer(&ipr_cmd->timer);
7145 list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
7146
7147 return IPR_RC_JOB_RETURN;
6358} 7148}
6359 7149
6360/** 7150/**
@@ -6373,7 +7163,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd)
6373 volatile u32 int_reg; 7163 volatile u32 int_reg;
6374 7164
6375 ENTER; 7165 ENTER;
6376 ipr_cmd->job_step = ipr_ioafp_indentify_hrrq; 7166 ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
6377 ipr_init_ioa_mem(ioa_cfg); 7167 ipr_init_ioa_mem(ioa_cfg);
6378 7168
6379 ioa_cfg->allow_interrupts = 1; 7169 ioa_cfg->allow_interrupts = 1;
@@ -6381,19 +7171,27 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd)
6381 7171
6382 if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { 7172 if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
6383 writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED), 7173 writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED),
6384 ioa_cfg->regs.clr_interrupt_mask_reg); 7174 ioa_cfg->regs.clr_interrupt_mask_reg32);
6385 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); 7175 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
6386 return IPR_RC_JOB_CONTINUE; 7176 return IPR_RC_JOB_CONTINUE;
6387 } 7177 }
6388 7178
6389 /* Enable destructive diagnostics on IOA */ 7179 /* Enable destructive diagnostics on IOA */
6390 writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg); 7180 writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg32);
7181
7182 writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32);
7183 if (ioa_cfg->sis64)
7184 writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_mask_reg);
6391 7185
6392 writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg);
6393 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); 7186 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
6394 7187
6395 dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n"); 7188 dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n");
6396 7189
7190 if (ioa_cfg->sis64) {
7191 ipr_cmd->job_step = ipr_reset_next_stage;
7192 return IPR_RC_JOB_CONTINUE;
7193 }
7194
6397 ipr_cmd->timer.data = (unsigned long) ipr_cmd; 7195 ipr_cmd->timer.data = (unsigned long) ipr_cmd;
6398 ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ); 7196 ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ);
6399 ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; 7197 ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout;
@@ -6463,7 +7261,7 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
6463 7261
6464 mailbox = readl(ioa_cfg->ioa_mailbox); 7262 mailbox = readl(ioa_cfg->ioa_mailbox);
6465 7263
6466 if (!ipr_sdt_is_fmt2(mailbox)) { 7264 if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(mailbox)) {
6467 ipr_unit_check_no_data(ioa_cfg); 7265 ipr_unit_check_no_data(ioa_cfg);
6468 return; 7266 return;
6469 } 7267 }
@@ -6472,15 +7270,20 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
6472 rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt, 7270 rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt,
6473 (sizeof(struct ipr_uc_sdt)) / sizeof(__be32)); 7271 (sizeof(struct ipr_uc_sdt)) / sizeof(__be32));
6474 7272
6475 if (rc || (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE) || 7273 if (rc || !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY) ||
6476 !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY)) { 7274 ((be32_to_cpu(sdt.hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
7275 (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) {
6477 ipr_unit_check_no_data(ioa_cfg); 7276 ipr_unit_check_no_data(ioa_cfg);
6478 return; 7277 return;
6479 } 7278 }
6480 7279
6481 /* Find length of the first sdt entry (UC buffer) */ 7280 /* Find length of the first sdt entry (UC buffer) */
6482 length = (be32_to_cpu(sdt.entry[0].end_offset) - 7281 if (be32_to_cpu(sdt.hdr.state) == IPR_FMT3_SDT_READY_TO_USE)
6483 be32_to_cpu(sdt.entry[0].bar_str_offset)) & IPR_FMT2_MBX_ADDR_MASK; 7282 length = be32_to_cpu(sdt.entry[0].end_token);
7283 else
7284 length = (be32_to_cpu(sdt.entry[0].end_token) -
7285 be32_to_cpu(sdt.entry[0].start_token)) &
7286 IPR_FMT2_MBX_ADDR_MASK;
6484 7287
6485 hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next, 7288 hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next,
6486 struct ipr_hostrcb, queue); 7289 struct ipr_hostrcb, queue);
@@ -6488,13 +7291,13 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
6488 memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam)); 7291 memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam));
6489 7292
6490 rc = ipr_get_ldump_data_section(ioa_cfg, 7293 rc = ipr_get_ldump_data_section(ioa_cfg,
6491 be32_to_cpu(sdt.entry[0].bar_str_offset), 7294 be32_to_cpu(sdt.entry[0].start_token),
6492 (__be32 *)&hostrcb->hcam, 7295 (__be32 *)&hostrcb->hcam,
6493 min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32)); 7296 min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32));
6494 7297
6495 if (!rc) { 7298 if (!rc) {
6496 ipr_handle_log_data(ioa_cfg, hostrcb); 7299 ipr_handle_log_data(ioa_cfg, hostrcb);
6497 ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); 7300 ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
6498 if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED && 7301 if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED &&
6499 ioa_cfg->sdt_state == GET_DUMP) 7302 ioa_cfg->sdt_state == GET_DUMP)
6500 ioa_cfg->sdt_state = WAIT_FOR_DUMP; 7303 ioa_cfg->sdt_state = WAIT_FOR_DUMP;
@@ -6722,7 +7525,7 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd)
6722 7525
6723 if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) { 7526 if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) {
6724 ipr_mask_and_clear_interrupts(ioa_cfg, ~0); 7527 ipr_mask_and_clear_interrupts(ioa_cfg, ~0);
6725 writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg); 7528 writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32);
6726 ipr_cmd->job_step = ipr_reset_wait_to_start_bist; 7529 ipr_cmd->job_step = ipr_reset_wait_to_start_bist;
6727 } else { 7530 } else {
6728 ipr_cmd->job_step = ioa_cfg->reset; 7531 ipr_cmd->job_step = ioa_cfg->reset;
@@ -6785,7 +7588,10 @@ static int ipr_reset_ucode_download(struct ipr_cmnd *ipr_cmd)
6785 ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8; 7588 ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8;
6786 ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff; 7589 ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff;
6787 7590
6788 ipr_build_ucode_ioadl(ipr_cmd, sglist); 7591 if (ioa_cfg->sis64)
7592 ipr_build_ucode_ioadl64(ipr_cmd, sglist);
7593 else
7594 ipr_build_ucode_ioadl(ipr_cmd, sglist);
6789 ipr_cmd->job_step = ipr_reset_ucode_download_done; 7595 ipr_cmd->job_step = ipr_reset_ucode_download_done;
6790 7596
6791 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, 7597 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
@@ -7154,8 +7960,8 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg)
7154 ipr_free_cmd_blks(ioa_cfg); 7960 ipr_free_cmd_blks(ioa_cfg);
7155 pci_free_consistent(ioa_cfg->pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, 7961 pci_free_consistent(ioa_cfg->pdev, sizeof(u32) * IPR_NUM_CMD_BLKS,
7156 ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); 7962 ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma);
7157 pci_free_consistent(ioa_cfg->pdev, sizeof(struct ipr_config_table), 7963 pci_free_consistent(ioa_cfg->pdev, ioa_cfg->cfg_table_size,
7158 ioa_cfg->cfg_table, 7964 ioa_cfg->u.cfg_table,
7159 ioa_cfg->cfg_table_dma); 7965 ioa_cfg->cfg_table_dma);
7160 7966
7161 for (i = 0; i < IPR_NUM_HCAMS; i++) { 7967 for (i = 0; i < IPR_NUM_HCAMS; i++) {
@@ -7209,7 +8015,7 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
7209 int i; 8015 int i;
7210 8016
7211 ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev, 8017 ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev,
7212 sizeof(struct ipr_cmnd), 8, 0); 8018 sizeof(struct ipr_cmnd), 16, 0);
7213 8019
7214 if (!ioa_cfg->ipr_cmd_pool) 8020 if (!ioa_cfg->ipr_cmd_pool)
7215 return -ENOMEM; 8021 return -ENOMEM;
@@ -7227,13 +8033,25 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
7227 ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr; 8033 ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr;
7228 8034
7229 ioarcb = &ipr_cmd->ioarcb; 8035 ioarcb = &ipr_cmd->ioarcb;
7230 ioarcb->ioarcb_host_pci_addr = cpu_to_be32(dma_addr); 8036 ipr_cmd->dma_addr = dma_addr;
8037 if (ioa_cfg->sis64)
8038 ioarcb->a.ioarcb_host_pci_addr64 = cpu_to_be64(dma_addr);
8039 else
8040 ioarcb->a.ioarcb_host_pci_addr = cpu_to_be32(dma_addr);
8041
7231 ioarcb->host_response_handle = cpu_to_be32(i << 2); 8042 ioarcb->host_response_handle = cpu_to_be32(i << 2);
7232 ioarcb->write_ioadl_addr = 8043 if (ioa_cfg->sis64) {
7233 cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); 8044 ioarcb->u.sis64_addr_data.data_ioadl_addr =
7234 ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; 8045 cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
7235 ioarcb->ioasa_host_pci_addr = 8046 ioarcb->u.sis64_addr_data.ioasa_host_pci_addr =
7236 cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa)); 8047 cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, ioasa));
8048 } else {
8049 ioarcb->write_ioadl_addr =
8050 cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
8051 ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
8052 ioarcb->ioasa_host_pci_addr =
8053 cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa));
8054 }
7237 ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa)); 8055 ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa));
7238 ipr_cmd->cmd_index = i; 8056 ipr_cmd->cmd_index = i;
7239 ipr_cmd->ioa_cfg = ioa_cfg; 8057 ipr_cmd->ioa_cfg = ioa_cfg;
@@ -7260,13 +8078,24 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
7260 8078
7261 ENTER; 8079 ENTER;
7262 ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) * 8080 ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) *
7263 IPR_MAX_PHYSICAL_DEVS, GFP_KERNEL); 8081 ioa_cfg->max_devs_supported, GFP_KERNEL);
7264 8082
7265 if (!ioa_cfg->res_entries) 8083 if (!ioa_cfg->res_entries)
7266 goto out; 8084 goto out;
7267 8085
7268 for (i = 0; i < IPR_MAX_PHYSICAL_DEVS; i++) 8086 if (ioa_cfg->sis64) {
8087 ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) *
8088 BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
8089 ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) *
8090 BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
8091 ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) *
8092 BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
8093 }
8094
8095 for (i = 0; i < ioa_cfg->max_devs_supported; i++) {
7269 list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q); 8096 list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q);
8097 ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg;
8098 }
7270 8099
7271 ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev, 8100 ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev,
7272 sizeof(struct ipr_misc_cbs), 8101 sizeof(struct ipr_misc_cbs),
@@ -7285,11 +8114,11 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
7285 if (!ioa_cfg->host_rrq) 8114 if (!ioa_cfg->host_rrq)
7286 goto out_ipr_free_cmd_blocks; 8115 goto out_ipr_free_cmd_blocks;
7287 8116
7288 ioa_cfg->cfg_table = pci_alloc_consistent(ioa_cfg->pdev, 8117 ioa_cfg->u.cfg_table = pci_alloc_consistent(ioa_cfg->pdev,
7289 sizeof(struct ipr_config_table), 8118 ioa_cfg->cfg_table_size,
7290 &ioa_cfg->cfg_table_dma); 8119 &ioa_cfg->cfg_table_dma);
7291 8120
7292 if (!ioa_cfg->cfg_table) 8121 if (!ioa_cfg->u.cfg_table)
7293 goto out_free_host_rrq; 8122 goto out_free_host_rrq;
7294 8123
7295 for (i = 0; i < IPR_NUM_HCAMS; i++) { 8124 for (i = 0; i < IPR_NUM_HCAMS; i++) {
@@ -7323,8 +8152,9 @@ out_free_hostrcb_dma:
7323 ioa_cfg->hostrcb[i], 8152 ioa_cfg->hostrcb[i],
7324 ioa_cfg->hostrcb_dma[i]); 8153 ioa_cfg->hostrcb_dma[i]);
7325 } 8154 }
7326 pci_free_consistent(pdev, sizeof(struct ipr_config_table), 8155 pci_free_consistent(pdev, ioa_cfg->cfg_table_size,
7327 ioa_cfg->cfg_table, ioa_cfg->cfg_table_dma); 8156 ioa_cfg->u.cfg_table,
8157 ioa_cfg->cfg_table_dma);
7328out_free_host_rrq: 8158out_free_host_rrq:
7329 pci_free_consistent(pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, 8159 pci_free_consistent(pdev, sizeof(u32) * IPR_NUM_CMD_BLKS,
7330 ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); 8160 ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma);
@@ -7399,15 +8229,21 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
7399 init_waitqueue_head(&ioa_cfg->reset_wait_q); 8229 init_waitqueue_head(&ioa_cfg->reset_wait_q);
7400 init_waitqueue_head(&ioa_cfg->msi_wait_q); 8230 init_waitqueue_head(&ioa_cfg->msi_wait_q);
7401 ioa_cfg->sdt_state = INACTIVE; 8231 ioa_cfg->sdt_state = INACTIVE;
7402 if (ipr_enable_cache)
7403 ioa_cfg->cache_state = CACHE_ENABLED;
7404 else
7405 ioa_cfg->cache_state = CACHE_DISABLED;
7406 8232
7407 ipr_initialize_bus_attr(ioa_cfg); 8233 ipr_initialize_bus_attr(ioa_cfg);
8234 ioa_cfg->max_devs_supported = ipr_max_devs;
7408 8235
7409 host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; 8236 if (ioa_cfg->sis64) {
7410 host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; 8237 host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS;
8238 host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET;
8239 if (ipr_max_devs > IPR_MAX_SIS64_DEVS)
8240 ioa_cfg->max_devs_supported = IPR_MAX_SIS64_DEVS;
8241 } else {
8242 host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS;
8243 host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET;
8244 if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS)
8245 ioa_cfg->max_devs_supported = IPR_MAX_PHYSICAL_DEVS;
8246 }
7411 host->max_channel = IPR_MAX_BUS_TO_SCAN; 8247 host->max_channel = IPR_MAX_BUS_TO_SCAN;
7412 host->unique_id = host->host_no; 8248 host->unique_id = host->host_no;
7413 host->max_cmd_len = IPR_MAX_CDB_LEN; 8249 host->max_cmd_len = IPR_MAX_CDB_LEN;
@@ -7419,13 +8255,26 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
7419 8255
7420 t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg; 8256 t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg;
7421 t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg; 8257 t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg;
8258 t->clr_interrupt_mask_reg32 = base + p->clr_interrupt_mask_reg32;
7422 t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg; 8259 t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg;
8260 t->sense_interrupt_mask_reg32 = base + p->sense_interrupt_mask_reg32;
7423 t->clr_interrupt_reg = base + p->clr_interrupt_reg; 8261 t->clr_interrupt_reg = base + p->clr_interrupt_reg;
8262 t->clr_interrupt_reg32 = base + p->clr_interrupt_reg32;
7424 t->sense_interrupt_reg = base + p->sense_interrupt_reg; 8263 t->sense_interrupt_reg = base + p->sense_interrupt_reg;
8264 t->sense_interrupt_reg32 = base + p->sense_interrupt_reg32;
7425 t->ioarrin_reg = base + p->ioarrin_reg; 8265 t->ioarrin_reg = base + p->ioarrin_reg;
7426 t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg; 8266 t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg;
8267 t->sense_uproc_interrupt_reg32 = base + p->sense_uproc_interrupt_reg32;
7427 t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg; 8268 t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg;
8269 t->set_uproc_interrupt_reg32 = base + p->set_uproc_interrupt_reg32;
7428 t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg; 8270 t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg;
8271 t->clr_uproc_interrupt_reg32 = base + p->clr_uproc_interrupt_reg32;
8272
8273 if (ioa_cfg->sis64) {
8274 t->init_feedback_reg = base + p->init_feedback_reg;
8275 t->dump_addr_reg = base + p->dump_addr_reg;
8276 t->dump_data_reg = base + p->dump_data_reg;
8277 }
7429} 8278}
7430 8279
7431/** 8280/**
@@ -7497,7 +8346,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg,
7497 init_waitqueue_head(&ioa_cfg->msi_wait_q); 8346 init_waitqueue_head(&ioa_cfg->msi_wait_q);
7498 ioa_cfg->msi_received = 0; 8347 ioa_cfg->msi_received = 0;
7499 ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); 8348 ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
7500 writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg); 8349 writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg32);
7501 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); 8350 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
7502 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 8351 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
7503 8352
@@ -7508,7 +8357,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg,
7508 } else if (ipr_debug) 8357 } else if (ipr_debug)
7509 dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq); 8358 dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq);
7510 8359
7511 writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg); 8360 writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32);
7512 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); 8361 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
7513 wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ); 8362 wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ);
7514 ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); 8363 ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
@@ -7578,6 +8427,8 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
7578 goto out_scsi_host_put; 8427 goto out_scsi_host_put;
7579 } 8428 }
7580 8429
8430 /* set SIS 32 or SIS 64 */
8431 ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0;
7581 ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg; 8432 ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg;
7582 8433
7583 if (ipr_transop_timeout) 8434 if (ipr_transop_timeout)
@@ -7615,7 +8466,16 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
7615 8466
7616 pci_set_master(pdev); 8467 pci_set_master(pdev);
7617 8468
7618 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 8469 if (ioa_cfg->sis64) {
8470 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
8471 if (rc < 0) {
8472 dev_dbg(&pdev->dev, "Failed to set 64 bit PCI DMA mask\n");
8473 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
8474 }
8475
8476 } else
8477 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
8478
7619 if (rc < 0) { 8479 if (rc < 0) {
7620 dev_err(&pdev->dev, "Failed to set PCI DMA mask\n"); 8480 dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
7621 goto cleanup_nomem; 8481 goto cleanup_nomem;
@@ -7657,6 +8517,15 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
7657 if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg))) 8517 if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg)))
7658 goto cleanup_nomem; 8518 goto cleanup_nomem;
7659 8519
8520 if (ioa_cfg->sis64)
8521 ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr64)
8522 + ((sizeof(struct ipr_config_table_entry64)
8523 * ioa_cfg->max_devs_supported)));
8524 else
8525 ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr)
8526 + ((sizeof(struct ipr_config_table_entry)
8527 * ioa_cfg->max_devs_supported)));
8528
7660 rc = ipr_alloc_mem(ioa_cfg); 8529 rc = ipr_alloc_mem(ioa_cfg);
7661 if (rc < 0) { 8530 if (rc < 0) {
7662 dev_err(&pdev->dev, 8531 dev_err(&pdev->dev,
@@ -7668,9 +8537,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
7668 * If HRRQ updated interrupt is not masked, or reset alert is set, 8537 * If HRRQ updated interrupt is not masked, or reset alert is set,
7669 * the card is in an unknown state and needs a hard reset 8538 * the card is in an unknown state and needs a hard reset
7670 */ 8539 */
7671 mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg); 8540 mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
7672 interrupts = readl(ioa_cfg->regs.sense_interrupt_reg); 8541 interrupts = readl(ioa_cfg->regs.sense_interrupt_reg32);
7673 uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg); 8542 uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg32);
7674 if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) 8543 if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT))
7675 ioa_cfg->needs_hard_reset = 1; 8544 ioa_cfg->needs_hard_reset = 1;
7676 if (interrupts & IPR_PCII_ERROR_INTERRUPTS) 8545 if (interrupts & IPR_PCII_ERROR_INTERRUPTS)
@@ -7958,9 +8827,6 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
7958 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0, 8827 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0,
7959 IPR_USE_LONG_TRANSOP_TIMEOUT }, 8828 IPR_USE_LONG_TRANSOP_TIMEOUT },
7960 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, 8829 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
7961 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0,
7962 IPR_USE_LONG_TRANSOP_TIMEOUT },
7963 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
7964 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 }, 8830 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 },
7965 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, 8831 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
7966 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, 8832 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0,
@@ -7975,9 +8841,22 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
7975 { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, 8841 { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
7976 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, 8842 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0,
7977 IPR_USE_LONG_TRANSOP_TIMEOUT }, 8843 IPR_USE_LONG_TRANSOP_TIMEOUT },
7978 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SCAMP_E, 8844 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
7979 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, 8845 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B5, 0, 0, 0 },
7980 IPR_USE_LONG_TRANSOP_TIMEOUT }, 8846 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
8847 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, 0 },
8848 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
8849 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 },
8850 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
8851 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B4, 0, 0, 0 },
8852 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
8853 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B1, 0, 0, 0 },
8854 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
8855 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C6, 0, 0, 0 },
8856 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
8857 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, 0 },
8858 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
8859 PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57CE, 0, 0, 0 },
7981 { } 8860 { }
7982}; 8861};
7983MODULE_DEVICE_TABLE(pci, ipr_pci_table); 8862MODULE_DEVICE_TABLE(pci, ipr_pci_table);
@@ -7997,6 +8876,61 @@ static struct pci_driver ipr_driver = {
7997}; 8876};
7998 8877
7999/** 8878/**
8879 * ipr_halt_done - Shutdown prepare completion
8880 *
8881 * Return value:
8882 * none
8883 **/
8884static void ipr_halt_done(struct ipr_cmnd *ipr_cmd)
8885{
8886 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
8887
8888 list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
8889}
8890
8891/**
8892 * ipr_halt - Issue shutdown prepare to all adapters
8893 *
8894 * Return value:
8895 * NOTIFY_OK on success / NOTIFY_DONE on failure
8896 **/
8897static int ipr_halt(struct notifier_block *nb, ulong event, void *buf)
8898{
8899 struct ipr_cmnd *ipr_cmd;
8900 struct ipr_ioa_cfg *ioa_cfg;
8901 unsigned long flags = 0;
8902
8903 if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
8904 return NOTIFY_DONE;
8905
8906 spin_lock(&ipr_driver_lock);
8907
8908 list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) {
8909 spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
8910 if (!ioa_cfg->allow_cmds) {
8911 spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
8912 continue;
8913 }
8914
8915 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
8916 ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
8917 ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
8918 ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN;
8919 ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL;
8920
8921 ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
8922 spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
8923 }
8924 spin_unlock(&ipr_driver_lock);
8925
8926 return NOTIFY_OK;
8927}
8928
8929static struct notifier_block ipr_notifier = {
8930 ipr_halt, NULL, 0
8931};
8932
8933/**
8000 * ipr_init - Module entry point 8934 * ipr_init - Module entry point
8001 * 8935 *
8002 * Return value: 8936 * Return value:
@@ -8007,6 +8941,7 @@ static int __init ipr_init(void)
8007 ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n", 8941 ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n",
8008 IPR_DRIVER_VERSION, IPR_DRIVER_DATE); 8942 IPR_DRIVER_VERSION, IPR_DRIVER_DATE);
8009 8943
8944 register_reboot_notifier(&ipr_notifier);
8010 return pci_register_driver(&ipr_driver); 8945 return pci_register_driver(&ipr_driver);
8011} 8946}
8012 8947
@@ -8020,6 +8955,7 @@ static int __init ipr_init(void)
8020 **/ 8955 **/
8021static void __exit ipr_exit(void) 8956static void __exit ipr_exit(void)
8022{ 8957{
8958 unregister_reboot_notifier(&ipr_notifier);
8023 pci_unregister_driver(&ipr_driver); 8959 pci_unregister_driver(&ipr_driver);
8024} 8960}
8025 8961
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 19bbcf39f0c9..4c267b5e0b96 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -37,8 +37,8 @@
37/* 37/*
38 * Literals 38 * Literals
39 */ 39 */
40#define IPR_DRIVER_VERSION "2.4.3" 40#define IPR_DRIVER_VERSION "2.5.0"
41#define IPR_DRIVER_DATE "(June 10, 2009)" 41#define IPR_DRIVER_DATE "(February 11, 2010)"
42 42
43/* 43/*
44 * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding 44 * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -55,7 +55,9 @@
55#define IPR_NUM_BASE_CMD_BLKS 100 55#define IPR_NUM_BASE_CMD_BLKS 100
56 56
57#define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339 57#define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339
58#define PCI_DEVICE_ID_IBM_SCAMP_E 0x034A 58
59#define PCI_DEVICE_ID_IBM_CROC_FPGA_E2 0x033D
60#define PCI_DEVICE_ID_IBM_CROC_ASIC_E2 0x034A
59 61
60#define IPR_SUBS_DEV_ID_2780 0x0264 62#define IPR_SUBS_DEV_ID_2780 0x0264
61#define IPR_SUBS_DEV_ID_5702 0x0266 63#define IPR_SUBS_DEV_ID_5702 0x0266
@@ -70,15 +72,24 @@
70#define IPR_SUBS_DEV_ID_572A 0x02C1 72#define IPR_SUBS_DEV_ID_572A 0x02C1
71#define IPR_SUBS_DEV_ID_572B 0x02C2 73#define IPR_SUBS_DEV_ID_572B 0x02C2
72#define IPR_SUBS_DEV_ID_572F 0x02C3 74#define IPR_SUBS_DEV_ID_572F 0x02C3
73#define IPR_SUBS_DEV_ID_574D 0x030B
74#define IPR_SUBS_DEV_ID_574E 0x030A 75#define IPR_SUBS_DEV_ID_574E 0x030A
75#define IPR_SUBS_DEV_ID_575B 0x030D 76#define IPR_SUBS_DEV_ID_575B 0x030D
76#define IPR_SUBS_DEV_ID_575C 0x0338 77#define IPR_SUBS_DEV_ID_575C 0x0338
77#define IPR_SUBS_DEV_ID_575D 0x033E
78#define IPR_SUBS_DEV_ID_57B3 0x033A 78#define IPR_SUBS_DEV_ID_57B3 0x033A
79#define IPR_SUBS_DEV_ID_57B7 0x0360 79#define IPR_SUBS_DEV_ID_57B7 0x0360
80#define IPR_SUBS_DEV_ID_57B8 0x02C2 80#define IPR_SUBS_DEV_ID_57B8 0x02C2
81 81
82#define IPR_SUBS_DEV_ID_57B4 0x033B
83#define IPR_SUBS_DEV_ID_57B2 0x035F
84#define IPR_SUBS_DEV_ID_57C6 0x0357
85
86#define IPR_SUBS_DEV_ID_57B5 0x033C
87#define IPR_SUBS_DEV_ID_57CE 0x035E
88#define IPR_SUBS_DEV_ID_57B1 0x0355
89
90#define IPR_SUBS_DEV_ID_574D 0x0356
91#define IPR_SUBS_DEV_ID_575D 0x035D
92
82#define IPR_NAME "ipr" 93#define IPR_NAME "ipr"
83 94
84/* 95/*
@@ -118,6 +129,10 @@
118#define IPR_NUM_LOG_HCAMS 2 129#define IPR_NUM_LOG_HCAMS 2
119#define IPR_NUM_CFG_CHG_HCAMS 2 130#define IPR_NUM_CFG_CHG_HCAMS 2
120#define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS) 131#define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS)
132
133#define IPR_MAX_SIS64_TARGETS_PER_BUS 1024
134#define IPR_MAX_SIS64_LUNS_PER_TARGET 0xffffffff
135
121#define IPR_MAX_NUM_TARGETS_PER_BUS 256 136#define IPR_MAX_NUM_TARGETS_PER_BUS 256
122#define IPR_MAX_NUM_LUNS_PER_TARGET 256 137#define IPR_MAX_NUM_LUNS_PER_TARGET 256
123#define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8 138#define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8
@@ -132,13 +147,15 @@
132 147
133/* We need resources for HCAMS, IOA reset, IOA bringdown, and ERP */ 148/* We need resources for HCAMS, IOA reset, IOA bringdown, and ERP */
134#define IPR_NUM_INTERNAL_CMD_BLKS (IPR_NUM_HCAMS + \ 149#define IPR_NUM_INTERNAL_CMD_BLKS (IPR_NUM_HCAMS + \
135 ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 3) 150 ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 4)
136 151
137#define IPR_MAX_COMMANDS IPR_NUM_BASE_CMD_BLKS 152#define IPR_MAX_COMMANDS IPR_NUM_BASE_CMD_BLKS
138#define IPR_NUM_CMD_BLKS (IPR_NUM_BASE_CMD_BLKS + \ 153#define IPR_NUM_CMD_BLKS (IPR_NUM_BASE_CMD_BLKS + \
139 IPR_NUM_INTERNAL_CMD_BLKS) 154 IPR_NUM_INTERNAL_CMD_BLKS)
140 155
141#define IPR_MAX_PHYSICAL_DEVS 192 156#define IPR_MAX_PHYSICAL_DEVS 192
157#define IPR_DEFAULT_SIS64_DEVS 1024
158#define IPR_MAX_SIS64_DEVS 4096
142 159
143#define IPR_MAX_SGLIST 64 160#define IPR_MAX_SGLIST 64
144#define IPR_IOA_MAX_SECTORS 32767 161#define IPR_IOA_MAX_SECTORS 32767
@@ -173,6 +190,7 @@
173#define IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE 0x01 190#define IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE 0x01
174#define IPR_HCAM_CDB_OP_CODE_LOG_DATA 0x02 191#define IPR_HCAM_CDB_OP_CODE_LOG_DATA 0x02
175#define IPR_SET_SUPPORTED_DEVICES 0xFB 192#define IPR_SET_SUPPORTED_DEVICES 0xFB
193#define IPR_SET_ALL_SUPPORTED_DEVICES 0x80
176#define IPR_IOA_SHUTDOWN 0xF7 194#define IPR_IOA_SHUTDOWN 0xF7
177#define IPR_WR_BUF_DOWNLOAD_AND_SAVE 0x05 195#define IPR_WR_BUF_DOWNLOAD_AND_SAVE 0x05
178 196
@@ -221,9 +239,17 @@
221#define IPR_SDT_FMT2_BAR5_SEL 0x5 239#define IPR_SDT_FMT2_BAR5_SEL 0x5
222#define IPR_SDT_FMT2_EXP_ROM_SEL 0x8 240#define IPR_SDT_FMT2_EXP_ROM_SEL 0x8
223#define IPR_FMT2_SDT_READY_TO_USE 0xC4D4E3F2 241#define IPR_FMT2_SDT_READY_TO_USE 0xC4D4E3F2
242#define IPR_FMT3_SDT_READY_TO_USE 0xC4D4E3F3
224#define IPR_DOORBELL 0x82800000 243#define IPR_DOORBELL 0x82800000
225#define IPR_RUNTIME_RESET 0x40000000 244#define IPR_RUNTIME_RESET 0x40000000
226 245
246#define IPR_IPL_INIT_MIN_STAGE_TIME 5
247#define IPR_IPL_INIT_STAGE_UNKNOWN 0x0
248#define IPR_IPL_INIT_STAGE_TRANSOP 0xB0000000
249#define IPR_IPL_INIT_STAGE_MASK 0xff000000
250#define IPR_IPL_INIT_STAGE_TIME_MASK 0x0000ffff
251#define IPR_PCII_IPL_STAGE_CHANGE (0x80000000 >> 0)
252
227#define IPR_PCII_IOA_TRANS_TO_OPER (0x80000000 >> 0) 253#define IPR_PCII_IOA_TRANS_TO_OPER (0x80000000 >> 0)
228#define IPR_PCII_IOARCB_XFER_FAILED (0x80000000 >> 3) 254#define IPR_PCII_IOARCB_XFER_FAILED (0x80000000 >> 3)
229#define IPR_PCII_IOA_UNIT_CHECKED (0x80000000 >> 4) 255#define IPR_PCII_IOA_UNIT_CHECKED (0x80000000 >> 4)
@@ -318,27 +344,27 @@ struct ipr_std_inq_data {
318 u8 serial_num[IPR_SERIAL_NUM_LEN]; 344 u8 serial_num[IPR_SERIAL_NUM_LEN];
319}__attribute__ ((packed)); 345}__attribute__ ((packed));
320 346
347#define IPR_RES_TYPE_AF_DASD 0x00
348#define IPR_RES_TYPE_GENERIC_SCSI 0x01
349#define IPR_RES_TYPE_VOLUME_SET 0x02
350#define IPR_RES_TYPE_REMOTE_AF_DASD 0x03
351#define IPR_RES_TYPE_GENERIC_ATA 0x04
352#define IPR_RES_TYPE_ARRAY 0x05
353#define IPR_RES_TYPE_IOAFP 0xff
354
321struct ipr_config_table_entry { 355struct ipr_config_table_entry {
322 u8 proto; 356 u8 proto;
323#define IPR_PROTO_SATA 0x02 357#define IPR_PROTO_SATA 0x02
324#define IPR_PROTO_SATA_ATAPI 0x03 358#define IPR_PROTO_SATA_ATAPI 0x03
325#define IPR_PROTO_SAS_STP 0x06 359#define IPR_PROTO_SAS_STP 0x06
326#define IPR_PROTO_SAS_STP_ATAPI 0x07 360#define IPR_PROTO_SAS_STP_ATAPI 0x07
327 u8 array_id; 361 u8 array_id;
328 u8 flags; 362 u8 flags;
329#define IPR_IS_IOA_RESOURCE 0x80 363#define IPR_IS_IOA_RESOURCE 0x80
330#define IPR_IS_ARRAY_MEMBER 0x20
331#define IPR_IS_HOT_SPARE 0x10
332
333 u8 rsvd_subtype; 364 u8 rsvd_subtype;
334#define IPR_RES_SUBTYPE(res) (((res)->cfgte.rsvd_subtype) & 0x0f) 365
335#define IPR_SUBTYPE_AF_DASD 0 366#define IPR_QUEUEING_MODEL(res) ((((res)->flags) & 0x70) >> 4)
336#define IPR_SUBTYPE_GENERIC_SCSI 1 367#define IPR_QUEUE_FROZEN_MODEL 0
337#define IPR_SUBTYPE_VOLUME_SET 2
338#define IPR_SUBTYPE_GENERIC_ATA 4
339
340#define IPR_QUEUEING_MODEL(res) ((((res)->cfgte.flags) & 0x70) >> 4)
341#define IPR_QUEUE_FROZEN_MODEL 0
342#define IPR_QUEUE_NACA_MODEL 1 368#define IPR_QUEUE_NACA_MODEL 1
343 369
344 struct ipr_res_addr res_addr; 370 struct ipr_res_addr res_addr;
@@ -347,6 +373,28 @@ struct ipr_config_table_entry {
347 struct ipr_std_inq_data std_inq_data; 373 struct ipr_std_inq_data std_inq_data;
348}__attribute__ ((packed, aligned (4))); 374}__attribute__ ((packed, aligned (4)));
349 375
376struct ipr_config_table_entry64 {
377 u8 res_type;
378 u8 proto;
379 u8 vset_num;
380 u8 array_id;
381 __be16 flags;
382 __be16 res_flags;
383#define IPR_QUEUEING_MODEL64(res) ((((res)->res_flags) & 0x7000) >> 12)
384 __be32 res_handle;
385 u8 dev_id_type;
386 u8 reserved[3];
387 __be64 dev_id;
388 __be64 lun;
389 __be64 lun_wwn[2];
390#define IPR_MAX_RES_PATH_LENGTH 24
391 __be64 res_path;
392 struct ipr_std_inq_data std_inq_data;
393 u8 reserved2[4];
394 __be64 reserved3[2]; // description text
395 u8 reserved4[8];
396}__attribute__ ((packed, aligned (8)));
397
350struct ipr_config_table_hdr { 398struct ipr_config_table_hdr {
351 u8 num_entries; 399 u8 num_entries;
352 u8 flags; 400 u8 flags;
@@ -354,13 +402,35 @@ struct ipr_config_table_hdr {
354 __be16 reserved; 402 __be16 reserved;
355}__attribute__((packed, aligned (4))); 403}__attribute__((packed, aligned (4)));
356 404
405struct ipr_config_table_hdr64 {
406 __be16 num_entries;
407 __be16 reserved;
408 u8 flags;
409 u8 reserved2[11];
410}__attribute__((packed, aligned (4)));
411
357struct ipr_config_table { 412struct ipr_config_table {
358 struct ipr_config_table_hdr hdr; 413 struct ipr_config_table_hdr hdr;
359 struct ipr_config_table_entry dev[IPR_MAX_PHYSICAL_DEVS]; 414 struct ipr_config_table_entry dev[0];
360}__attribute__((packed, aligned (4))); 415}__attribute__((packed, aligned (4)));
361 416
417struct ipr_config_table64 {
418 struct ipr_config_table_hdr64 hdr64;
419 struct ipr_config_table_entry64 dev[0];
420}__attribute__((packed, aligned (8)));
421
422struct ipr_config_table_entry_wrapper {
423 union {
424 struct ipr_config_table_entry *cfgte;
425 struct ipr_config_table_entry64 *cfgte64;
426 } u;
427};
428
362struct ipr_hostrcb_cfg_ch_not { 429struct ipr_hostrcb_cfg_ch_not {
363 struct ipr_config_table_entry cfgte; 430 union {
431 struct ipr_config_table_entry cfgte;
432 struct ipr_config_table_entry64 cfgte64;
433 } u;
364 u8 reserved[936]; 434 u8 reserved[936];
365}__attribute__((packed, aligned (4))); 435}__attribute__((packed, aligned (4)));
366 436
@@ -381,7 +451,7 @@ struct ipr_cmd_pkt {
381#define IPR_RQTYPE_HCAM 0x02 451#define IPR_RQTYPE_HCAM 0x02
382#define IPR_RQTYPE_ATA_PASSTHRU 0x04 452#define IPR_RQTYPE_ATA_PASSTHRU 0x04
383 453
384 u8 luntar_luntrn; 454 u8 reserved2;
385 455
386 u8 flags_hi; 456 u8 flags_hi;
387#define IPR_FLAGS_HI_WRITE_NOT_READ 0x80 457#define IPR_FLAGS_HI_WRITE_NOT_READ 0x80
@@ -403,7 +473,7 @@ struct ipr_cmd_pkt {
403 __be16 timeout; 473 __be16 timeout;
404}__attribute__ ((packed, aligned(4))); 474}__attribute__ ((packed, aligned(4)));
405 475
406struct ipr_ioarcb_ata_regs { 476struct ipr_ioarcb_ata_regs { /* 22 bytes */
407 u8 flags; 477 u8 flags;
408#define IPR_ATA_FLAG_PACKET_CMD 0x80 478#define IPR_ATA_FLAG_PACKET_CMD 0x80
409#define IPR_ATA_FLAG_XFER_TYPE_DMA 0x40 479#define IPR_ATA_FLAG_XFER_TYPE_DMA 0x40
@@ -442,28 +512,49 @@ struct ipr_ioadl_desc {
442 __be32 address; 512 __be32 address;
443}__attribute__((packed, aligned (8))); 513}__attribute__((packed, aligned (8)));
444 514
515struct ipr_ioadl64_desc {
516 __be32 flags;
517 __be32 data_len;
518 __be64 address;
519}__attribute__((packed, aligned (16)));
520
521struct ipr_ata64_ioadl {
522 struct ipr_ioarcb_ata_regs regs;
523 u16 reserved[5];
524 struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES];
525}__attribute__((packed, aligned (16)));
526
445struct ipr_ioarcb_add_data { 527struct ipr_ioarcb_add_data {
446 union { 528 union {
447 struct ipr_ioarcb_ata_regs regs; 529 struct ipr_ioarcb_ata_regs regs;
448 struct ipr_ioadl_desc ioadl[5]; 530 struct ipr_ioadl_desc ioadl[5];
449 __be32 add_cmd_parms[10]; 531 __be32 add_cmd_parms[10];
450 }u; 532 } u;
451}__attribute__ ((packed, aligned(4))); 533}__attribute__ ((packed, aligned (4)));
534
535struct ipr_ioarcb_sis64_add_addr_ecb {
536 __be64 ioasa_host_pci_addr;
537 __be64 data_ioadl_addr;
538 __be64 reserved;
539 __be32 ext_control_buf[4];
540}__attribute__((packed, aligned (8)));
452 541
453/* IOA Request Control Block 128 bytes */ 542/* IOA Request Control Block 128 bytes */
454struct ipr_ioarcb { 543struct ipr_ioarcb {
455 __be32 ioarcb_host_pci_addr; 544 union {
456 __be32 reserved; 545 __be32 ioarcb_host_pci_addr;
546 __be64 ioarcb_host_pci_addr64;
547 } a;
457 __be32 res_handle; 548 __be32 res_handle;
458 __be32 host_response_handle; 549 __be32 host_response_handle;
459 __be32 reserved1; 550 __be32 reserved1;
460 __be32 reserved2; 551 __be32 reserved2;
461 __be32 reserved3; 552 __be32 reserved3;
462 553
463 __be32 write_data_transfer_length; 554 __be32 data_transfer_length;
464 __be32 read_data_transfer_length; 555 __be32 read_data_transfer_length;
465 __be32 write_ioadl_addr; 556 __be32 write_ioadl_addr;
466 __be32 write_ioadl_len; 557 __be32 ioadl_len;
467 __be32 read_ioadl_addr; 558 __be32 read_ioadl_addr;
468 __be32 read_ioadl_len; 559 __be32 read_ioadl_len;
469 560
@@ -473,8 +564,14 @@ struct ipr_ioarcb {
473 564
474 struct ipr_cmd_pkt cmd_pkt; 565 struct ipr_cmd_pkt cmd_pkt;
475 566
476 __be32 add_cmd_parms_len; 567 __be16 add_cmd_parms_offset;
477 struct ipr_ioarcb_add_data add_data; 568 __be16 add_cmd_parms_len;
569
570 union {
571 struct ipr_ioarcb_add_data add_data;
572 struct ipr_ioarcb_sis64_add_addr_ecb sis64_addr_data;
573 } u;
574
478}__attribute__((packed, aligned (4))); 575}__attribute__((packed, aligned (4)));
479 576
480struct ipr_ioasa_vset { 577struct ipr_ioasa_vset {
@@ -676,12 +773,29 @@ struct ipr_hostrcb_device_data_entry_enhanced {
676 struct ipr_ext_vpd cfc_last_with_dev_vpd; 773 struct ipr_ext_vpd cfc_last_with_dev_vpd;
677}__attribute__((packed, aligned (4))); 774}__attribute__((packed, aligned (4)));
678 775
776struct ipr_hostrcb64_device_data_entry_enhanced {
777 struct ipr_ext_vpd vpd;
778 u8 ccin[4];
779 u8 res_path[8];
780 struct ipr_ext_vpd new_vpd;
781 u8 new_ccin[4];
782 struct ipr_ext_vpd ioa_last_with_dev_vpd;
783 struct ipr_ext_vpd cfc_last_with_dev_vpd;
784}__attribute__((packed, aligned (4)));
785
679struct ipr_hostrcb_array_data_entry { 786struct ipr_hostrcb_array_data_entry {
680 struct ipr_vpd vpd; 787 struct ipr_vpd vpd;
681 struct ipr_res_addr expected_dev_res_addr; 788 struct ipr_res_addr expected_dev_res_addr;
682 struct ipr_res_addr dev_res_addr; 789 struct ipr_res_addr dev_res_addr;
683}__attribute__((packed, aligned (4))); 790}__attribute__((packed, aligned (4)));
684 791
792struct ipr_hostrcb64_array_data_entry {
793 struct ipr_ext_vpd vpd;
794 u8 ccin[4];
795 u8 expected_res_path[8];
796 u8 res_path[8];
797}__attribute__((packed, aligned (4)));
798
685struct ipr_hostrcb_array_data_entry_enhanced { 799struct ipr_hostrcb_array_data_entry_enhanced {
686 struct ipr_ext_vpd vpd; 800 struct ipr_ext_vpd vpd;
687 u8 ccin[4]; 801 u8 ccin[4];
@@ -733,6 +847,14 @@ struct ipr_hostrcb_type_13_error {
733 struct ipr_hostrcb_device_data_entry_enhanced dev[3]; 847 struct ipr_hostrcb_device_data_entry_enhanced dev[3];
734}__attribute__((packed, aligned (4))); 848}__attribute__((packed, aligned (4)));
735 849
850struct ipr_hostrcb_type_23_error {
851 struct ipr_ext_vpd ioa_vpd;
852 struct ipr_ext_vpd cfc_vpd;
853 __be32 errors_detected;
854 __be32 errors_logged;
855 struct ipr_hostrcb64_device_data_entry_enhanced dev[3];
856}__attribute__((packed, aligned (4)));
857
736struct ipr_hostrcb_type_04_error { 858struct ipr_hostrcb_type_04_error {
737 struct ipr_vpd ioa_vpd; 859 struct ipr_vpd ioa_vpd;
738 struct ipr_vpd cfc_vpd; 860 struct ipr_vpd cfc_vpd;
@@ -760,6 +882,22 @@ struct ipr_hostrcb_type_14_error {
760 struct ipr_hostrcb_array_data_entry_enhanced array_member[18]; 882 struct ipr_hostrcb_array_data_entry_enhanced array_member[18];
761}__attribute__((packed, aligned (4))); 883}__attribute__((packed, aligned (4)));
762 884
885struct ipr_hostrcb_type_24_error {
886 struct ipr_ext_vpd ioa_vpd;
887 struct ipr_ext_vpd cfc_vpd;
888 u8 reserved[2];
889 u8 exposed_mode_adn;
890#define IPR_INVALID_ARRAY_DEV_NUM 0xff
891 u8 array_id;
892 u8 last_res_path[8];
893 u8 protection_level[8];
894 struct ipr_ext_vpd array_vpd;
895 u8 description[16];
896 u8 reserved2[3];
897 u8 num_entries;
898 struct ipr_hostrcb64_array_data_entry array_member[32];
899}__attribute__((packed, aligned (4)));
900
763struct ipr_hostrcb_type_07_error { 901struct ipr_hostrcb_type_07_error {
764 u8 failure_reason[64]; 902 u8 failure_reason[64];
765 struct ipr_vpd vpd; 903 struct ipr_vpd vpd;
@@ -797,6 +935,22 @@ struct ipr_hostrcb_config_element {
797 __be32 wwid[2]; 935 __be32 wwid[2];
798}__attribute__((packed, aligned (4))); 936}__attribute__((packed, aligned (4)));
799 937
938struct ipr_hostrcb64_config_element {
939 __be16 length;
940 u8 descriptor_id;
941#define IPR_DESCRIPTOR_MASK 0xC0
942#define IPR_DESCRIPTOR_SIS64 0x00
943
944 u8 reserved;
945 u8 type_status;
946
947 u8 reserved2[2];
948 u8 link_rate;
949
950 u8 res_path[8];
951 __be32 wwid[2];
952}__attribute__((packed, aligned (8)));
953
800struct ipr_hostrcb_fabric_desc { 954struct ipr_hostrcb_fabric_desc {
801 __be16 length; 955 __be16 length;
802 u8 ioa_port; 956 u8 ioa_port;
@@ -818,6 +972,20 @@ struct ipr_hostrcb_fabric_desc {
818 struct ipr_hostrcb_config_element elem[1]; 972 struct ipr_hostrcb_config_element elem[1];
819}__attribute__((packed, aligned (4))); 973}__attribute__((packed, aligned (4)));
820 974
975struct ipr_hostrcb64_fabric_desc {
976 __be16 length;
977 u8 descriptor_id;
978
979 u8 reserved;
980 u8 path_state;
981
982 u8 reserved2[2];
983 u8 res_path[8];
984 u8 reserved3[6];
985 __be16 num_entries;
986 struct ipr_hostrcb64_config_element elem[1];
987}__attribute__((packed, aligned (8)));
988
821#define for_each_fabric_cfg(fabric, cfg) \ 989#define for_each_fabric_cfg(fabric, cfg) \
822 for (cfg = (fabric)->elem; \ 990 for (cfg = (fabric)->elem; \
823 cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \ 991 cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \
@@ -830,10 +998,17 @@ struct ipr_hostrcb_type_20_error {
830 struct ipr_hostrcb_fabric_desc desc[1]; 998 struct ipr_hostrcb_fabric_desc desc[1];
831}__attribute__((packed, aligned (4))); 999}__attribute__((packed, aligned (4)));
832 1000
1001struct ipr_hostrcb_type_30_error {
1002 u8 failure_reason[64];
1003 u8 reserved[3];
1004 u8 num_entries;
1005 struct ipr_hostrcb64_fabric_desc desc[1];
1006}__attribute__((packed, aligned (4)));
1007
833struct ipr_hostrcb_error { 1008struct ipr_hostrcb_error {
834 __be32 failing_dev_ioasc; 1009 __be32 fd_ioasc;
835 struct ipr_res_addr failing_dev_res_addr; 1010 struct ipr_res_addr fd_res_addr;
836 __be32 failing_dev_res_handle; 1011 __be32 fd_res_handle;
837 __be32 prc; 1012 __be32 prc;
838 union { 1013 union {
839 struct ipr_hostrcb_type_ff_error type_ff_error; 1014 struct ipr_hostrcb_type_ff_error type_ff_error;
@@ -850,6 +1025,26 @@ struct ipr_hostrcb_error {
850 } u; 1025 } u;
851}__attribute__((packed, aligned (4))); 1026}__attribute__((packed, aligned (4)));
852 1027
1028struct ipr_hostrcb64_error {
1029 __be32 fd_ioasc;
1030 __be32 ioa_fw_level;
1031 __be32 fd_res_handle;
1032 __be32 prc;
1033 __be64 fd_dev_id;
1034 __be64 fd_lun;
1035 u8 fd_res_path[8];
1036 __be64 time_stamp;
1037 u8 reserved[2];
1038 union {
1039 struct ipr_hostrcb_type_ff_error type_ff_error;
1040 struct ipr_hostrcb_type_12_error type_12_error;
1041 struct ipr_hostrcb_type_17_error type_17_error;
1042 struct ipr_hostrcb_type_23_error type_23_error;
1043 struct ipr_hostrcb_type_24_error type_24_error;
1044 struct ipr_hostrcb_type_30_error type_30_error;
1045 } u;
1046}__attribute__((packed, aligned (8)));
1047
853struct ipr_hostrcb_raw { 1048struct ipr_hostrcb_raw {
854 __be32 data[sizeof(struct ipr_hostrcb_error)/sizeof(__be32)]; 1049 __be32 data[sizeof(struct ipr_hostrcb_error)/sizeof(__be32)];
855}__attribute__((packed, aligned (4))); 1050}__attribute__((packed, aligned (4)));
@@ -887,7 +1082,11 @@ struct ipr_hcam {
887#define IPR_HOST_RCB_OVERLAY_ID_16 0x16 1082#define IPR_HOST_RCB_OVERLAY_ID_16 0x16
888#define IPR_HOST_RCB_OVERLAY_ID_17 0x17 1083#define IPR_HOST_RCB_OVERLAY_ID_17 0x17
889#define IPR_HOST_RCB_OVERLAY_ID_20 0x20 1084#define IPR_HOST_RCB_OVERLAY_ID_20 0x20
890#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF 1085#define IPR_HOST_RCB_OVERLAY_ID_23 0x23
1086#define IPR_HOST_RCB_OVERLAY_ID_24 0x24
1087#define IPR_HOST_RCB_OVERLAY_ID_26 0x26
1088#define IPR_HOST_RCB_OVERLAY_ID_30 0x30
1089#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF
891 1090
892 u8 reserved1[3]; 1091 u8 reserved1[3];
893 __be32 ilid; 1092 __be32 ilid;
@@ -897,6 +1096,7 @@ struct ipr_hcam {
897 1096
898 union { 1097 union {
899 struct ipr_hostrcb_error error; 1098 struct ipr_hostrcb_error error;
1099 struct ipr_hostrcb64_error error64;
900 struct ipr_hostrcb_cfg_ch_not ccn; 1100 struct ipr_hostrcb_cfg_ch_not ccn;
901 struct ipr_hostrcb_raw raw; 1101 struct ipr_hostrcb_raw raw;
902 } u; 1102 } u;
@@ -907,14 +1107,14 @@ struct ipr_hostrcb {
907 dma_addr_t hostrcb_dma; 1107 dma_addr_t hostrcb_dma;
908 struct list_head queue; 1108 struct list_head queue;
909 struct ipr_ioa_cfg *ioa_cfg; 1109 struct ipr_ioa_cfg *ioa_cfg;
1110 char rp_buffer[IPR_MAX_RES_PATH_LENGTH];
910}; 1111};
911 1112
912/* IPR smart dump table structures */ 1113/* IPR smart dump table structures */
913struct ipr_sdt_entry { 1114struct ipr_sdt_entry {
914 __be32 bar_str_offset; 1115 __be32 start_token;
915 __be32 end_offset; 1116 __be32 end_token;
916 u8 entry_byte; 1117 u8 reserved[4];
917 u8 reserved[3];
918 1118
919 u8 flags; 1119 u8 flags;
920#define IPR_SDT_ENDIAN 0x80 1120#define IPR_SDT_ENDIAN 0x80
@@ -960,28 +1160,48 @@ struct ipr_sata_port {
960}; 1160};
961 1161
962struct ipr_resource_entry { 1162struct ipr_resource_entry {
963 struct ipr_config_table_entry cfgte;
964 u8 needs_sync_complete:1; 1163 u8 needs_sync_complete:1;
965 u8 in_erp:1; 1164 u8 in_erp:1;
966 u8 add_to_ml:1; 1165 u8 add_to_ml:1;
967 u8 del_from_ml:1; 1166 u8 del_from_ml:1;
968 u8 resetting_device:1; 1167 u8 resetting_device:1;
969 1168
1169 u32 bus; /* AKA channel */
1170 u32 target; /* AKA id */
1171 u32 lun;
1172#define IPR_ARRAY_VIRTUAL_BUS 0x1
1173#define IPR_VSET_VIRTUAL_BUS 0x2
1174#define IPR_IOAFP_VIRTUAL_BUS 0x3
1175
1176#define IPR_GET_RES_PHYS_LOC(res) \
1177 (((res)->bus << 24) | ((res)->target << 8) | (res)->lun)
1178
1179 u8 ata_class;
1180
1181 u8 flags;
1182 __be16 res_flags;
1183
1184 __be32 type;
1185
1186 u8 qmodel;
1187 struct ipr_std_inq_data std_inq_data;
1188
1189 __be32 res_handle;
1190 __be64 dev_id;
1191 struct scsi_lun dev_lun;
1192 u8 res_path[8];
1193
1194 struct ipr_ioa_cfg *ioa_cfg;
970 struct scsi_device *sdev; 1195 struct scsi_device *sdev;
971 struct ipr_sata_port *sata_port; 1196 struct ipr_sata_port *sata_port;
972 struct list_head queue; 1197 struct list_head queue;
973}; 1198}; /* struct ipr_resource_entry */
974 1199
975struct ipr_resource_hdr { 1200struct ipr_resource_hdr {
976 u16 num_entries; 1201 u16 num_entries;
977 u16 reserved; 1202 u16 reserved;
978}; 1203};
979 1204
980struct ipr_resource_table {
981 struct ipr_resource_hdr hdr;
982 struct ipr_resource_entry dev[IPR_MAX_PHYSICAL_DEVS];
983};
984
985struct ipr_misc_cbs { 1205struct ipr_misc_cbs {
986 struct ipr_ioa_vpd ioa_vpd; 1206 struct ipr_ioa_vpd ioa_vpd;
987 struct ipr_inquiry_page0 page0_data; 1207 struct ipr_inquiry_page0 page0_data;
@@ -994,27 +1214,51 @@ struct ipr_misc_cbs {
994struct ipr_interrupt_offsets { 1214struct ipr_interrupt_offsets {
995 unsigned long set_interrupt_mask_reg; 1215 unsigned long set_interrupt_mask_reg;
996 unsigned long clr_interrupt_mask_reg; 1216 unsigned long clr_interrupt_mask_reg;
1217 unsigned long clr_interrupt_mask_reg32;
997 unsigned long sense_interrupt_mask_reg; 1218 unsigned long sense_interrupt_mask_reg;
1219 unsigned long sense_interrupt_mask_reg32;
998 unsigned long clr_interrupt_reg; 1220 unsigned long clr_interrupt_reg;
1221 unsigned long clr_interrupt_reg32;
999 1222
1000 unsigned long sense_interrupt_reg; 1223 unsigned long sense_interrupt_reg;
1224 unsigned long sense_interrupt_reg32;
1001 unsigned long ioarrin_reg; 1225 unsigned long ioarrin_reg;
1002 unsigned long sense_uproc_interrupt_reg; 1226 unsigned long sense_uproc_interrupt_reg;
1227 unsigned long sense_uproc_interrupt_reg32;
1003 unsigned long set_uproc_interrupt_reg; 1228 unsigned long set_uproc_interrupt_reg;
1229 unsigned long set_uproc_interrupt_reg32;
1004 unsigned long clr_uproc_interrupt_reg; 1230 unsigned long clr_uproc_interrupt_reg;
1231 unsigned long clr_uproc_interrupt_reg32;
1232
1233 unsigned long init_feedback_reg;
1234
1235 unsigned long dump_addr_reg;
1236 unsigned long dump_data_reg;
1005}; 1237};
1006 1238
1007struct ipr_interrupts { 1239struct ipr_interrupts {
1008 void __iomem *set_interrupt_mask_reg; 1240 void __iomem *set_interrupt_mask_reg;
1009 void __iomem *clr_interrupt_mask_reg; 1241 void __iomem *clr_interrupt_mask_reg;
1242 void __iomem *clr_interrupt_mask_reg32;
1010 void __iomem *sense_interrupt_mask_reg; 1243 void __iomem *sense_interrupt_mask_reg;
1244 void __iomem *sense_interrupt_mask_reg32;
1011 void __iomem *clr_interrupt_reg; 1245 void __iomem *clr_interrupt_reg;
1246 void __iomem *clr_interrupt_reg32;
1012 1247
1013 void __iomem *sense_interrupt_reg; 1248 void __iomem *sense_interrupt_reg;
1249 void __iomem *sense_interrupt_reg32;
1014 void __iomem *ioarrin_reg; 1250 void __iomem *ioarrin_reg;
1015 void __iomem *sense_uproc_interrupt_reg; 1251 void __iomem *sense_uproc_interrupt_reg;
1252 void __iomem *sense_uproc_interrupt_reg32;
1016 void __iomem *set_uproc_interrupt_reg; 1253 void __iomem *set_uproc_interrupt_reg;
1254 void __iomem *set_uproc_interrupt_reg32;
1017 void __iomem *clr_uproc_interrupt_reg; 1255 void __iomem *clr_uproc_interrupt_reg;
1256 void __iomem *clr_uproc_interrupt_reg32;
1257
1258 void __iomem *init_feedback_reg;
1259
1260 void __iomem *dump_addr_reg;
1261 void __iomem *dump_data_reg;
1018}; 1262};
1019 1263
1020struct ipr_chip_cfg_t { 1264struct ipr_chip_cfg_t {
@@ -1029,6 +1273,9 @@ struct ipr_chip_t {
1029 u16 intr_type; 1273 u16 intr_type;
1030#define IPR_USE_LSI 0x00 1274#define IPR_USE_LSI 0x00
1031#define IPR_USE_MSI 0x01 1275#define IPR_USE_MSI 0x01
1276 u16 sis_type;
1277#define IPR_SIS32 0x00
1278#define IPR_SIS64 0x01
1032 const struct ipr_chip_cfg_t *cfg; 1279 const struct ipr_chip_cfg_t *cfg;
1033}; 1280};
1034 1281
@@ -1073,13 +1320,6 @@ enum ipr_sdt_state {
1073 DUMP_OBTAINED 1320 DUMP_OBTAINED
1074}; 1321};
1075 1322
1076enum ipr_cache_state {
1077 CACHE_NONE,
1078 CACHE_DISABLED,
1079 CACHE_ENABLED,
1080 CACHE_INVALID
1081};
1082
1083/* Per-controller data */ 1323/* Per-controller data */
1084struct ipr_ioa_cfg { 1324struct ipr_ioa_cfg {
1085 char eye_catcher[8]; 1325 char eye_catcher[8];
@@ -1099,10 +1339,17 @@ struct ipr_ioa_cfg {
1099 u8 dual_raid:1; 1339 u8 dual_raid:1;
1100 u8 needs_warm_reset:1; 1340 u8 needs_warm_reset:1;
1101 u8 msi_received:1; 1341 u8 msi_received:1;
1342 u8 sis64:1;
1102 1343
1103 u8 revid; 1344 u8 revid;
1104 1345
1105 enum ipr_cache_state cache_state; 1346 /*
1347 * Bitmaps for SIS64 generated target values
1348 */
1349 unsigned long *target_ids;
1350 unsigned long *array_ids;
1351 unsigned long *vset_ids;
1352
1106 u16 type; /* CCIN of the card */ 1353 u16 type; /* CCIN of the card */
1107 1354
1108 u8 log_level; 1355 u8 log_level;
@@ -1133,8 +1380,13 @@ struct ipr_ioa_cfg {
1133 1380
1134 char cfg_table_start[8]; 1381 char cfg_table_start[8];
1135#define IPR_CFG_TBL_START "cfg" 1382#define IPR_CFG_TBL_START "cfg"
1136 struct ipr_config_table *cfg_table; 1383 union {
1384 struct ipr_config_table *cfg_table;
1385 struct ipr_config_table64 *cfg_table64;
1386 } u;
1137 dma_addr_t cfg_table_dma; 1387 dma_addr_t cfg_table_dma;
1388 u32 cfg_table_size;
1389 u32 max_devs_supported;
1138 1390
1139 char resource_table_label[8]; 1391 char resource_table_label[8];
1140#define IPR_RES_TABLE_LABEL "res_tbl" 1392#define IPR_RES_TABLE_LABEL "res_tbl"
@@ -1202,13 +1454,17 @@ struct ipr_ioa_cfg {
1202 char ipr_cmd_label[8]; 1454 char ipr_cmd_label[8];
1203#define IPR_CMD_LABEL "ipr_cmd" 1455#define IPR_CMD_LABEL "ipr_cmd"
1204 struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS]; 1456 struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS];
1205 u32 ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS]; 1457 dma_addr_t ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS];
1206}; 1458}; /* struct ipr_ioa_cfg */
1207 1459
1208struct ipr_cmnd { 1460struct ipr_cmnd {
1209 struct ipr_ioarcb ioarcb; 1461 struct ipr_ioarcb ioarcb;
1462 union {
1463 struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES];
1464 struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES];
1465 struct ipr_ata64_ioadl ata_ioadl;
1466 } i;
1210 struct ipr_ioasa ioasa; 1467 struct ipr_ioasa ioasa;
1211 struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES];
1212 struct list_head queue; 1468 struct list_head queue;
1213 struct scsi_cmnd *scsi_cmd; 1469 struct scsi_cmnd *scsi_cmd;
1214 struct ata_queued_cmd *qc; 1470 struct ata_queued_cmd *qc;
@@ -1221,7 +1477,7 @@ struct ipr_cmnd {
1221 u8 sense_buffer[SCSI_SENSE_BUFFERSIZE]; 1477 u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
1222 dma_addr_t sense_buffer_dma; 1478 dma_addr_t sense_buffer_dma;
1223 unsigned short dma_use_sg; 1479 unsigned short dma_use_sg;
1224 dma_addr_t dma_handle; 1480 dma_addr_t dma_addr;
1225 struct ipr_cmnd *sibling; 1481 struct ipr_cmnd *sibling;
1226 union { 1482 union {
1227 enum ipr_shutdown_type shutdown_type; 1483 enum ipr_shutdown_type shutdown_type;
@@ -1314,8 +1570,6 @@ struct ipr_ioa_dump {
1314 u32 next_page_index; 1570 u32 next_page_index;
1315 u32 page_offset; 1571 u32 page_offset;
1316 u32 format; 1572 u32 format;
1317#define IPR_SDT_FMT2 2
1318#define IPR_SDT_UNKNOWN 3
1319}__attribute__((packed, aligned (4))); 1573}__attribute__((packed, aligned (4)));
1320 1574
1321struct ipr_dump { 1575struct ipr_dump {
@@ -1377,6 +1631,13 @@ struct ipr_ucode_image_header {
1377#define ipr_info(...) printk(KERN_INFO IPR_NAME ": "__VA_ARGS__) 1631#define ipr_info(...) printk(KERN_INFO IPR_NAME ": "__VA_ARGS__)
1378#define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__)) 1632#define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__))
1379 1633
1634#define ipr_res_printk(level, ioa_cfg, bus, target, lun, fmt, ...) \
1635 printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \
1636 bus, target, lun, ##__VA_ARGS__)
1637
1638#define ipr_res_err(ioa_cfg, res, fmt, ...) \
1639 ipr_res_printk(KERN_ERR, ioa_cfg, (res)->bus, (res)->target, (res)->lun, fmt, ##__VA_ARGS__)
1640
1380#define ipr_ra_printk(level, ioa_cfg, ra, fmt, ...) \ 1641#define ipr_ra_printk(level, ioa_cfg, ra, fmt, ...) \
1381 printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \ 1642 printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \
1382 (ra).bus, (ra).target, (ra).lun, ##__VA_ARGS__) 1643 (ra).bus, (ra).target, (ra).lun, ##__VA_ARGS__)
@@ -1384,9 +1645,6 @@ struct ipr_ucode_image_header {
1384#define ipr_ra_err(ioa_cfg, ra, fmt, ...) \ 1645#define ipr_ra_err(ioa_cfg, ra, fmt, ...) \
1385 ipr_ra_printk(KERN_ERR, ioa_cfg, ra, fmt, ##__VA_ARGS__) 1646 ipr_ra_printk(KERN_ERR, ioa_cfg, ra, fmt, ##__VA_ARGS__)
1386 1647
1387#define ipr_res_err(ioa_cfg, res, fmt, ...) \
1388 ipr_ra_err(ioa_cfg, (res)->cfgte.res_addr, fmt, ##__VA_ARGS__)
1389
1390#define ipr_phys_res_err(ioa_cfg, res, fmt, ...) \ 1648#define ipr_phys_res_err(ioa_cfg, res, fmt, ...) \
1391{ \ 1649{ \
1392 if ((res).bus >= IPR_MAX_NUM_BUSES) { \ 1650 if ((res).bus >= IPR_MAX_NUM_BUSES) { \
@@ -1399,14 +1657,21 @@ struct ipr_ucode_image_header {
1399} 1657}
1400 1658
1401#define ipr_hcam_err(hostrcb, fmt, ...) \ 1659#define ipr_hcam_err(hostrcb, fmt, ...) \
1402{ \ 1660{ \
1403 if (ipr_is_device(&(hostrcb)->hcam.u.error.failing_dev_res_addr)) { \ 1661 if (ipr_is_device(hostrcb)) { \
1404 ipr_ra_err((hostrcb)->ioa_cfg, \ 1662 if ((hostrcb)->ioa_cfg->sis64) { \
1405 (hostrcb)->hcam.u.error.failing_dev_res_addr, \ 1663 printk(KERN_ERR IPR_NAME ": %s: " fmt, \
1406 fmt, ##__VA_ARGS__); \ 1664 ipr_format_resource_path(&hostrcb->hcam.u.error64.fd_res_path[0], \
1407 } else { \ 1665 &hostrcb->rp_buffer[0]), \
1408 dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, ##__VA_ARGS__); \ 1666 __VA_ARGS__); \
1409 } \ 1667 } else { \
1668 ipr_ra_err((hostrcb)->ioa_cfg, \
1669 (hostrcb)->hcam.u.error.fd_res_addr, \
1670 fmt, __VA_ARGS__); \
1671 } \
1672 } else { \
1673 dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, __VA_ARGS__); \
1674 } \
1410} 1675}
1411 1676
1412#define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ 1677#define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\
@@ -1432,7 +1697,7 @@ ipr_err("----------------------------------------------------------\n")
1432 **/ 1697 **/
1433static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res) 1698static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res)
1434{ 1699{
1435 return (res->cfgte.flags & IPR_IS_IOA_RESOURCE) ? 1 : 0; 1700 return res->type == IPR_RES_TYPE_IOAFP;
1436} 1701}
1437 1702
1438/** 1703/**
@@ -1444,12 +1709,8 @@ static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res)
1444 **/ 1709 **/
1445static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res) 1710static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res)
1446{ 1711{
1447 if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) && 1712 return res->type == IPR_RES_TYPE_AF_DASD ||
1448 !ipr_is_ioa_resource(res) && 1713 res->type == IPR_RES_TYPE_REMOTE_AF_DASD;
1449 IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_AF_DASD)
1450 return 1;
1451 else
1452 return 0;
1453} 1714}
1454 1715
1455/** 1716/**
@@ -1461,12 +1722,7 @@ static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res)
1461 **/ 1722 **/
1462static inline int ipr_is_vset_device(struct ipr_resource_entry *res) 1723static inline int ipr_is_vset_device(struct ipr_resource_entry *res)
1463{ 1724{
1464 if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) && 1725 return res->type == IPR_RES_TYPE_VOLUME_SET;
1465 !ipr_is_ioa_resource(res) &&
1466 IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_VOLUME_SET)
1467 return 1;
1468 else
1469 return 0;
1470} 1726}
1471 1727
1472/** 1728/**
@@ -1478,11 +1734,7 @@ static inline int ipr_is_vset_device(struct ipr_resource_entry *res)
1478 **/ 1734 **/
1479static inline int ipr_is_gscsi(struct ipr_resource_entry *res) 1735static inline int ipr_is_gscsi(struct ipr_resource_entry *res)
1480{ 1736{
1481 if (!ipr_is_ioa_resource(res) && 1737 return res->type == IPR_RES_TYPE_GENERIC_SCSI;
1482 IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_SCSI)
1483 return 1;
1484 else
1485 return 0;
1486} 1738}
1487 1739
1488/** 1740/**
@@ -1495,7 +1747,7 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res)
1495static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res) 1747static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res)
1496{ 1748{
1497 if (ipr_is_af_dasd_device(res) || 1749 if (ipr_is_af_dasd_device(res) ||
1498 (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data))) 1750 (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->std_inq_data)))
1499 return 1; 1751 return 1;
1500 else 1752 else
1501 return 0; 1753 return 0;
@@ -1510,11 +1762,7 @@ static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res)
1510 **/ 1762 **/
1511static inline int ipr_is_gata(struct ipr_resource_entry *res) 1763static inline int ipr_is_gata(struct ipr_resource_entry *res)
1512{ 1764{
1513 if (!ipr_is_ioa_resource(res) && 1765 return res->type == IPR_RES_TYPE_GENERIC_ATA;
1514 IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_ATA)
1515 return 1;
1516 else
1517 return 0;
1518} 1766}
1519 1767
1520/** 1768/**
@@ -1526,24 +1774,35 @@ static inline int ipr_is_gata(struct ipr_resource_entry *res)
1526 **/ 1774 **/
1527static inline int ipr_is_naca_model(struct ipr_resource_entry *res) 1775static inline int ipr_is_naca_model(struct ipr_resource_entry *res)
1528{ 1776{
1529 if (ipr_is_gscsi(res) && IPR_QUEUEING_MODEL(res) == IPR_QUEUE_NACA_MODEL) 1777 if (ipr_is_gscsi(res) && res->qmodel == IPR_QUEUE_NACA_MODEL)
1530 return 1; 1778 return 1;
1531 return 0; 1779 return 0;
1532} 1780}
1533 1781
1534/** 1782/**
1535 * ipr_is_device - Determine if resource address is that of a device 1783 * ipr_is_device - Determine if the hostrcb structure is related to a device
1536 * @res_addr: resource address struct 1784 * @hostrcb: host resource control blocks struct
1537 * 1785 *
1538 * Return value: 1786 * Return value:
1539 * 1 if AF / 0 if not AF 1787 * 1 if AF / 0 if not AF
1540 **/ 1788 **/
1541static inline int ipr_is_device(struct ipr_res_addr *res_addr) 1789static inline int ipr_is_device(struct ipr_hostrcb *hostrcb)
1542{ 1790{
1543 if ((res_addr->bus < IPR_MAX_NUM_BUSES) && 1791 struct ipr_res_addr *res_addr;
1544 (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1))) 1792 u8 *res_path;
1545 return 1; 1793
1546 1794 if (hostrcb->ioa_cfg->sis64) {
1795 res_path = &hostrcb->hcam.u.error64.fd_res_path[0];
1796 if ((res_path[0] == 0x00 || res_path[0] == 0x80 ||
1797 res_path[0] == 0x81) && res_path[2] != 0xFF)
1798 return 1;
1799 } else {
1800 res_addr = &hostrcb->hcam.u.error.fd_res_addr;
1801
1802 if ((res_addr->bus < IPR_MAX_NUM_BUSES) &&
1803 (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1)))
1804 return 1;
1805 }
1547 return 0; 1806 return 0;
1548} 1807}
1549 1808
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 8a89ba900588..249053a9d4fa 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -874,7 +874,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
874 .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, 874 .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
875 .eh_abort_handler = iscsi_eh_abort, 875 .eh_abort_handler = iscsi_eh_abort,
876 .eh_device_reset_handler= iscsi_eh_device_reset, 876 .eh_device_reset_handler= iscsi_eh_device_reset,
877 .eh_target_reset_handler= iscsi_eh_target_reset, 877 .eh_target_reset_handler = iscsi_eh_recover_target,
878 .use_clustering = DISABLE_CLUSTERING, 878 .use_clustering = DISABLE_CLUSTERING,
879 .slave_alloc = iscsi_sw_tcp_slave_alloc, 879 .slave_alloc = iscsi_sw_tcp_slave_alloc,
880 .slave_configure = iscsi_sw_tcp_slave_configure, 880 .slave_configure = iscsi_sw_tcp_slave_configure,
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 703eb6a88790..685eaec53218 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2338,7 +2338,7 @@ EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout);
2338 * This function will wait for a relogin, session termination from 2338 * This function will wait for a relogin, session termination from
2339 * userspace, or a recovery/replacement timeout. 2339 * userspace, or a recovery/replacement timeout.
2340 */ 2340 */
2341static int iscsi_eh_session_reset(struct scsi_cmnd *sc) 2341int iscsi_eh_session_reset(struct scsi_cmnd *sc)
2342{ 2342{
2343 struct iscsi_cls_session *cls_session; 2343 struct iscsi_cls_session *cls_session;
2344 struct iscsi_session *session; 2344 struct iscsi_session *session;
@@ -2389,6 +2389,7 @@ failed:
2389 mutex_unlock(&session->eh_mutex); 2389 mutex_unlock(&session->eh_mutex);
2390 return SUCCESS; 2390 return SUCCESS;
2391} 2391}
2392EXPORT_SYMBOL_GPL(iscsi_eh_session_reset);
2392 2393
2393static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr) 2394static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
2394{ 2395{
@@ -2403,8 +2404,7 @@ static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
2403 * iscsi_eh_target_reset - reset target 2404 * iscsi_eh_target_reset - reset target
2404 * @sc: scsi command 2405 * @sc: scsi command
2405 * 2406 *
2406 * This will attempt to send a warm target reset. If that fails 2407 * This will attempt to send a warm target reset.
2407 * then we will drop the session and attempt ERL0 recovery.
2408 */ 2408 */
2409int iscsi_eh_target_reset(struct scsi_cmnd *sc) 2409int iscsi_eh_target_reset(struct scsi_cmnd *sc)
2410{ 2410{
@@ -2476,12 +2476,27 @@ done:
2476 ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname, 2476 ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname,
2477 rc == SUCCESS ? "SUCCESS" : "FAILED"); 2477 rc == SUCCESS ? "SUCCESS" : "FAILED");
2478 mutex_unlock(&session->eh_mutex); 2478 mutex_unlock(&session->eh_mutex);
2479 return rc;
2480}
2481EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
2479 2482
2483/**
2484 * iscsi_eh_recover_target - reset target and possibly the session
2485 * @sc: scsi command
2486 *
2487 * This will attempt to send a warm target reset. If that fails,
2488 * we will escalate to ERL0 session recovery.
2489 */
2490int iscsi_eh_recover_target(struct scsi_cmnd *sc)
2491{
2492 int rc;
2493
2494 rc = iscsi_eh_target_reset(sc);
2480 if (rc == FAILED) 2495 if (rc == FAILED)
2481 rc = iscsi_eh_session_reset(sc); 2496 rc = iscsi_eh_session_reset(sc);
2482 return rc; 2497 return rc;
2483} 2498}
2484EXPORT_SYMBOL_GPL(iscsi_eh_target_reset); 2499EXPORT_SYMBOL_GPL(iscsi_eh_recover_target);
2485 2500
2486/* 2501/*
2487 * Pre-allocate a pool of @max items of @item_size. By default, the pool 2502 * Pre-allocate a pool of @max items of @item_size. By default, the pool
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 84b696463a58..565e16dd74fc 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -37,6 +37,9 @@ struct lpfc_sli2_slim;
37 the NameServer before giving up. */ 37 the NameServer before giving up. */
38#define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ 38#define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */
39#define LPFC_DEFAULT_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ 39#define LPFC_DEFAULT_SG_SEG_CNT 64 /* sg element count per scsi cmnd */
40#define LPFC_DEFAULT_MENLO_SG_SEG_CNT 128 /* sg element count per scsi
41 cmnd for menlo needs nearly twice as for firmware
42 downloads using bsg */
40#define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */ 43#define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */
41#define LPFC_MAX_SG_SEG_CNT 4096 /* sg element count per scsi cmnd */ 44#define LPFC_MAX_SG_SEG_CNT 4096 /* sg element count per scsi cmnd */
42#define LPFC_MAX_PROT_SG_SEG_CNT 4096 /* prot sg element count per scsi cmd*/ 45#define LPFC_MAX_PROT_SG_SEG_CNT 4096 /* prot sg element count per scsi cmd*/
@@ -509,7 +512,6 @@ struct lpfc_hba {
509 int (*lpfc_hba_down_link) 512 int (*lpfc_hba_down_link)
510 (struct lpfc_hba *); 513 (struct lpfc_hba *);
511 514
512
513 /* SLI4 specific HBA data structure */ 515 /* SLI4 specific HBA data structure */
514 struct lpfc_sli4_hba sli4_hba; 516 struct lpfc_sli4_hba sli4_hba;
515 517
@@ -623,6 +625,9 @@ struct lpfc_hba {
623 uint32_t cfg_log_verbose; 625 uint32_t cfg_log_verbose;
624 uint32_t cfg_aer_support; 626 uint32_t cfg_aer_support;
625 uint32_t cfg_suppress_link_up; 627 uint32_t cfg_suppress_link_up;
628#define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */
629#define LPFC_DELAY_INIT_LINK 1 /* layered driver hold off */
630#define LPFC_DELAY_INIT_LINK_INDEFINITELY 2 /* wait, manual intervention */
626 631
627 lpfc_vpd_t vpd; /* vital product data */ 632 lpfc_vpd_t vpd; /* vital product data */
628 633
@@ -804,6 +809,9 @@ struct lpfc_hba {
804 struct list_head ct_ev_waiters; 809 struct list_head ct_ev_waiters;
805 struct unsol_rcv_ct_ctx ct_ctx[64]; 810 struct unsol_rcv_ct_ctx ct_ctx[64];
806 uint32_t ctx_idx; 811 uint32_t ctx_idx;
812
813 uint8_t menlo_flag; /* menlo generic flags */
814#define HBA_MENLO_SUPPORT 0x1 /* HBA supports menlo commands */
807}; 815};
808 816
809static inline struct Scsi_Host * 817static inline struct Scsi_Host *
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index c992e8328f9e..64cd17eedb64 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1939,7 +1939,9 @@ static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO,
1939# 0x2 = never bring up link 1939# 0x2 = never bring up link
1940# Default value is 0. 1940# Default value is 0.
1941*/ 1941*/
1942LPFC_ATTR_R(suppress_link_up, 0, 0, 2, "Suppress Link Up at initialization"); 1942LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK,
1943 LPFC_DELAY_INIT_LINK_INDEFINITELY,
1944 "Suppress Link Up at initialization");
1943 1945
1944/* 1946/*
1945# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear 1947# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
@@ -1966,8 +1968,7 @@ lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr,
1966{ 1968{
1967 struct Scsi_Host *shost = class_to_shost(dev); 1969 struct Scsi_Host *shost = class_to_shost(dev);
1968 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; 1970 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1969 int val = 0; 1971
1970 val = vport->cfg_devloss_tmo;
1971 return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo); 1972 return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);
1972} 1973}
1973 1974
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index f3f1bf1a0a71..692c29f6048e 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -83,15 +83,28 @@ struct lpfc_bsg_mbox {
83 struct fc_bsg_job *set_job; 83 struct fc_bsg_job *set_job;
84}; 84};
85 85
86#define MENLO_DID 0x0000FC0E
87
88struct lpfc_bsg_menlo {
89 struct lpfc_iocbq *cmdiocbq;
90 struct lpfc_iocbq *rspiocbq;
91 struct lpfc_dmabuf *bmp;
92
93 /* job waiting for this iocb to finish */
94 struct fc_bsg_job *set_job;
95};
96
86#define TYPE_EVT 1 97#define TYPE_EVT 1
87#define TYPE_IOCB 2 98#define TYPE_IOCB 2
88#define TYPE_MBOX 3 99#define TYPE_MBOX 3
100#define TYPE_MENLO 4
89struct bsg_job_data { 101struct bsg_job_data {
90 uint32_t type; 102 uint32_t type;
91 union { 103 union {
92 struct lpfc_bsg_event *evt; 104 struct lpfc_bsg_event *evt;
93 struct lpfc_bsg_iocb iocb; 105 struct lpfc_bsg_iocb iocb;
94 struct lpfc_bsg_mbox mbox; 106 struct lpfc_bsg_mbox mbox;
107 struct lpfc_bsg_menlo menlo;
95 } context_un; 108 } context_un;
96}; 109};
97 110
@@ -2456,6 +2469,18 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba,
2456 case MBX_PORT_IOV_CONTROL: 2469 case MBX_PORT_IOV_CONTROL:
2457 break; 2470 break;
2458 case MBX_SET_VARIABLE: 2471 case MBX_SET_VARIABLE:
2472 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2473 "1226 mbox: set_variable 0x%x, 0x%x\n",
2474 mb->un.varWords[0],
2475 mb->un.varWords[1]);
2476 if ((mb->un.varWords[0] == SETVAR_MLOMNT)
2477 && (mb->un.varWords[1] == 1)) {
2478 phba->wait_4_mlo_maint_flg = 1;
2479 } else if (mb->un.varWords[0] == SETVAR_MLORST) {
2480 phba->link_flag &= ~LS_LOOPBACK_MODE;
2481 phba->fc_topology = TOPOLOGY_PT_PT;
2482 }
2483 break;
2459 case MBX_RUN_BIU_DIAG64: 2484 case MBX_RUN_BIU_DIAG64:
2460 case MBX_READ_EVENT_LOG: 2485 case MBX_READ_EVENT_LOG:
2461 case MBX_READ_SPARM64: 2486 case MBX_READ_SPARM64:
@@ -2638,6 +2663,297 @@ job_error:
2638} 2663}
2639 2664
2640/** 2665/**
2666 * lpfc_bsg_menlo_cmd_cmp - lpfc_menlo_cmd completion handler
2667 * @phba: Pointer to HBA context object.
2668 * @cmdiocbq: Pointer to command iocb.
2669 * @rspiocbq: Pointer to response iocb.
2670 *
2671 * This function is the completion handler for iocbs issued using
2672 * lpfc_menlo_cmd function. This function is called by the
2673 * ring event handler function without any lock held. This function
2674 * can be called from both worker thread context and interrupt
2675 * context. This function also can be called from another thread which
2676 * cleans up the SLI layer objects.
2677 * This function copies the contents of the response iocb to the
2678 * response iocb memory object provided by the caller of
2679 * lpfc_sli_issue_iocb_wait and then wakes up the thread which
2680 * sleeps for the iocb completion.
2681 **/
2682static void
2683lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
2684 struct lpfc_iocbq *cmdiocbq,
2685 struct lpfc_iocbq *rspiocbq)
2686{
2687 struct bsg_job_data *dd_data;
2688 struct fc_bsg_job *job;
2689 IOCB_t *rsp;
2690 struct lpfc_dmabuf *bmp;
2691 struct lpfc_bsg_menlo *menlo;
2692 unsigned long flags;
2693 struct menlo_response *menlo_resp;
2694 int rc = 0;
2695
2696 spin_lock_irqsave(&phba->ct_ev_lock, flags);
2697 dd_data = cmdiocbq->context1;
2698 if (!dd_data) {
2699 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
2700 return;
2701 }
2702
2703 menlo = &dd_data->context_un.menlo;
2704 job = menlo->set_job;
2705 job->dd_data = NULL; /* so timeout handler does not reply */
2706
2707 spin_lock_irqsave(&phba->hbalock, flags);
2708 cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
2709 if (cmdiocbq->context2 && rspiocbq)
2710 memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
2711 &rspiocbq->iocb, sizeof(IOCB_t));
2712 spin_unlock_irqrestore(&phba->hbalock, flags);
2713
2714 bmp = menlo->bmp;
2715 rspiocbq = menlo->rspiocbq;
2716 rsp = &rspiocbq->iocb;
2717
2718 pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
2719 job->request_payload.sg_cnt, DMA_TO_DEVICE);
2720 pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
2721 job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
2722
2723 /* always return the xri, this would be used in the case
2724 * of a menlo download to allow the data to be sent as a continuation
2725 * of the exchange.
2726 */
2727 menlo_resp = (struct menlo_response *)
2728 job->reply->reply_data.vendor_reply.vendor_rsp;
2729 menlo_resp->xri = rsp->ulpContext;
2730 if (rsp->ulpStatus) {
2731 if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
2732 switch (rsp->un.ulpWord[4] & 0xff) {
2733 case IOERR_SEQUENCE_TIMEOUT:
2734 rc = -ETIMEDOUT;
2735 break;
2736 case IOERR_INVALID_RPI:
2737 rc = -EFAULT;
2738 break;
2739 default:
2740 rc = -EACCES;
2741 break;
2742 }
2743 } else
2744 rc = -EACCES;
2745 } else
2746 job->reply->reply_payload_rcv_len =
2747 rsp->un.genreq64.bdl.bdeSize;
2748
2749 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
2750 lpfc_sli_release_iocbq(phba, rspiocbq);
2751 lpfc_sli_release_iocbq(phba, cmdiocbq);
2752 kfree(bmp);
2753 kfree(dd_data);
2754 /* make error code available to userspace */
2755 job->reply->result = rc;
2756 /* complete the job back to userspace */
2757 job->job_done(job);
2758 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
2759 return;
2760}
2761
2762/**
2763 * lpfc_menlo_cmd - send an ioctl for menlo hardware
2764 * @job: fc_bsg_job to handle
2765 *
2766 * This function issues a gen request 64 CR ioctl for all menlo cmd requests,
2767 * all the command completions will return the xri for the command.
2768 * For menlo data requests a gen request 64 CX is used to continue the exchange
2769 * supplied in the menlo request header xri field.
2770 **/
2771static int
2772lpfc_menlo_cmd(struct fc_bsg_job *job)
2773{
2774 struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
2775 struct lpfc_hba *phba = vport->phba;
2776 struct lpfc_iocbq *cmdiocbq, *rspiocbq;
2777 IOCB_t *cmd, *rsp;
2778 int rc = 0;
2779 struct menlo_command *menlo_cmd;
2780 struct menlo_response *menlo_resp;
2781 struct lpfc_dmabuf *bmp = NULL;
2782 int request_nseg;
2783 int reply_nseg;
2784 struct scatterlist *sgel = NULL;
2785 int numbde;
2786 dma_addr_t busaddr;
2787 struct bsg_job_data *dd_data;
2788 struct ulp_bde64 *bpl = NULL;
2789
2790 /* in case no data is returned return just the return code */
2791 job->reply->reply_payload_rcv_len = 0;
2792
2793 if (job->request_len <
2794 sizeof(struct fc_bsg_request) +
2795 sizeof(struct menlo_command)) {
2796 lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
2797 "2784 Received MENLO_CMD request below "
2798 "minimum size\n");
2799 rc = -ERANGE;
2800 goto no_dd_data;
2801 }
2802
2803 if (job->reply_len <
2804 sizeof(struct fc_bsg_request) + sizeof(struct menlo_response)) {
2805 lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
2806 "2785 Received MENLO_CMD reply below "
2807 "minimum size\n");
2808 rc = -ERANGE;
2809 goto no_dd_data;
2810 }
2811
2812 if (!(phba->menlo_flag & HBA_MENLO_SUPPORT)) {
2813 lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
2814 "2786 Adapter does not support menlo "
2815 "commands\n");
2816 rc = -EPERM;
2817 goto no_dd_data;
2818 }
2819
2820 menlo_cmd = (struct menlo_command *)
2821 job->request->rqst_data.h_vendor.vendor_cmd;
2822
2823 menlo_resp = (struct menlo_response *)
2824 job->reply->reply_data.vendor_reply.vendor_rsp;
2825
2826 /* allocate our bsg tracking structure */
2827 dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
2828 if (!dd_data) {
2829 lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
2830 "2787 Failed allocation of dd_data\n");
2831 rc = -ENOMEM;
2832 goto no_dd_data;
2833 }
2834
2835 bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2836 if (!bmp) {
2837 rc = -ENOMEM;
2838 goto free_dd;
2839 }
2840
2841 cmdiocbq = lpfc_sli_get_iocbq(phba);
2842 if (!cmdiocbq) {
2843 rc = -ENOMEM;
2844 goto free_bmp;
2845 }
2846
2847 rspiocbq = lpfc_sli_get_iocbq(phba);
2848 if (!rspiocbq) {
2849 rc = -ENOMEM;
2850 goto free_cmdiocbq;
2851 }
2852
2853 rsp = &rspiocbq->iocb;
2854
2855 bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
2856 if (!bmp->virt) {
2857 rc = -ENOMEM;
2858 goto free_rspiocbq;
2859 }
2860
2861 INIT_LIST_HEAD(&bmp->list);
2862 bpl = (struct ulp_bde64 *) bmp->virt;
2863 request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list,
2864 job->request_payload.sg_cnt, DMA_TO_DEVICE);
2865 for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) {
2866 busaddr = sg_dma_address(sgel);
2867 bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
2868 bpl->tus.f.bdeSize = sg_dma_len(sgel);
2869 bpl->tus.w = cpu_to_le32(bpl->tus.w);
2870 bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
2871 bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
2872 bpl++;
2873 }
2874
2875 reply_nseg = pci_map_sg(phba->pcidev, job->reply_payload.sg_list,
2876 job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
2877 for_each_sg(job->reply_payload.sg_list, sgel, reply_nseg, numbde) {
2878 busaddr = sg_dma_address(sgel);
2879 bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
2880 bpl->tus.f.bdeSize = sg_dma_len(sgel);
2881 bpl->tus.w = cpu_to_le32(bpl->tus.w);
2882 bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
2883 bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
2884 bpl++;
2885 }
2886
2887 cmd = &cmdiocbq->iocb;
2888 cmd->un.genreq64.bdl.ulpIoTag32 = 0;
2889 cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
2890 cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
2891 cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
2892 cmd->un.genreq64.bdl.bdeSize =
2893 (request_nseg + reply_nseg) * sizeof(struct ulp_bde64);
2894 cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
2895 cmd->un.genreq64.w5.hcsw.Dfctl = 0;
2896 cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CMD;
2897 cmd->un.genreq64.w5.hcsw.Type = MENLO_TRANSPORT_TYPE; /* 0xfe */
2898 cmd->ulpBdeCount = 1;
2899 cmd->ulpClass = CLASS3;
2900 cmd->ulpOwner = OWN_CHIP;
2901 cmd->ulpLe = 1; /* Limited Edition */
2902 cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC;
2903 cmdiocbq->vport = phba->pport;
2904 /* We want the firmware to timeout before we do */
2905 cmd->ulpTimeout = MENLO_TIMEOUT - 5;
2906 cmdiocbq->context3 = bmp;
2907 cmdiocbq->context2 = rspiocbq;
2908 cmdiocbq->iocb_cmpl = lpfc_bsg_menlo_cmd_cmp;
2909 cmdiocbq->context1 = dd_data;
2910 cmdiocbq->context2 = rspiocbq;
2911 if (menlo_cmd->cmd == LPFC_BSG_VENDOR_MENLO_CMD) {
2912 cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
2913 cmd->ulpPU = MENLO_PU; /* 3 */
2914 cmd->un.ulpWord[4] = MENLO_DID; /* 0x0000FC0E */
2915 cmd->ulpContext = MENLO_CONTEXT; /* 0 */
2916 } else {
2917 cmd->ulpCommand = CMD_GEN_REQUEST64_CX;
2918 cmd->ulpPU = 1;
2919 cmd->un.ulpWord[4] = 0;
2920 cmd->ulpContext = menlo_cmd->xri;
2921 }
2922
2923 dd_data->type = TYPE_MENLO;
2924 dd_data->context_un.menlo.cmdiocbq = cmdiocbq;
2925 dd_data->context_un.menlo.rspiocbq = rspiocbq;
2926 dd_data->context_un.menlo.set_job = job;
2927 dd_data->context_un.menlo.bmp = bmp;
2928
2929 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq,
2930 MENLO_TIMEOUT - 5);
2931 if (rc == IOCB_SUCCESS)
2932 return 0; /* done for now */
2933
2934 /* iocb failed so cleanup */
2935 pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
2936 job->request_payload.sg_cnt, DMA_TO_DEVICE);
2937 pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
2938 job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
2939
2940 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
2941
2942free_rspiocbq:
2943 lpfc_sli_release_iocbq(phba, rspiocbq);
2944free_cmdiocbq:
2945 lpfc_sli_release_iocbq(phba, cmdiocbq);
2946free_bmp:
2947 kfree(bmp);
2948free_dd:
2949 kfree(dd_data);
2950no_dd_data:
2951 /* make error code available to userspace */
2952 job->reply->result = rc;
2953 job->dd_data = NULL;
2954 return rc;
2955}
2956/**
2641 * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job 2957 * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
2642 * @job: fc_bsg_job to handle 2958 * @job: fc_bsg_job to handle
2643 **/ 2959 **/
@@ -2669,6 +2985,10 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
2669 case LPFC_BSG_VENDOR_MBOX: 2985 case LPFC_BSG_VENDOR_MBOX:
2670 rc = lpfc_bsg_mbox_cmd(job); 2986 rc = lpfc_bsg_mbox_cmd(job);
2671 break; 2987 break;
2988 case LPFC_BSG_VENDOR_MENLO_CMD:
2989 case LPFC_BSG_VENDOR_MENLO_DATA:
2990 rc = lpfc_menlo_cmd(job);
2991 break;
2672 default: 2992 default:
2673 rc = -EINVAL; 2993 rc = -EINVAL;
2674 job->reply->reply_payload_rcv_len = 0; 2994 job->reply->reply_payload_rcv_len = 0;
@@ -2728,6 +3048,7 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
2728 struct lpfc_bsg_event *evt; 3048 struct lpfc_bsg_event *evt;
2729 struct lpfc_bsg_iocb *iocb; 3049 struct lpfc_bsg_iocb *iocb;
2730 struct lpfc_bsg_mbox *mbox; 3050 struct lpfc_bsg_mbox *mbox;
3051 struct lpfc_bsg_menlo *menlo;
2731 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; 3052 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
2732 struct bsg_job_data *dd_data; 3053 struct bsg_job_data *dd_data;
2733 unsigned long flags; 3054 unsigned long flags;
@@ -2775,6 +3096,17 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
2775 spin_unlock_irqrestore(&phba->ct_ev_lock, flags); 3096 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
2776 job->job_done(job); 3097 job->job_done(job);
2777 break; 3098 break;
3099 case TYPE_MENLO:
3100 menlo = &dd_data->context_un.menlo;
3101 cmdiocb = menlo->cmdiocbq;
3102 /* hint to completion handler that the job timed out */
3103 job->reply->result = -EAGAIN;
3104 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
3105 /* this will call our completion handler */
3106 spin_lock_irq(&phba->hbalock);
3107 lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb);
3108 spin_unlock_irq(&phba->hbalock);
3109 break;
2778 default: 3110 default:
2779 spin_unlock_irqrestore(&phba->ct_ev_lock, flags); 3111 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
2780 break; 3112 break;
diff --git a/drivers/scsi/lpfc/lpfc_bsg.h b/drivers/scsi/lpfc/lpfc_bsg.h
index 6c8f87e39b98..5bc630819b9e 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.h
+++ b/drivers/scsi/lpfc/lpfc_bsg.h
@@ -31,6 +31,8 @@
31#define LPFC_BSG_VENDOR_DIAG_TEST 5 31#define LPFC_BSG_VENDOR_DIAG_TEST 5
32#define LPFC_BSG_VENDOR_GET_MGMT_REV 6 32#define LPFC_BSG_VENDOR_GET_MGMT_REV 6
33#define LPFC_BSG_VENDOR_MBOX 7 33#define LPFC_BSG_VENDOR_MBOX 7
34#define LPFC_BSG_VENDOR_MENLO_CMD 8
35#define LPFC_BSG_VENDOR_MENLO_DATA 9
34 36
35struct set_ct_event { 37struct set_ct_event {
36 uint32_t command; 38 uint32_t command;
@@ -96,3 +98,13 @@ struct dfc_mbox_req {
96 uint8_t mbOffset; 98 uint8_t mbOffset;
97}; 99};
98 100
101/* Used for menlo command or menlo data. The xri is only used for menlo data */
102struct menlo_command {
103 uint32_t cmd;
104 uint32_t xri;
105};
106
107struct menlo_response {
108 uint32_t xri; /* return the xri of the iocb exchange */
109};
110
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 6f0fb51eb461..5087c4211b43 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -63,6 +63,7 @@ void lpfc_linkdown_port(struct lpfc_vport *);
63void lpfc_port_link_failure(struct lpfc_vport *); 63void lpfc_port_link_failure(struct lpfc_vport *);
64void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); 64void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
65void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); 65void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
66void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *);
66void lpfc_retry_pport_discovery(struct lpfc_hba *); 67void lpfc_retry_pport_discovery(struct lpfc_hba *);
67 68
68void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); 69void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -221,6 +222,10 @@ void lpfc_unregister_fcf_rescan(struct lpfc_hba *);
221void lpfc_unregister_unused_fcf(struct lpfc_hba *); 222void lpfc_unregister_unused_fcf(struct lpfc_hba *);
222int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *); 223int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *);
223void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *); 224void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *);
225void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *);
226uint16_t lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *);
227int lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *, uint16_t);
228void lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *, uint16_t);
224 229
225int lpfc_mem_alloc(struct lpfc_hba *, int align); 230int lpfc_mem_alloc(struct lpfc_hba *, int align);
226void lpfc_mem_free(struct lpfc_hba *); 231void lpfc_mem_free(struct lpfc_hba *);
@@ -385,7 +390,7 @@ void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t);
385int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); 390int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
386void lpfc_start_fdiscs(struct lpfc_hba *phba); 391void lpfc_start_fdiscs(struct lpfc_hba *phba);
387struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t); 392struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t);
388 393struct lpfc_sglq *__lpfc_get_active_sglq(struct lpfc_hba *, uint16_t);
389#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) 394#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
390#define HBA_EVENT_RSCN 5 395#define HBA_EVENT_RSCN 5
391#define HBA_EVENT_LINK_UP 2 396#define HBA_EVENT_LINK_UP 2
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 2a40a6eabf4d..ee980bd66869 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -771,6 +771,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
771 struct lpfc_nodelist *ndlp = cmdiocb->context1; 771 struct lpfc_nodelist *ndlp = cmdiocb->context1;
772 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp; 772 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
773 struct serv_parm *sp; 773 struct serv_parm *sp;
774 uint16_t fcf_index;
774 int rc; 775 int rc;
775 776
776 /* Check to see if link went down during discovery */ 777 /* Check to see if link went down during discovery */
@@ -788,6 +789,54 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
788 vport->port_state); 789 vport->port_state);
789 790
790 if (irsp->ulpStatus) { 791 if (irsp->ulpStatus) {
792 /*
793 * In case of FIP mode, perform round robin FCF failover
794 * due to new FCF discovery
795 */
796 if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
797 (phba->fcf.fcf_flag & FCF_DISCOVERY)) {
798 lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
799 "2611 FLOGI failed on registered "
800 "FCF record fcf_index:%d, trying "
801 "to perform round robin failover\n",
802 phba->fcf.current_rec.fcf_indx);
803 fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
804 if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) {
805 /*
806 * Exhausted the eligible FCF record list,
807 * fail through to retry FLOGI on current
808 * FCF record.
809 */
810 lpfc_printf_log(phba, KERN_WARNING,
811 LOG_FIP | LOG_ELS,
812 "2760 FLOGI exhausted FCF "
813 "round robin failover list, "
814 "retry FLOGI on the current "
815 "registered FCF index:%d\n",
816 phba->fcf.current_rec.fcf_indx);
817 spin_lock_irq(&phba->hbalock);
818 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
819 spin_unlock_irq(&phba->hbalock);
820 } else {
821 rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba,
822 fcf_index);
823 if (rc) {
824 lpfc_printf_log(phba, KERN_WARNING,
825 LOG_FIP | LOG_ELS,
826 "2761 FLOGI round "
827 "robin FCF failover "
828 "read FCF failed "
829 "rc:x%x, fcf_index:"
830 "%d\n", rc,
831 phba->fcf.current_rec.fcf_indx);
832 spin_lock_irq(&phba->hbalock);
833 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
834 spin_unlock_irq(&phba->hbalock);
835 } else
836 goto out;
837 }
838 }
839
791 /* Check for retry */ 840 /* Check for retry */
792 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) 841 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
793 goto out; 842 goto out;
@@ -806,9 +855,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
806 } 855 }
807 856
808 /* FLOGI failure */ 857 /* FLOGI failure */
809 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, 858 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
810 "0100 FLOGI failure Data: x%x x%x " 859 "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n",
811 "x%x\n",
812 irsp->ulpStatus, irsp->un.ulpWord[4], 860 irsp->ulpStatus, irsp->un.ulpWord[4],
813 irsp->ulpTimeout); 861 irsp->ulpTimeout);
814 goto flogifail; 862 goto flogifail;
@@ -842,8 +890,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
842 else 890 else
843 rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); 891 rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
844 892
845 if (!rc) 893 if (!rc) {
894 /* Mark the FCF discovery process done */
895 lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS,
896 "2769 FLOGI successful on FCF record: "
897 "current_fcf_index:x%x, terminate FCF "
898 "round robin failover process\n",
899 phba->fcf.current_rec.fcf_indx);
900 spin_lock_irq(&phba->hbalock);
901 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
902 spin_unlock_irq(&phba->hbalock);
846 goto out; 903 goto out;
904 }
847 } 905 }
848 906
849flogifail: 907flogifail:
@@ -1409,6 +1467,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1409 goto out; 1467 goto out;
1410 } 1468 }
1411 /* PLOGI failed */ 1469 /* PLOGI failed */
1470 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1471 "2753 PLOGI failure DID:%06X Status:x%x/x%x\n",
1472 ndlp->nlp_DID, irsp->ulpStatus,
1473 irsp->un.ulpWord[4]);
1412 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 1474 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
1413 if (lpfc_error_lost_link(irsp)) 1475 if (lpfc_error_lost_link(irsp))
1414 rc = NLP_STE_FREED_NODE; 1476 rc = NLP_STE_FREED_NODE;
@@ -1577,6 +1639,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1577 goto out; 1639 goto out;
1578 } 1640 }
1579 /* PRLI failed */ 1641 /* PRLI failed */
1642 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1643 "2754 PRLI failure DID:%06X Status:x%x/x%x\n",
1644 ndlp->nlp_DID, irsp->ulpStatus,
1645 irsp->un.ulpWord[4]);
1580 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 1646 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
1581 if (lpfc_error_lost_link(irsp)) 1647 if (lpfc_error_lost_link(irsp))
1582 goto out; 1648 goto out;
@@ -1860,6 +1926,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1860 goto out; 1926 goto out;
1861 } 1927 }
1862 /* ADISC failed */ 1928 /* ADISC failed */
1929 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1930 "2755 ADISC failure DID:%06X Status:x%x/x%x\n",
1931 ndlp->nlp_DID, irsp->ulpStatus,
1932 irsp->un.ulpWord[4]);
1863 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 1933 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
1864 if (!lpfc_error_lost_link(irsp)) 1934 if (!lpfc_error_lost_link(irsp))
1865 lpfc_disc_state_machine(vport, ndlp, cmdiocb, 1935 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
@@ -2009,6 +2079,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2009 /* ELS command is being retried */ 2079 /* ELS command is being retried */
2010 goto out; 2080 goto out;
2011 /* LOGO failed */ 2081 /* LOGO failed */
2082 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
2083 "2756 LOGO failure DID:%06X Status:x%x/x%x\n",
2084 ndlp->nlp_DID, irsp->ulpStatus,
2085 irsp->un.ulpWord[4]);
2012 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 2086 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
2013 if (lpfc_error_lost_link(irsp)) 2087 if (lpfc_error_lost_link(irsp))
2014 goto out; 2088 goto out;
@@ -5989,7 +6063,12 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5989 if (phba->sli_rev < LPFC_SLI_REV4) 6063 if (phba->sli_rev < LPFC_SLI_REV4)
5990 lpfc_issue_fabric_reglogin(vport); 6064 lpfc_issue_fabric_reglogin(vport);
5991 else { 6065 else {
5992 lpfc_start_fdiscs(phba); 6066 /*
6067 * If the physical port is instantiated using
6068 * FDISC, do not start vport discovery.
6069 */
6070 if (vport->port_state != LPFC_FDISC)
6071 lpfc_start_fdiscs(phba);
5993 lpfc_do_scr_ns_plogi(phba, vport); 6072 lpfc_do_scr_ns_plogi(phba, vport);
5994 } 6073 }
5995 } else 6074 } else
@@ -6055,21 +6134,18 @@ mbox_err_exit:
6055} 6134}
6056 6135
6057/** 6136/**
6058 * lpfc_retry_pport_discovery - Start timer to retry FLOGI. 6137 * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer
6059 * @phba: pointer to lpfc hba data structure. 6138 * @phba: pointer to lpfc hba data structure.
6060 * 6139 *
6061 * This routine abort all pending discovery commands and 6140 * This routine cancels the retry delay timers to all the vports.
6062 * start a timer to retry FLOGI for the physical port
6063 * discovery.
6064 **/ 6141 **/
6065void 6142void
6066lpfc_retry_pport_discovery(struct lpfc_hba *phba) 6143lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba)
6067{ 6144{
6068 struct lpfc_vport **vports; 6145 struct lpfc_vport **vports;
6069 struct lpfc_nodelist *ndlp; 6146 struct lpfc_nodelist *ndlp;
6070 struct Scsi_Host *shost;
6071 int i;
6072 uint32_t link_state; 6147 uint32_t link_state;
6148 int i;
6073 6149
6074 /* Treat this failure as linkdown for all vports */ 6150 /* Treat this failure as linkdown for all vports */
6075 link_state = phba->link_state; 6151 link_state = phba->link_state;
@@ -6087,13 +6163,30 @@ lpfc_retry_pport_discovery(struct lpfc_hba *phba)
6087 } 6163 }
6088 lpfc_destroy_vport_work_array(phba, vports); 6164 lpfc_destroy_vport_work_array(phba, vports);
6089 } 6165 }
6166}
6167
6168/**
6169 * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
6170 * @phba: pointer to lpfc hba data structure.
6171 *
6172 * This routine abort all pending discovery commands and
6173 * start a timer to retry FLOGI for the physical port
6174 * discovery.
6175 **/
6176void
6177lpfc_retry_pport_discovery(struct lpfc_hba *phba)
6178{
6179 struct lpfc_nodelist *ndlp;
6180 struct Scsi_Host *shost;
6181
6182 /* Cancel the all vports retry delay retry timers */
6183 lpfc_cancel_all_vport_retry_delay_timer(phba);
6090 6184
6091 /* If fabric require FLOGI, then re-instantiate physical login */ 6185 /* If fabric require FLOGI, then re-instantiate physical login */
6092 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); 6186 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
6093 if (!ndlp) 6187 if (!ndlp)
6094 return; 6188 return;
6095 6189
6096
6097 shost = lpfc_shost_from_vport(phba->pport); 6190 shost = lpfc_shost_from_vport(phba->pport);
6098 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); 6191 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
6099 spin_lock_irq(shost->host_lock); 6192 spin_lock_irq(shost->host_lock);
@@ -6219,7 +6312,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6219 lpfc_mbx_unreg_vpi(vport); 6312 lpfc_mbx_unreg_vpi(vport);
6220 spin_lock_irq(shost->host_lock); 6313 spin_lock_irq(shost->host_lock);
6221 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 6314 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
6222 vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; 6315 if (phba->sli_rev == LPFC_SLI_REV4)
6316 vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
6223 spin_unlock_irq(shost->host_lock); 6317 spin_unlock_irq(shost->host_lock);
6224 } 6318 }
6225 6319
@@ -6797,21 +6891,27 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
6797 struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; 6891 struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
6798 unsigned long iflag = 0; 6892 unsigned long iflag = 0;
6799 6893
6800 spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag); 6894 spin_lock_irqsave(&phba->hbalock, iflag);
6895 spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
6801 list_for_each_entry_safe(sglq_entry, sglq_next, 6896 list_for_each_entry_safe(sglq_entry, sglq_next,
6802 &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { 6897 &phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
6803 if (sglq_entry->sli4_xritag == xri) { 6898 if (sglq_entry->sli4_xritag == xri) {
6804 list_del(&sglq_entry->list); 6899 list_del(&sglq_entry->list);
6805 spin_unlock_irqrestore(
6806 &phba->sli4_hba.abts_sgl_list_lock,
6807 iflag);
6808 spin_lock_irqsave(&phba->hbalock, iflag);
6809
6810 list_add_tail(&sglq_entry->list, 6900 list_add_tail(&sglq_entry->list,
6811 &phba->sli4_hba.lpfc_sgl_list); 6901 &phba->sli4_hba.lpfc_sgl_list);
6902 sglq_entry->state = SGL_FREED;
6903 spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
6812 spin_unlock_irqrestore(&phba->hbalock, iflag); 6904 spin_unlock_irqrestore(&phba->hbalock, iflag);
6813 return; 6905 return;
6814 } 6906 }
6815 } 6907 }
6816 spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag); 6908 spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
6909 sglq_entry = __lpfc_get_active_sglq(phba, xri);
6910 if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) {
6911 spin_unlock_irqrestore(&phba->hbalock, iflag);
6912 return;
6913 }
6914 sglq_entry->state = SGL_XRI_ABORTED;
6915 spin_unlock_irqrestore(&phba->hbalock, iflag);
6916 return;
6817} 6917}
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 2359d0bfb734..c555e3b7f202 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1481,8 +1481,6 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
1481int 1481int
1482lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) 1482lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
1483{ 1483{
1484 LPFC_MBOXQ_t *mbox;
1485 int rc;
1486 /* 1484 /*
1487 * If the Link is up and no FCoE events while in the 1485 * If the Link is up and no FCoE events while in the
1488 * FCF discovery, no need to restart FCF discovery. 1486 * FCF discovery, no need to restart FCF discovery.
@@ -1491,86 +1489,70 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
1491 (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan)) 1489 (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan))
1492 return 0; 1490 return 0;
1493 1491
1492 lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
1493 "2768 Pending link or FCF event during current "
1494 "handling of the previous event: link_state:x%x, "
1495 "evt_tag_at_scan:x%x, evt_tag_current:x%x\n",
1496 phba->link_state, phba->fcoe_eventtag_at_fcf_scan,
1497 phba->fcoe_eventtag);
1498
1494 spin_lock_irq(&phba->hbalock); 1499 spin_lock_irq(&phba->hbalock);
1495 phba->fcf.fcf_flag &= ~FCF_AVAILABLE; 1500 phba->fcf.fcf_flag &= ~FCF_AVAILABLE;
1496 spin_unlock_irq(&phba->hbalock); 1501 spin_unlock_irq(&phba->hbalock);
1497 1502
1498 if (phba->link_state >= LPFC_LINK_UP) 1503 if (phba->link_state >= LPFC_LINK_UP) {
1499 lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); 1504 lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
1500 else { 1505 "2780 Restart FCF table scan due to "
1506 "pending FCF event:evt_tag_at_scan:x%x, "
1507 "evt_tag_current:x%x\n",
1508 phba->fcoe_eventtag_at_fcf_scan,
1509 phba->fcoe_eventtag);
1510 lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
1511 } else {
1501 /* 1512 /*
1502 * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS 1513 * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS
1503 * flag 1514 * flag
1504 */ 1515 */
1505 spin_lock_irq(&phba->hbalock); 1516 spin_lock_irq(&phba->hbalock);
1506 phba->hba_flag &= ~FCF_DISC_INPROGRESS; 1517 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1507 phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; 1518 phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | FCF_DISCOVERY);
1508 spin_unlock_irq(&phba->hbalock); 1519 spin_unlock_irq(&phba->hbalock);
1509 } 1520 }
1510 1521
1522 /* Unregister the currently registered FCF if required */
1511 if (unreg_fcf) { 1523 if (unreg_fcf) {
1512 spin_lock_irq(&phba->hbalock); 1524 spin_lock_irq(&phba->hbalock);
1513 phba->fcf.fcf_flag &= ~FCF_REGISTERED; 1525 phba->fcf.fcf_flag &= ~FCF_REGISTERED;
1514 spin_unlock_irq(&phba->hbalock); 1526 spin_unlock_irq(&phba->hbalock);
1515 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 1527 lpfc_sli4_unregister_fcf(phba);
1516 if (!mbox) {
1517 lpfc_printf_log(phba, KERN_ERR,
1518 LOG_DISCOVERY|LOG_MBOX,
1519 "2610 UNREG_FCFI mbox allocation failed\n");
1520 return 1;
1521 }
1522 lpfc_unreg_fcfi(mbox, phba->fcf.fcfi);
1523 mbox->vport = phba->pport;
1524 mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl;
1525 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
1526 if (rc == MBX_NOT_FINISHED) {
1527 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
1528 "2611 UNREG_FCFI issue mbox failed\n");
1529 mempool_free(mbox, phba->mbox_mem_pool);
1530 }
1531 } 1528 }
1532
1533 return 1; 1529 return 1;
1534} 1530}
1535 1531
1536/** 1532/**
1537 * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox. 1533 * lpfc_sli4_fcf_rec_mbox_parse - parse non-embedded fcf record mailbox command
1538 * @phba: pointer to lpfc hba data structure. 1534 * @phba: pointer to lpfc hba data structure.
1539 * @mboxq: pointer to mailbox object. 1535 * @mboxq: pointer to mailbox object.
1536 * @next_fcf_index: pointer to holder of next fcf index.
1540 * 1537 *
1541 * This function iterate through all the fcf records available in 1538 * This routine parses the non-embedded fcf mailbox command by performing the
1542 * HBA and choose the optimal FCF record for discovery. After finding 1539 * necessarily error checking, non-embedded read FCF record mailbox command
1543 * the FCF for discovery it register the FCF record and kick start 1540 * SGE parsing, and endianness swapping.
1544 * discovery. 1541 *
1545 * If FCF_IN_USE flag is set in currently used FCF, the routine try to 1542 * Returns the pointer to the new FCF record in the non-embedded mailbox
1546 * use a FCF record which match fabric name and mac address of the 1543 * command DMA memory if successfully, other NULL.
1547 * currently used FCF record.
1548 * If the driver support only one FCF, it will try to use the FCF record
1549 * used by BOOT_BIOS.
1550 */ 1544 */
1551void 1545static struct fcf_record *
1552lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) 1546lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
1547 uint16_t *next_fcf_index)
1553{ 1548{
1554 void *virt_addr; 1549 void *virt_addr;
1555 dma_addr_t phys_addr; 1550 dma_addr_t phys_addr;
1556 uint8_t *bytep;
1557 struct lpfc_mbx_sge sge; 1551 struct lpfc_mbx_sge sge;
1558 struct lpfc_mbx_read_fcf_tbl *read_fcf; 1552 struct lpfc_mbx_read_fcf_tbl *read_fcf;
1559 uint32_t shdr_status, shdr_add_status; 1553 uint32_t shdr_status, shdr_add_status;
1560 union lpfc_sli4_cfg_shdr *shdr; 1554 union lpfc_sli4_cfg_shdr *shdr;
1561 struct fcf_record *new_fcf_record; 1555 struct fcf_record *new_fcf_record;
1562 uint32_t boot_flag, addr_mode;
1563 uint32_t next_fcf_index;
1564 struct lpfc_fcf_rec *fcf_rec = NULL;
1565 unsigned long iflags;
1566 uint16_t vlan_id;
1567 int rc;
1568
1569 /* If there is pending FCoE event restart FCF table scan */
1570 if (lpfc_check_pending_fcoe_event(phba, 0)) {
1571 lpfc_sli4_mbox_cmd_free(phba, mboxq);
1572 return;
1573 }
1574 1556
1575 /* Get the first SGE entry from the non-embedded DMA memory. This 1557 /* Get the first SGE entry from the non-embedded DMA memory. This
1576 * routine only uses a single SGE. 1558 * routine only uses a single SGE.
@@ -1581,59 +1563,183 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1581 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, 1563 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1582 "2524 Failed to get the non-embedded SGE " 1564 "2524 Failed to get the non-embedded SGE "
1583 "virtual address\n"); 1565 "virtual address\n");
1584 goto out; 1566 return NULL;
1585 } 1567 }
1586 virt_addr = mboxq->sge_array->addr[0]; 1568 virt_addr = mboxq->sge_array->addr[0];
1587 1569
1588 shdr = (union lpfc_sli4_cfg_shdr *)virt_addr; 1570 shdr = (union lpfc_sli4_cfg_shdr *)virt_addr;
1589 shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); 1571 shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
1590 shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, 1572 shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
1591 &shdr->response);
1592 /*
1593 * The FCF Record was read and there is no reason for the driver
1594 * to maintain the FCF record data or memory. Instead, just need
1595 * to book keeping the FCFIs can be used.
1596 */
1597 if (shdr_status || shdr_add_status) { 1573 if (shdr_status || shdr_add_status) {
1598 if (shdr_status == STATUS_FCF_TABLE_EMPTY) { 1574 if (shdr_status == STATUS_FCF_TABLE_EMPTY)
1599 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 1575 lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
1600 "2726 READ_FCF_RECORD Indicates empty " 1576 "2726 READ_FCF_RECORD Indicates empty "
1601 "FCF table.\n"); 1577 "FCF table.\n");
1602 } else { 1578 else
1603 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 1579 lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
1604 "2521 READ_FCF_RECORD mailbox failed " 1580 "2521 READ_FCF_RECORD mailbox failed "
1605 "with status x%x add_status x%x, mbx\n", 1581 "with status x%x add_status x%x, "
1606 shdr_status, shdr_add_status); 1582 "mbx\n", shdr_status, shdr_add_status);
1607 } 1583 return NULL;
1608 goto out;
1609 } 1584 }
1610 /* Interpreting the returned information of FCF records */ 1585
1586 /* Interpreting the returned information of the FCF record */
1611 read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; 1587 read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr;
1612 lpfc_sli_pcimem_bcopy(read_fcf, read_fcf, 1588 lpfc_sli_pcimem_bcopy(read_fcf, read_fcf,
1613 sizeof(struct lpfc_mbx_read_fcf_tbl)); 1589 sizeof(struct lpfc_mbx_read_fcf_tbl));
1614 next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf); 1590 *next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf);
1615
1616 new_fcf_record = (struct fcf_record *)(virt_addr + 1591 new_fcf_record = (struct fcf_record *)(virt_addr +
1617 sizeof(struct lpfc_mbx_read_fcf_tbl)); 1592 sizeof(struct lpfc_mbx_read_fcf_tbl));
1618 lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, 1593 lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record,
1619 sizeof(struct fcf_record)); 1594 sizeof(struct fcf_record));
1620 bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr);
1621 1595
1596 return new_fcf_record;
1597}
1598
1599/**
1600 * lpfc_sli4_log_fcf_record_info - Log the information of a fcf record
1601 * @phba: pointer to lpfc hba data structure.
1602 * @fcf_record: pointer to the fcf record.
1603 * @vlan_id: the lowest vlan identifier associated to this fcf record.
1604 * @next_fcf_index: the index to the next fcf record in hba's fcf table.
1605 *
1606 * This routine logs the detailed FCF record if the LOG_FIP loggin is
1607 * enabled.
1608 **/
1609static void
1610lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba,
1611 struct fcf_record *fcf_record,
1612 uint16_t vlan_id,
1613 uint16_t next_fcf_index)
1614{
1615 lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
1616 "2764 READ_FCF_RECORD:\n"
1617 "\tFCF_Index : x%x\n"
1618 "\tFCF_Avail : x%x\n"
1619 "\tFCF_Valid : x%x\n"
1620 "\tFIP_Priority : x%x\n"
1621 "\tMAC_Provider : x%x\n"
1622 "\tLowest VLANID : x%x\n"
1623 "\tFCF_MAC Addr : x%x:%x:%x:%x:%x:%x\n"
1624 "\tFabric_Name : x%x:%x:%x:%x:%x:%x:%x:%x\n"
1625 "\tSwitch_Name : x%x:%x:%x:%x:%x:%x:%x:%x\n"
1626 "\tNext_FCF_Index: x%x\n",
1627 bf_get(lpfc_fcf_record_fcf_index, fcf_record),
1628 bf_get(lpfc_fcf_record_fcf_avail, fcf_record),
1629 bf_get(lpfc_fcf_record_fcf_valid, fcf_record),
1630 fcf_record->fip_priority,
1631 bf_get(lpfc_fcf_record_mac_addr_prov, fcf_record),
1632 vlan_id,
1633 bf_get(lpfc_fcf_record_mac_0, fcf_record),
1634 bf_get(lpfc_fcf_record_mac_1, fcf_record),
1635 bf_get(lpfc_fcf_record_mac_2, fcf_record),
1636 bf_get(lpfc_fcf_record_mac_3, fcf_record),
1637 bf_get(lpfc_fcf_record_mac_4, fcf_record),
1638 bf_get(lpfc_fcf_record_mac_5, fcf_record),
1639 bf_get(lpfc_fcf_record_fab_name_0, fcf_record),
1640 bf_get(lpfc_fcf_record_fab_name_1, fcf_record),
1641 bf_get(lpfc_fcf_record_fab_name_2, fcf_record),
1642 bf_get(lpfc_fcf_record_fab_name_3, fcf_record),
1643 bf_get(lpfc_fcf_record_fab_name_4, fcf_record),
1644 bf_get(lpfc_fcf_record_fab_name_5, fcf_record),
1645 bf_get(lpfc_fcf_record_fab_name_6, fcf_record),
1646 bf_get(lpfc_fcf_record_fab_name_7, fcf_record),
1647 bf_get(lpfc_fcf_record_switch_name_0, fcf_record),
1648 bf_get(lpfc_fcf_record_switch_name_1, fcf_record),
1649 bf_get(lpfc_fcf_record_switch_name_2, fcf_record),
1650 bf_get(lpfc_fcf_record_switch_name_3, fcf_record),
1651 bf_get(lpfc_fcf_record_switch_name_4, fcf_record),
1652 bf_get(lpfc_fcf_record_switch_name_5, fcf_record),
1653 bf_get(lpfc_fcf_record_switch_name_6, fcf_record),
1654 bf_get(lpfc_fcf_record_switch_name_7, fcf_record),
1655 next_fcf_index);
1656}
1657
1658/**
1659 * lpfc_mbx_cmpl_fcf_scan_read_fcf_rec - fcf scan read_fcf mbox cmpl handler.
1660 * @phba: pointer to lpfc hba data structure.
1661 * @mboxq: pointer to mailbox object.
1662 *
1663 * This function iterates through all the fcf records available in
1664 * HBA and chooses the optimal FCF record for discovery. After finding
1665 * the FCF for discovery it registers the FCF record and kicks start
1666 * discovery.
1667 * If FCF_IN_USE flag is set in currently used FCF, the routine tries to
1668 * use an FCF record which matches fabric name and mac address of the
1669 * currently used FCF record.
1670 * If the driver supports only one FCF, it will try to use the FCF record
1671 * used by BOOT_BIOS.
1672 */
1673void
1674lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1675{
1676 struct fcf_record *new_fcf_record;
1677 uint32_t boot_flag, addr_mode;
1678 uint16_t fcf_index, next_fcf_index;
1679 struct lpfc_fcf_rec *fcf_rec = NULL;
1680 uint16_t vlan_id;
1681 int rc;
1682
1683 /* If there is pending FCoE event restart FCF table scan */
1684 if (lpfc_check_pending_fcoe_event(phba, 0)) {
1685 lpfc_sli4_mbox_cmd_free(phba, mboxq);
1686 return;
1687 }
1688
1689 /* Parse the FCF record from the non-embedded mailbox command */
1690 new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
1691 &next_fcf_index);
1692 if (!new_fcf_record) {
1693 lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
1694 "2765 Mailbox command READ_FCF_RECORD "
1695 "failed to retrieve a FCF record.\n");
1696 /* Let next new FCF event trigger fast failover */
1697 spin_lock_irq(&phba->hbalock);
1698 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1699 spin_unlock_irq(&phba->hbalock);
1700 lpfc_sli4_mbox_cmd_free(phba, mboxq);
1701 return;
1702 }
1703
1704 /* Check the FCF record against the connection list */
1622 rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, 1705 rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
1623 &addr_mode, &vlan_id); 1706 &addr_mode, &vlan_id);
1707
1708 /* Log the FCF record information if turned on */
1709 lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
1710 next_fcf_index);
1711
1624 /* 1712 /*
1625 * If the fcf record does not match with connect list entries 1713 * If the fcf record does not match with connect list entries
1626 * read the next entry. 1714 * read the next entry; otherwise, this is an eligible FCF
1715 * record for round robin FCF failover.
1627 */ 1716 */
1628 if (!rc) 1717 if (!rc) {
1718 lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
1719 "2781 FCF record fcf_index:x%x failed FCF "
1720 "connection list check, fcf_avail:x%x, "
1721 "fcf_valid:x%x\n",
1722 bf_get(lpfc_fcf_record_fcf_index,
1723 new_fcf_record),
1724 bf_get(lpfc_fcf_record_fcf_avail,
1725 new_fcf_record),
1726 bf_get(lpfc_fcf_record_fcf_valid,
1727 new_fcf_record));
1629 goto read_next_fcf; 1728 goto read_next_fcf;
1729 } else {
1730 fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
1731 rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index);
1732 if (rc)
1733 goto read_next_fcf;
1734 }
1735
1630 /* 1736 /*
1631 * If this is not the first FCF discovery of the HBA, use last 1737 * If this is not the first FCF discovery of the HBA, use last
1632 * FCF record for the discovery. The condition that a rescan 1738 * FCF record for the discovery. The condition that a rescan
1633 * matches the in-use FCF record: fabric name, switch name, mac 1739 * matches the in-use FCF record: fabric name, switch name, mac
1634 * address, and vlan_id. 1740 * address, and vlan_id.
1635 */ 1741 */
1636 spin_lock_irqsave(&phba->hbalock, iflags); 1742 spin_lock_irq(&phba->hbalock);
1637 if (phba->fcf.fcf_flag & FCF_IN_USE) { 1743 if (phba->fcf.fcf_flag & FCF_IN_USE) {
1638 if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, 1744 if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name,
1639 new_fcf_record) && 1745 new_fcf_record) &&
@@ -1649,8 +1755,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1649 __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); 1755 __lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
1650 else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) 1756 else if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
1651 /* If in fast failover, mark it's completed */ 1757 /* If in fast failover, mark it's completed */
1652 phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; 1758 phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV |
1653 spin_unlock_irqrestore(&phba->hbalock, iflags); 1759 FCF_DISCOVERY);
1760 spin_unlock_irq(&phba->hbalock);
1654 goto out; 1761 goto out;
1655 } 1762 }
1656 /* 1763 /*
@@ -1661,7 +1768,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1661 * next candidate. 1768 * next candidate.
1662 */ 1769 */
1663 if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { 1770 if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) {
1664 spin_unlock_irqrestore(&phba->hbalock, iflags); 1771 spin_unlock_irq(&phba->hbalock);
1665 goto read_next_fcf; 1772 goto read_next_fcf;
1666 } 1773 }
1667 } 1774 }
@@ -1669,14 +1776,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1669 * Update on failover FCF record only if it's in FCF fast-failover 1776 * Update on failover FCF record only if it's in FCF fast-failover
1670 * period; otherwise, update on current FCF record. 1777 * period; otherwise, update on current FCF record.
1671 */ 1778 */
1672 if (phba->fcf.fcf_flag & FCF_REDISC_FOV) { 1779 if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
1673 /* Fast FCF failover only to the same fabric name */ 1780 fcf_rec = &phba->fcf.failover_rec;
1674 if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, 1781 else
1675 new_fcf_record))
1676 fcf_rec = &phba->fcf.failover_rec;
1677 else
1678 goto read_next_fcf;
1679 } else
1680 fcf_rec = &phba->fcf.current_rec; 1782 fcf_rec = &phba->fcf.current_rec;
1681 1783
1682 if (phba->fcf.fcf_flag & FCF_AVAILABLE) { 1784 if (phba->fcf.fcf_flag & FCF_AVAILABLE) {
@@ -1689,7 +1791,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1689 /* Choose this FCF record */ 1791 /* Choose this FCF record */
1690 __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, 1792 __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record,
1691 addr_mode, vlan_id, BOOT_ENABLE); 1793 addr_mode, vlan_id, BOOT_ENABLE);
1692 spin_unlock_irqrestore(&phba->hbalock, iflags); 1794 spin_unlock_irq(&phba->hbalock);
1693 goto read_next_fcf; 1795 goto read_next_fcf;
1694 } 1796 }
1695 /* 1797 /*
@@ -1698,20 +1800,19 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1698 * the next FCF record. 1800 * the next FCF record.
1699 */ 1801 */
1700 if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) { 1802 if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) {
1701 spin_unlock_irqrestore(&phba->hbalock, iflags); 1803 spin_unlock_irq(&phba->hbalock);
1702 goto read_next_fcf; 1804 goto read_next_fcf;
1703 } 1805 }
1704 /* 1806 /*
1705 * If the new hba FCF record has lower priority value 1807 * If the new hba FCF record has lower priority value
1706 * than the driver FCF record, use the new record. 1808 * than the driver FCF record, use the new record.
1707 */ 1809 */
1708 if (lpfc_fab_name_match(fcf_rec->fabric_name, new_fcf_record) && 1810 if (new_fcf_record->fip_priority < fcf_rec->priority) {
1709 (new_fcf_record->fip_priority < fcf_rec->priority)) {
1710 /* Choose this FCF record */ 1811 /* Choose this FCF record */
1711 __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, 1812 __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record,
1712 addr_mode, vlan_id, 0); 1813 addr_mode, vlan_id, 0);
1713 } 1814 }
1714 spin_unlock_irqrestore(&phba->hbalock, iflags); 1815 spin_unlock_irq(&phba->hbalock);
1715 goto read_next_fcf; 1816 goto read_next_fcf;
1716 } 1817 }
1717 /* 1818 /*
@@ -1724,7 +1825,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1724 BOOT_ENABLE : 0)); 1825 BOOT_ENABLE : 0));
1725 phba->fcf.fcf_flag |= FCF_AVAILABLE; 1826 phba->fcf.fcf_flag |= FCF_AVAILABLE;
1726 } 1827 }
1727 spin_unlock_irqrestore(&phba->hbalock, iflags); 1828 spin_unlock_irq(&phba->hbalock);
1728 goto read_next_fcf; 1829 goto read_next_fcf;
1729 1830
1730read_next_fcf: 1831read_next_fcf:
@@ -1740,9 +1841,22 @@ read_next_fcf:
1740 * FCF scan inprogress, and do nothing 1841 * FCF scan inprogress, and do nothing
1741 */ 1842 */
1742 if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) { 1843 if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) {
1743 spin_lock_irqsave(&phba->hbalock, iflags); 1844 lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
1845 "2782 No suitable FCF record "
1846 "found during this round of "
1847 "post FCF rediscovery scan: "
1848 "fcf_evt_tag:x%x, fcf_index: "
1849 "x%x\n",
1850 phba->fcoe_eventtag_at_fcf_scan,
1851 bf_get(lpfc_fcf_record_fcf_index,
1852 new_fcf_record));
1853 /*
1854 * Let next new FCF event trigger fast
1855 * failover
1856 */
1857 spin_lock_irq(&phba->hbalock);
1744 phba->hba_flag &= ~FCF_DISC_INPROGRESS; 1858 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1745 spin_unlock_irqrestore(&phba->hbalock, iflags); 1859 spin_unlock_irq(&phba->hbalock);
1746 return; 1860 return;
1747 } 1861 }
1748 /* 1862 /*
@@ -1754,16 +1868,23 @@ read_next_fcf:
1754 * record. 1868 * record.
1755 */ 1869 */
1756 1870
1757 /* unregister the current in-use FCF record */ 1871 /* Unregister the current in-use FCF record */
1758 lpfc_unregister_fcf(phba); 1872 lpfc_unregister_fcf(phba);
1759 /* replace in-use record with the new record */ 1873
1874 /* Replace in-use record with the new record */
1760 memcpy(&phba->fcf.current_rec, 1875 memcpy(&phba->fcf.current_rec,
1761 &phba->fcf.failover_rec, 1876 &phba->fcf.failover_rec,
1762 sizeof(struct lpfc_fcf_rec)); 1877 sizeof(struct lpfc_fcf_rec));
1763 /* mark the FCF fast failover completed */ 1878 /* mark the FCF fast failover completed */
1764 spin_lock_irqsave(&phba->hbalock, iflags); 1879 spin_lock_irq(&phba->hbalock);
1765 phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; 1880 phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
1766 spin_unlock_irqrestore(&phba->hbalock, iflags); 1881 spin_unlock_irq(&phba->hbalock);
1882 /*
1883 * Set up the initial registered FCF index for FLOGI
1884 * round robin FCF failover.
1885 */
1886 phba->fcf.fcf_rr_init_indx =
1887 phba->fcf.failover_rec.fcf_indx;
1767 /* Register to the new FCF record */ 1888 /* Register to the new FCF record */
1768 lpfc_register_fcf(phba); 1889 lpfc_register_fcf(phba);
1769 } else { 1890 } else {
@@ -1776,13 +1897,25 @@ read_next_fcf:
1776 return; 1897 return;
1777 /* 1898 /*
1778 * Otherwise, initial scan or post linkdown rescan, 1899 * Otherwise, initial scan or post linkdown rescan,
1779 * register with the best fit FCF record found so 1900 * register with the best FCF record found so far
1780 * far through the scanning process. 1901 * through the FCF scanning process.
1902 */
1903
1904 /* mark the initial FCF discovery completed */
1905 spin_lock_irq(&phba->hbalock);
1906 phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
1907 spin_unlock_irq(&phba->hbalock);
1908 /*
1909 * Set up the initial registered FCF index for FLOGI
1910 * round robin FCF failover
1781 */ 1911 */
1912 phba->fcf.fcf_rr_init_indx =
1913 phba->fcf.current_rec.fcf_indx;
1914 /* Register to the new FCF record */
1782 lpfc_register_fcf(phba); 1915 lpfc_register_fcf(phba);
1783 } 1916 }
1784 } else 1917 } else
1785 lpfc_sli4_read_fcf_record(phba, next_fcf_index); 1918 lpfc_sli4_fcf_scan_read_fcf_rec(phba, next_fcf_index);
1786 return; 1919 return;
1787 1920
1788out: 1921out:
@@ -1793,6 +1926,141 @@ out:
1793} 1926}
1794 1927
1795/** 1928/**
1929 * lpfc_mbx_cmpl_fcf_rr_read_fcf_rec - fcf round robin read_fcf mbox cmpl hdler
1930 * @phba: pointer to lpfc hba data structure.
1931 * @mboxq: pointer to mailbox object.
1932 *
1933 * This is the callback function for FLOGI failure round robin FCF failover
1934 * read FCF record mailbox command from the eligible FCF record bmask for
1935 * performing the failover. If the FCF read back is not valid/available, it
1936 * fails through to retrying FLOGI to the currently registered FCF again.
1937 * Otherwise, if the FCF read back is valid and available, it will set the
1938 * newly read FCF record to the failover FCF record, unregister currently
1939 * registered FCF record, copy the failover FCF record to the current
1940 * FCF record, and then register the current FCF record before proceeding
1941 * to trying FLOGI on the new failover FCF.
1942 */
1943void
1944lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1945{
1946 struct fcf_record *new_fcf_record;
1947 uint32_t boot_flag, addr_mode;
1948 uint16_t next_fcf_index;
1949 uint16_t current_fcf_index;
1950 uint16_t vlan_id;
1951
1952 /* If link state is not up, stop the round robin failover process */
1953 if (phba->link_state < LPFC_LINK_UP) {
1954 spin_lock_irq(&phba->hbalock);
1955 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
1956 spin_unlock_irq(&phba->hbalock);
1957 lpfc_sli4_mbox_cmd_free(phba, mboxq);
1958 return;
1959 }
1960
1961 /* Parse the FCF record from the non-embedded mailbox command */
1962 new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
1963 &next_fcf_index);
1964 if (!new_fcf_record) {
1965 lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
1966 "2766 Mailbox command READ_FCF_RECORD "
1967 "failed to retrieve a FCF record.\n");
1968 goto out;
1969 }
1970
1971 /* Get the needed parameters from FCF record */
1972 lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
1973 &addr_mode, &vlan_id);
1974
1975 /* Log the FCF record information if turned on */
1976 lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
1977 next_fcf_index);
1978
1979 /* Upload new FCF record to the failover FCF record */
1980 spin_lock_irq(&phba->hbalock);
1981 __lpfc_update_fcf_record(phba, &phba->fcf.failover_rec,
1982 new_fcf_record, addr_mode, vlan_id,
1983 (boot_flag ? BOOT_ENABLE : 0));
1984 spin_unlock_irq(&phba->hbalock);
1985
1986 current_fcf_index = phba->fcf.current_rec.fcf_indx;
1987
1988 /* Unregister the current in-use FCF record */
1989 lpfc_unregister_fcf(phba);
1990
1991 /* Replace in-use record with the new record */
1992 memcpy(&phba->fcf.current_rec, &phba->fcf.failover_rec,
1993 sizeof(struct lpfc_fcf_rec));
1994
1995 lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
1996 "2783 FLOGI round robin FCF failover from FCF "
1997 "(index:x%x) to FCF (index:x%x).\n",
1998 current_fcf_index,
1999 bf_get(lpfc_fcf_record_fcf_index, new_fcf_record));
2000
2001out:
2002 lpfc_sli4_mbox_cmd_free(phba, mboxq);
2003 lpfc_register_fcf(phba);
2004}
2005
2006/**
2007 * lpfc_mbx_cmpl_read_fcf_rec - read fcf completion handler.
2008 * @phba: pointer to lpfc hba data structure.
2009 * @mboxq: pointer to mailbox object.
2010 *
2011 * This is the callback function of read FCF record mailbox command for
2012 * updating the eligible FCF bmask for FLOGI failure round robin FCF
2013 * failover when a new FCF event happened. If the FCF read back is
2014 * valid/available and it passes the connection list check, it updates
2015 * the bmask for the eligible FCF record for round robin failover.
2016 */
2017void
2018lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
2019{
2020 struct fcf_record *new_fcf_record;
2021 uint32_t boot_flag, addr_mode;
2022 uint16_t fcf_index, next_fcf_index;
2023 uint16_t vlan_id;
2024 int rc;
2025
2026 /* If link state is not up, no need to proceed */
2027 if (phba->link_state < LPFC_LINK_UP)
2028 goto out;
2029
2030 /* If FCF discovery period is over, no need to proceed */
2031 if (phba->fcf.fcf_flag & FCF_DISCOVERY)
2032 goto out;
2033
2034 /* Parse the FCF record from the non-embedded mailbox command */
2035 new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
2036 &next_fcf_index);
2037 if (!new_fcf_record) {
2038 lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
2039 "2767 Mailbox command READ_FCF_RECORD "
2040 "failed to retrieve a FCF record.\n");
2041 goto out;
2042 }
2043
2044 /* Check the connection list for eligibility */
2045 rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
2046 &addr_mode, &vlan_id);
2047
2048 /* Log the FCF record information if turned on */
2049 lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
2050 next_fcf_index);
2051
2052 if (!rc)
2053 goto out;
2054
2055 /* Update the eligible FCF record index bmask */
2056 fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
2057 rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index);
2058
2059out:
2060 lpfc_sli4_mbox_cmd_free(phba, mboxq);
2061}
2062
2063/**
1796 * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command. 2064 * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command.
1797 * @phba: pointer to lpfc hba data structure. 2065 * @phba: pointer to lpfc hba data structure.
1798 * @mboxq: pointer to mailbox data structure. 2066 * @mboxq: pointer to mailbox data structure.
@@ -2024,8 +2292,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
2024 int rc; 2292 int rc;
2025 struct fcf_record *fcf_record; 2293 struct fcf_record *fcf_record;
2026 2294
2027 sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2028
2029 spin_lock_irq(&phba->hbalock); 2295 spin_lock_irq(&phba->hbalock);
2030 switch (la->UlnkSpeed) { 2296 switch (la->UlnkSpeed) {
2031 case LA_1GHZ_LINK: 2297 case LA_1GHZ_LINK:
@@ -2117,18 +2383,24 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
2117 spin_unlock_irq(&phba->hbalock); 2383 spin_unlock_irq(&phba->hbalock);
2118 2384
2119 lpfc_linkup(phba); 2385 lpfc_linkup(phba);
2120 if (sparam_mbox) { 2386 sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2121 lpfc_read_sparam(phba, sparam_mbox, 0); 2387 if (!sparam_mbox)
2122 sparam_mbox->vport = vport; 2388 goto out;
2123 sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; 2389
2124 rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT); 2390 rc = lpfc_read_sparam(phba, sparam_mbox, 0);
2125 if (rc == MBX_NOT_FINISHED) { 2391 if (rc) {
2126 mp = (struct lpfc_dmabuf *) sparam_mbox->context1; 2392 mempool_free(sparam_mbox, phba->mbox_mem_pool);
2127 lpfc_mbuf_free(phba, mp->virt, mp->phys); 2393 goto out;
2128 kfree(mp); 2394 }
2129 mempool_free(sparam_mbox, phba->mbox_mem_pool); 2395 sparam_mbox->vport = vport;
2130 goto out; 2396 sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
2131 } 2397 rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
2398 if (rc == MBX_NOT_FINISHED) {
2399 mp = (struct lpfc_dmabuf *) sparam_mbox->context1;
2400 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2401 kfree(mp);
2402 mempool_free(sparam_mbox, phba->mbox_mem_pool);
2403 goto out;
2132 } 2404 }
2133 2405
2134 if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) { 2406 if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) {
@@ -2186,10 +2458,20 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
2186 spin_unlock_irq(&phba->hbalock); 2458 spin_unlock_irq(&phba->hbalock);
2187 return; 2459 return;
2188 } 2460 }
2461 /* This is the initial FCF discovery scan */
2462 phba->fcf.fcf_flag |= FCF_INIT_DISC;
2189 spin_unlock_irq(&phba->hbalock); 2463 spin_unlock_irq(&phba->hbalock);
2190 rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); 2464 lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
2191 if (rc) 2465 "2778 Start FCF table scan at linkup\n");
2466
2467 rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
2468 LPFC_FCOE_FCF_GET_FIRST);
2469 if (rc) {
2470 spin_lock_irq(&phba->hbalock);
2471 phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
2472 spin_unlock_irq(&phba->hbalock);
2192 goto out; 2473 goto out;
2474 }
2193 } 2475 }
2194 2476
2195 return; 2477 return;
@@ -3379,8 +3661,12 @@ lpfc_unreg_hba_rpis(struct lpfc_hba *phba)
3379 shost = lpfc_shost_from_vport(vports[i]); 3661 shost = lpfc_shost_from_vport(vports[i]);
3380 spin_lock_irq(shost->host_lock); 3662 spin_lock_irq(shost->host_lock);
3381 list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { 3663 list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) {
3382 if (ndlp->nlp_flag & NLP_RPI_VALID) 3664 if (ndlp->nlp_flag & NLP_RPI_VALID) {
3665 /* The mempool_alloc might sleep */
3666 spin_unlock_irq(shost->host_lock);
3383 lpfc_unreg_rpi(vports[i], ndlp); 3667 lpfc_unreg_rpi(vports[i], ndlp);
3668 spin_lock_irq(shost->host_lock);
3669 }
3384 } 3670 }
3385 spin_unlock_irq(shost->host_lock); 3671 spin_unlock_irq(shost->host_lock);
3386 } 3672 }
@@ -4756,6 +5042,7 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba)
4756 return; 5042 return;
4757 /* Reset HBA FCF states after successful unregister FCF */ 5043 /* Reset HBA FCF states after successful unregister FCF */
4758 phba->fcf.fcf_flag = 0; 5044 phba->fcf.fcf_flag = 0;
5045 phba->fcf.current_rec.flag = 0;
4759 5046
4760 /* 5047 /*
4761 * If driver is not unloading, check if there is any other 5048 * If driver is not unloading, check if there is any other
@@ -4765,13 +5052,21 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba)
4765 (phba->link_state < LPFC_LINK_UP)) 5052 (phba->link_state < LPFC_LINK_UP))
4766 return; 5053 return;
4767 5054
4768 rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); 5055 /* This is considered as the initial FCF discovery scan */
5056 spin_lock_irq(&phba->hbalock);
5057 phba->fcf.fcf_flag |= FCF_INIT_DISC;
5058 spin_unlock_irq(&phba->hbalock);
5059 rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
4769 5060
4770 if (rc) 5061 if (rc) {
5062 spin_lock_irq(&phba->hbalock);
5063 phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
5064 spin_unlock_irq(&phba->hbalock);
4771 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, 5065 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
4772 "2553 lpfc_unregister_unused_fcf failed " 5066 "2553 lpfc_unregister_unused_fcf failed "
4773 "to read FCF record HBA state x%x\n", 5067 "to read FCF record HBA state x%x\n",
4774 phba->pport->port_state); 5068 phba->pport->port_state);
5069 }
4775} 5070}
4776 5071
4777/** 5072/**
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index d29ac7c317d9..ea44239eeb33 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -350,7 +350,12 @@ lpfc_config_port_post(struct lpfc_hba *phba)
350 mb = &pmb->u.mb; 350 mb = &pmb->u.mb;
351 351
352 /* Get login parameters for NID. */ 352 /* Get login parameters for NID. */
353 lpfc_read_sparam(phba, pmb, 0); 353 rc = lpfc_read_sparam(phba, pmb, 0);
354 if (rc) {
355 mempool_free(pmb, phba->mbox_mem_pool);
356 return -ENOMEM;
357 }
358
354 pmb->vport = vport; 359 pmb->vport = vport;
355 if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { 360 if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
356 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 361 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -359,7 +364,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
359 mb->mbxCommand, mb->mbxStatus); 364 mb->mbxCommand, mb->mbxStatus);
360 phba->link_state = LPFC_HBA_ERROR; 365 phba->link_state = LPFC_HBA_ERROR;
361 mp = (struct lpfc_dmabuf *) pmb->context1; 366 mp = (struct lpfc_dmabuf *) pmb->context1;
362 mempool_free( pmb, phba->mbox_mem_pool); 367 mempool_free(pmb, phba->mbox_mem_pool);
363 lpfc_mbuf_free(phba, mp->virt, mp->phys); 368 lpfc_mbuf_free(phba, mp->virt, mp->phys);
364 kfree(mp); 369 kfree(mp);
365 return -EIO; 370 return -EIO;
@@ -544,7 +549,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
544 mempool_free(pmb, phba->mbox_mem_pool); 549 mempool_free(pmb, phba->mbox_mem_pool);
545 return -EIO; 550 return -EIO;
546 } 551 }
547 } else if (phba->cfg_suppress_link_up == 0) { 552 } else if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) {
548 lpfc_init_link(phba, pmb, phba->cfg_topology, 553 lpfc_init_link(phba, pmb, phba->cfg_topology,
549 phba->cfg_link_speed); 554 phba->cfg_link_speed);
550 pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 555 pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@@ -571,6 +576,11 @@ lpfc_config_port_post(struct lpfc_hba *phba)
571 } 576 }
572 /* MBOX buffer will be freed in mbox compl */ 577 /* MBOX buffer will be freed in mbox compl */
573 pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 578 pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
579 if (!pmb) {
580 phba->link_state = LPFC_HBA_ERROR;
581 return -ENOMEM;
582 }
583
574 lpfc_config_async(phba, pmb, LPFC_ELS_RING); 584 lpfc_config_async(phba, pmb, LPFC_ELS_RING);
575 pmb->mbox_cmpl = lpfc_config_async_cmpl; 585 pmb->mbox_cmpl = lpfc_config_async_cmpl;
576 pmb->vport = phba->pport; 586 pmb->vport = phba->pport;
@@ -588,6 +598,11 @@ lpfc_config_port_post(struct lpfc_hba *phba)
588 598
589 /* Get Option rom version */ 599 /* Get Option rom version */
590 pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 600 pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
601 if (!pmb) {
602 phba->link_state = LPFC_HBA_ERROR;
603 return -ENOMEM;
604 }
605
591 lpfc_dump_wakeup_param(phba, pmb); 606 lpfc_dump_wakeup_param(phba, pmb);
592 pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl; 607 pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl;
593 pmb->vport = phba->pport; 608 pmb->vport = phba->pport;
@@ -652,7 +667,7 @@ lpfc_hba_init_link(struct lpfc_hba *phba)
652 mempool_free(pmb, phba->mbox_mem_pool); 667 mempool_free(pmb, phba->mbox_mem_pool);
653 return -EIO; 668 return -EIO;
654 } 669 }
655 phba->cfg_suppress_link_up = 0; 670 phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK;
656 671
657 return 0; 672 return 0;
658} 673}
@@ -807,6 +822,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
807 LIST_HEAD(aborts); 822 LIST_HEAD(aborts);
808 int ret; 823 int ret;
809 unsigned long iflag = 0; 824 unsigned long iflag = 0;
825 struct lpfc_sglq *sglq_entry = NULL;
826
810 ret = lpfc_hba_down_post_s3(phba); 827 ret = lpfc_hba_down_post_s3(phba);
811 if (ret) 828 if (ret)
812 return ret; 829 return ret;
@@ -822,6 +839,10 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
822 * list. 839 * list.
823 */ 840 */
824 spin_lock(&phba->sli4_hba.abts_sgl_list_lock); 841 spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
842 list_for_each_entry(sglq_entry,
843 &phba->sli4_hba.lpfc_abts_els_sgl_list, list)
844 sglq_entry->state = SGL_FREED;
845
825 list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list, 846 list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list,
826 &phba->sli4_hba.lpfc_sgl_list); 847 &phba->sli4_hba.lpfc_sgl_list);
827 spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); 848 spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
@@ -2178,8 +2199,10 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport)
2178void 2199void
2179__lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba) 2200__lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
2180{ 2201{
2181 /* Clear pending FCF rediscovery wait timer */ 2202 /* Clear pending FCF rediscovery wait and failover in progress flags */
2182 phba->fcf.fcf_flag &= ~FCF_REDISC_PEND; 2203 phba->fcf.fcf_flag &= ~(FCF_REDISC_PEND |
2204 FCF_DEAD_DISC |
2205 FCF_ACVL_DISC);
2183 /* Now, try to stop the timer */ 2206 /* Now, try to stop the timer */
2184 del_timer(&phba->fcf.redisc_wait); 2207 del_timer(&phba->fcf.redisc_wait);
2185} 2208}
@@ -2576,6 +2599,14 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
2576 init_timer(&vport->els_tmofunc); 2599 init_timer(&vport->els_tmofunc);
2577 vport->els_tmofunc.function = lpfc_els_timeout; 2600 vport->els_tmofunc.function = lpfc_els_timeout;
2578 vport->els_tmofunc.data = (unsigned long)vport; 2601 vport->els_tmofunc.data = (unsigned long)vport;
2602 if (phba->pcidev->device == PCI_DEVICE_ID_HORNET) {
2603 phba->menlo_flag |= HBA_MENLO_SUPPORT;
2604 /* check for menlo minimum sg count */
2605 if (phba->cfg_sg_seg_cnt < LPFC_DEFAULT_MENLO_SG_SEG_CNT) {
2606 phba->cfg_sg_seg_cnt = LPFC_DEFAULT_MENLO_SG_SEG_CNT;
2607 shost->sg_tablesize = phba->cfg_sg_seg_cnt;
2608 }
2609 }
2579 2610
2580 error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev); 2611 error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
2581 if (error) 2612 if (error)
@@ -2912,6 +2943,9 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr)
2912 /* FCF rediscovery event to worker thread */ 2943 /* FCF rediscovery event to worker thread */
2913 phba->fcf.fcf_flag |= FCF_REDISC_EVT; 2944 phba->fcf.fcf_flag |= FCF_REDISC_EVT;
2914 spin_unlock_irq(&phba->hbalock); 2945 spin_unlock_irq(&phba->hbalock);
2946 lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
2947 "2776 FCF rediscover wait timer expired, post "
2948 "a worker thread event for FCF table scan\n");
2915 /* wake up worker thread */ 2949 /* wake up worker thread */
2916 lpfc_worker_wake_up(phba); 2950 lpfc_worker_wake_up(phba);
2917} 2951}
@@ -3183,6 +3217,68 @@ out_free_pmb:
3183} 3217}
3184 3218
3185/** 3219/**
3220 * lpfc_sli4_perform_vport_cvl - Perform clear virtual link on a vport
3221 * @vport: pointer to vport data structure.
3222 *
3223 * This routine is to perform Clear Virtual Link (CVL) on a vport in
3224 * response to a CVL event.
3225 *
3226 * Return the pointer to the ndlp with the vport if successful, otherwise
3227 * return NULL.
3228 **/
3229static struct lpfc_nodelist *
3230lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport)
3231{
3232 struct lpfc_nodelist *ndlp;
3233 struct Scsi_Host *shost;
3234 struct lpfc_hba *phba;
3235
3236 if (!vport)
3237 return NULL;
3238 ndlp = lpfc_findnode_did(vport, Fabric_DID);
3239 if (!ndlp)
3240 return NULL;
3241 phba = vport->phba;
3242 if (!phba)
3243 return NULL;
3244 if (phba->pport->port_state <= LPFC_FLOGI)
3245 return NULL;
3246 /* If virtual link is not yet instantiated ignore CVL */
3247 if (vport->port_state <= LPFC_FDISC)
3248 return NULL;
3249 shost = lpfc_shost_from_vport(vport);
3250 if (!shost)
3251 return NULL;
3252 lpfc_linkdown_port(vport);
3253 lpfc_cleanup_pending_mbox(vport);
3254 spin_lock_irq(shost->host_lock);
3255 vport->fc_flag |= FC_VPORT_CVL_RCVD;
3256 spin_unlock_irq(shost->host_lock);
3257
3258 return ndlp;
3259}
3260
3261/**
3262 * lpfc_sli4_perform_all_vport_cvl - Perform clear virtual link on all vports
3263 * @vport: pointer to lpfc hba data structure.
3264 *
3265 * This routine is to perform Clear Virtual Link (CVL) on all vports in
3266 * response to a FCF dead event.
3267 **/
3268static void
3269lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba)
3270{
3271 struct lpfc_vport **vports;
3272 int i;
3273
3274 vports = lpfc_create_vport_work_array(phba);
3275 if (vports)
3276 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
3277 lpfc_sli4_perform_vport_cvl(vports[i]);
3278 lpfc_destroy_vport_work_array(phba, vports);
3279}
3280
3281/**
3186 * lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event 3282 * lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event
3187 * @phba: pointer to lpfc hba data structure. 3283 * @phba: pointer to lpfc hba data structure.
3188 * @acqe_link: pointer to the async fcoe completion queue entry. 3284 * @acqe_link: pointer to the async fcoe completion queue entry.
@@ -3198,7 +3294,6 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3198 struct lpfc_vport *vport; 3294 struct lpfc_vport *vport;
3199 struct lpfc_nodelist *ndlp; 3295 struct lpfc_nodelist *ndlp;
3200 struct Scsi_Host *shost; 3296 struct Scsi_Host *shost;
3201 uint32_t link_state;
3202 int active_vlink_present; 3297 int active_vlink_present;
3203 struct lpfc_vport **vports; 3298 struct lpfc_vport **vports;
3204 int i; 3299 int i;
@@ -3208,10 +3303,11 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3208 switch (event_type) { 3303 switch (event_type) {
3209 case LPFC_FCOE_EVENT_TYPE_NEW_FCF: 3304 case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
3210 case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD: 3305 case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD:
3211 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, 3306 lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
3212 "2546 New FCF found index 0x%x tag 0x%x\n", 3307 "2546 New FCF found/FCF parameter modified event: "
3213 acqe_fcoe->index, 3308 "evt_tag:x%x, fcf_index:x%x\n",
3214 acqe_fcoe->event_tag); 3309 acqe_fcoe->event_tag, acqe_fcoe->index);
3310
3215 spin_lock_irq(&phba->hbalock); 3311 spin_lock_irq(&phba->hbalock);
3216 if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) || 3312 if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) ||
3217 (phba->hba_flag & FCF_DISC_INPROGRESS)) { 3313 (phba->hba_flag & FCF_DISC_INPROGRESS)) {
@@ -3222,6 +3318,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3222 spin_unlock_irq(&phba->hbalock); 3318 spin_unlock_irq(&phba->hbalock);
3223 break; 3319 break;
3224 } 3320 }
3321
3225 if (phba->fcf.fcf_flag & FCF_REDISC_EVT) { 3322 if (phba->fcf.fcf_flag & FCF_REDISC_EVT) {
3226 /* 3323 /*
3227 * If fast FCF failover rescan event is pending, 3324 * If fast FCF failover rescan event is pending,
@@ -3232,12 +3329,33 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3232 } 3329 }
3233 spin_unlock_irq(&phba->hbalock); 3330 spin_unlock_irq(&phba->hbalock);
3234 3331
3235 /* Read the FCF table and re-discover SAN. */ 3332 if ((phba->fcf.fcf_flag & FCF_DISCOVERY) &&
3236 rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); 3333 !(phba->fcf.fcf_flag & FCF_REDISC_FOV)) {
3334 /*
3335 * During period of FCF discovery, read the FCF
3336 * table record indexed by the event to update
3337 * FCF round robin failover eligible FCF bmask.
3338 */
3339 lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
3340 LOG_DISCOVERY,
3341 "2779 Read new FCF record with "
3342 "fcf_index:x%x for updating FCF "
3343 "round robin failover bmask\n",
3344 acqe_fcoe->index);
3345 rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index);
3346 }
3347
3348 /* Otherwise, scan the entire FCF table and re-discover SAN */
3349 lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
3350 "2770 Start FCF table scan due to new FCF "
3351 "event: evt_tag:x%x, fcf_index:x%x\n",
3352 acqe_fcoe->event_tag, acqe_fcoe->index);
3353 rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
3354 LPFC_FCOE_FCF_GET_FIRST);
3237 if (rc) 3355 if (rc)
3238 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, 3356 lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
3239 "2547 Read FCF record failed 0x%x\n", 3357 "2547 Issue FCF scan read FCF mailbox "
3240 rc); 3358 "command failed 0x%x\n", rc);
3241 break; 3359 break;
3242 3360
3243 case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL: 3361 case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
@@ -3248,47 +3366,63 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3248 break; 3366 break;
3249 3367
3250 case LPFC_FCOE_EVENT_TYPE_FCF_DEAD: 3368 case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
3251 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, 3369 lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
3252 "2549 FCF disconnected from network index 0x%x" 3370 "2549 FCF disconnected from network index 0x%x"
3253 " tag 0x%x\n", acqe_fcoe->index, 3371 " tag 0x%x\n", acqe_fcoe->index,
3254 acqe_fcoe->event_tag); 3372 acqe_fcoe->event_tag);
3255 /* If the event is not for currently used fcf do nothing */ 3373 /* If the event is not for currently used fcf do nothing */
3256 if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index) 3374 if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index)
3257 break; 3375 break;
3258 /* 3376 /* We request port to rediscover the entire FCF table for
3259 * Currently, driver support only one FCF - so treat this as 3377 * a fast recovery from case that the current FCF record
3260 * a link down, but save the link state because we don't want 3378 * is no longer valid if we are not in the middle of FCF
3261 * it to be changed to Link Down unless it is already down. 3379 * failover process already.
3262 */ 3380 */
3263 link_state = phba->link_state; 3381 spin_lock_irq(&phba->hbalock);
3264 lpfc_linkdown(phba); 3382 if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
3265 phba->link_state = link_state; 3383 spin_unlock_irq(&phba->hbalock);
3266 /* Unregister FCF if no devices connected to it */ 3384 /* Update FLOGI FCF failover eligible FCF bmask */
3267 lpfc_unregister_unused_fcf(phba); 3385 lpfc_sli4_fcf_rr_index_clear(phba, acqe_fcoe->index);
3386 break;
3387 }
3388 /* Mark the fast failover process in progress */
3389 phba->fcf.fcf_flag |= FCF_DEAD_DISC;
3390 spin_unlock_irq(&phba->hbalock);
3391 lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
3392 "2771 Start FCF fast failover process due to "
3393 "FCF DEAD event: evt_tag:x%x, fcf_index:x%x "
3394 "\n", acqe_fcoe->event_tag, acqe_fcoe->index);
3395 rc = lpfc_sli4_redisc_fcf_table(phba);
3396 if (rc) {
3397 lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
3398 LOG_DISCOVERY,
3399 "2772 Issue FCF rediscover mabilbox "
3400 "command failed, fail through to FCF "
3401 "dead event\n");
3402 spin_lock_irq(&phba->hbalock);
3403 phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
3404 spin_unlock_irq(&phba->hbalock);
3405 /*
3406 * Last resort will fail over by treating this
3407 * as a link down to FCF registration.
3408 */
3409 lpfc_sli4_fcf_dead_failthrough(phba);
3410 } else
3411 /* Handling fast FCF failover to a DEAD FCF event
3412 * is considered equalivant to receiving CVL to all
3413 * vports.
3414 */
3415 lpfc_sli4_perform_all_vport_cvl(phba);
3268 break; 3416 break;
3269 case LPFC_FCOE_EVENT_TYPE_CVL: 3417 case LPFC_FCOE_EVENT_TYPE_CVL:
3270 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, 3418 lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
3271 "2718 Clear Virtual Link Received for VPI 0x%x" 3419 "2718 Clear Virtual Link Received for VPI 0x%x"
3272 " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag); 3420 " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
3273 vport = lpfc_find_vport_by_vpid(phba, 3421 vport = lpfc_find_vport_by_vpid(phba,
3274 acqe_fcoe->index - phba->vpi_base); 3422 acqe_fcoe->index - phba->vpi_base);
3275 if (!vport) 3423 ndlp = lpfc_sli4_perform_vport_cvl(vport);
3276 break;
3277 ndlp = lpfc_findnode_did(vport, Fabric_DID);
3278 if (!ndlp) 3424 if (!ndlp)
3279 break; 3425 break;
3280 shost = lpfc_shost_from_vport(vport);
3281 if (phba->pport->port_state <= LPFC_FLOGI)
3282 break;
3283 /* If virtual link is not yet instantiated ignore CVL */
3284 if (vport->port_state <= LPFC_FDISC)
3285 break;
3286
3287 lpfc_linkdown_port(vport);
3288 lpfc_cleanup_pending_mbox(vport);
3289 spin_lock_irq(shost->host_lock);
3290 vport->fc_flag |= FC_VPORT_CVL_RCVD;
3291 spin_unlock_irq(shost->host_lock);
3292 active_vlink_present = 0; 3426 active_vlink_present = 0;
3293 3427
3294 vports = lpfc_create_vport_work_array(phba); 3428 vports = lpfc_create_vport_work_array(phba);
@@ -3311,6 +3445,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3311 * re-instantiate the Vlink using FDISC. 3445 * re-instantiate the Vlink using FDISC.
3312 */ 3446 */
3313 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); 3447 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
3448 shost = lpfc_shost_from_vport(vport);
3314 spin_lock_irq(shost->host_lock); 3449 spin_lock_irq(shost->host_lock);
3315 ndlp->nlp_flag |= NLP_DELAY_TMO; 3450 ndlp->nlp_flag |= NLP_DELAY_TMO;
3316 spin_unlock_irq(shost->host_lock); 3451 spin_unlock_irq(shost->host_lock);
@@ -3321,15 +3456,38 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3321 * Otherwise, we request port to rediscover 3456 * Otherwise, we request port to rediscover
3322 * the entire FCF table for a fast recovery 3457 * the entire FCF table for a fast recovery
3323 * from possible case that the current FCF 3458 * from possible case that the current FCF
3324 * is no longer valid. 3459 * is no longer valid if we are not already
3460 * in the FCF failover process.
3325 */ 3461 */
3462 spin_lock_irq(&phba->hbalock);
3463 if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
3464 spin_unlock_irq(&phba->hbalock);
3465 break;
3466 }
3467 /* Mark the fast failover process in progress */
3468 phba->fcf.fcf_flag |= FCF_ACVL_DISC;
3469 spin_unlock_irq(&phba->hbalock);
3470 lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
3471 LOG_DISCOVERY,
3472 "2773 Start FCF fast failover due "
3473 "to CVL event: evt_tag:x%x\n",
3474 acqe_fcoe->event_tag);
3326 rc = lpfc_sli4_redisc_fcf_table(phba); 3475 rc = lpfc_sli4_redisc_fcf_table(phba);
3327 if (rc) 3476 if (rc) {
3477 lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
3478 LOG_DISCOVERY,
3479 "2774 Issue FCF rediscover "
3480 "mabilbox command failed, "
3481 "through to CVL event\n");
3482 spin_lock_irq(&phba->hbalock);
3483 phba->fcf.fcf_flag &= ~FCF_ACVL_DISC;
3484 spin_unlock_irq(&phba->hbalock);
3328 /* 3485 /*
3329 * Last resort will be re-try on the 3486 * Last resort will be re-try on the
3330 * the current registered FCF entry. 3487 * the current registered FCF entry.
3331 */ 3488 */
3332 lpfc_retry_pport_discovery(phba); 3489 lpfc_retry_pport_discovery(phba);
3490 }
3333 } 3491 }
3334 break; 3492 break;
3335 default: 3493 default:
@@ -3426,11 +3584,14 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba)
3426 spin_unlock_irq(&phba->hbalock); 3584 spin_unlock_irq(&phba->hbalock);
3427 3585
3428 /* Scan FCF table from the first entry to re-discover SAN */ 3586 /* Scan FCF table from the first entry to re-discover SAN */
3429 rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); 3587 lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
3588 "2777 Start FCF table scan after FCF "
3589 "rediscovery quiescent period over\n");
3590 rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
3430 if (rc) 3591 if (rc)
3431 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, 3592 lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
3432 "2747 Post FCF rediscovery read FCF record " 3593 "2747 Issue FCF scan read FCF mailbox "
3433 "failed 0x%x\n", rc); 3594 "command failed 0x%x\n", rc);
3434} 3595}
3435 3596
3436/** 3597/**
@@ -3722,6 +3883,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
3722 int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size; 3883 int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size;
3723 uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; 3884 uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0};
3724 struct lpfc_mqe *mqe; 3885 struct lpfc_mqe *mqe;
3886 int longs;
3725 3887
3726 /* Before proceed, wait for POST done and device ready */ 3888 /* Before proceed, wait for POST done and device ready */
3727 rc = lpfc_sli4_post_status_check(phba); 3889 rc = lpfc_sli4_post_status_check(phba);
@@ -3898,13 +4060,24 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
3898 goto out_free_active_sgl; 4060 goto out_free_active_sgl;
3899 } 4061 }
3900 4062
4063 /* Allocate eligible FCF bmask memory for FCF round robin failover */
4064 longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG;
4065 phba->fcf.fcf_rr_bmask = kzalloc(longs * sizeof(unsigned long),
4066 GFP_KERNEL);
4067 if (!phba->fcf.fcf_rr_bmask) {
4068 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4069 "2759 Failed allocate memory for FCF round "
4070 "robin failover bmask\n");
4071 goto out_remove_rpi_hdrs;
4072 }
4073
3901 phba->sli4_hba.fcp_eq_hdl = kzalloc((sizeof(struct lpfc_fcp_eq_hdl) * 4074 phba->sli4_hba.fcp_eq_hdl = kzalloc((sizeof(struct lpfc_fcp_eq_hdl) *
3902 phba->cfg_fcp_eq_count), GFP_KERNEL); 4075 phba->cfg_fcp_eq_count), GFP_KERNEL);
3903 if (!phba->sli4_hba.fcp_eq_hdl) { 4076 if (!phba->sli4_hba.fcp_eq_hdl) {
3904 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 4077 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
3905 "2572 Failed allocate memory for fast-path " 4078 "2572 Failed allocate memory for fast-path "
3906 "per-EQ handle array\n"); 4079 "per-EQ handle array\n");
3907 goto out_remove_rpi_hdrs; 4080 goto out_free_fcf_rr_bmask;
3908 } 4081 }
3909 4082
3910 phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) * 4083 phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) *
@@ -3957,6 +4130,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
3957 4130
3958out_free_fcp_eq_hdl: 4131out_free_fcp_eq_hdl:
3959 kfree(phba->sli4_hba.fcp_eq_hdl); 4132 kfree(phba->sli4_hba.fcp_eq_hdl);
4133out_free_fcf_rr_bmask:
4134 kfree(phba->fcf.fcf_rr_bmask);
3960out_remove_rpi_hdrs: 4135out_remove_rpi_hdrs:
3961 lpfc_sli4_remove_rpi_hdrs(phba); 4136 lpfc_sli4_remove_rpi_hdrs(phba);
3962out_free_active_sgl: 4137out_free_active_sgl:
@@ -4002,6 +4177,9 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba)
4002 lpfc_sli4_remove_rpi_hdrs(phba); 4177 lpfc_sli4_remove_rpi_hdrs(phba);
4003 lpfc_sli4_remove_rpis(phba); 4178 lpfc_sli4_remove_rpis(phba);
4004 4179
4180 /* Free eligible FCF index bmask */
4181 kfree(phba->fcf.fcf_rr_bmask);
4182
4005 /* Free the ELS sgl list */ 4183 /* Free the ELS sgl list */
4006 lpfc_free_active_sgl(phba); 4184 lpfc_free_active_sgl(phba);
4007 lpfc_free_sgl_list(phba); 4185 lpfc_free_sgl_list(phba);
@@ -4397,6 +4575,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba)
4397 4575
4398 /* The list order is used by later block SGL registraton */ 4576 /* The list order is used by later block SGL registraton */
4399 spin_lock_irq(&phba->hbalock); 4577 spin_lock_irq(&phba->hbalock);
4578 sglq_entry->state = SGL_FREED;
4400 list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list); 4579 list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list);
4401 phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry; 4580 phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry;
4402 phba->sli4_hba.total_sglq_bufs++; 4581 phba->sli4_hba.total_sglq_bufs++;
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h
index 954ba57970a3..bb59e9273126 100644
--- a/drivers/scsi/lpfc/lpfc_logmsg.h
+++ b/drivers/scsi/lpfc/lpfc_logmsg.h
@@ -35,6 +35,7 @@
35#define LOG_VPORT 0x00004000 /* NPIV events */ 35#define LOG_VPORT 0x00004000 /* NPIV events */
36#define LOF_SECURITY 0x00008000 /* Security events */ 36#define LOF_SECURITY 0x00008000 /* Security events */
37#define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */ 37#define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */
38#define LOG_FIP 0x00020000 /* FIP events */
38#define LOG_ALL_MSG 0xffffffff /* LOG all messages */ 39#define LOG_ALL_MSG 0xffffffff /* LOG all messages */
39 40
40#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ 41#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 6c4dce1a30ca..1e61ae3bc4eb 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -1748,7 +1748,7 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
1748} 1748}
1749 1749
1750/** 1750/**
1751 * lpfc_sli4_mbx_read_fcf_record - Allocate and construct read fcf mbox cmd 1751 * lpfc_sli4_mbx_read_fcf_rec - Allocate and construct read fcf mbox cmd
1752 * @phba: pointer to lpfc hba data structure. 1752 * @phba: pointer to lpfc hba data structure.
1753 * @fcf_index: index to fcf table. 1753 * @fcf_index: index to fcf table.
1754 * 1754 *
@@ -1759,9 +1759,9 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
1759 * NULL. 1759 * NULL.
1760 **/ 1760 **/
1761int 1761int
1762lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *phba, 1762lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *phba,
1763 struct lpfcMboxq *mboxq, 1763 struct lpfcMboxq *mboxq,
1764 uint16_t fcf_index) 1764 uint16_t fcf_index)
1765{ 1765{
1766 void *virt_addr; 1766 void *virt_addr;
1767 dma_addr_t phys_addr; 1767 dma_addr_t phys_addr;
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 483fb74bc592..b16bb2c9978b 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -620,23 +620,40 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
620 uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); 620 uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
621 struct lpfc_scsi_buf *psb, *next_psb; 621 struct lpfc_scsi_buf *psb, *next_psb;
622 unsigned long iflag = 0; 622 unsigned long iflag = 0;
623 struct lpfc_iocbq *iocbq;
624 int i;
623 625
624 spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag); 626 spin_lock_irqsave(&phba->hbalock, iflag);
627 spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock);
625 list_for_each_entry_safe(psb, next_psb, 628 list_for_each_entry_safe(psb, next_psb,
626 &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) { 629 &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) {
627 if (psb->cur_iocbq.sli4_xritag == xri) { 630 if (psb->cur_iocbq.sli4_xritag == xri) {
628 list_del(&psb->list); 631 list_del(&psb->list);
629 psb->exch_busy = 0; 632 psb->exch_busy = 0;
630 psb->status = IOSTAT_SUCCESS; 633 psb->status = IOSTAT_SUCCESS;
631 spin_unlock_irqrestore( 634 spin_unlock(
632 &phba->sli4_hba.abts_scsi_buf_list_lock, 635 &phba->sli4_hba.abts_scsi_buf_list_lock);
633 iflag); 636 spin_unlock_irqrestore(&phba->hbalock, iflag);
634 lpfc_release_scsi_buf_s4(phba, psb); 637 lpfc_release_scsi_buf_s4(phba, psb);
635 return; 638 return;
636 } 639 }
637 } 640 }
638 spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock, 641 spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock);
639 iflag); 642 for (i = 1; i <= phba->sli.last_iotag; i++) {
643 iocbq = phba->sli.iocbq_lookup[i];
644
645 if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
646 (iocbq->iocb_flag & LPFC_IO_LIBDFC))
647 continue;
648 if (iocbq->sli4_xritag != xri)
649 continue;
650 psb = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
651 psb->exch_busy = 0;
652 spin_unlock_irqrestore(&phba->hbalock, iflag);
653 return;
654
655 }
656 spin_unlock_irqrestore(&phba->hbalock, iflag);
640} 657}
641 658
642/** 659/**
@@ -1006,6 +1023,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1006 struct scatterlist *sgel = NULL; 1023 struct scatterlist *sgel = NULL;
1007 struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; 1024 struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
1008 struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl; 1025 struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl;
1026 struct lpfc_iocbq *iocbq = &lpfc_cmd->cur_iocbq;
1009 IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; 1027 IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
1010 struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde; 1028 struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde;
1011 dma_addr_t physaddr; 1029 dma_addr_t physaddr;
@@ -1056,6 +1074,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1056 physaddr = sg_dma_address(sgel); 1074 physaddr = sg_dma_address(sgel);
1057 if (phba->sli_rev == 3 && 1075 if (phba->sli_rev == 3 &&
1058 !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && 1076 !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
1077 !(iocbq->iocb_flag & DSS_SECURITY_OP) &&
1059 nseg <= LPFC_EXT_DATA_BDE_COUNT) { 1078 nseg <= LPFC_EXT_DATA_BDE_COUNT) {
1060 data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; 1079 data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
1061 data_bde->tus.f.bdeSize = sg_dma_len(sgel); 1080 data_bde->tus.f.bdeSize = sg_dma_len(sgel);
@@ -1082,7 +1101,8 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1082 * explicitly reinitialized since all iocb memory resources are reused. 1101 * explicitly reinitialized since all iocb memory resources are reused.
1083 */ 1102 */
1084 if (phba->sli_rev == 3 && 1103 if (phba->sli_rev == 3 &&
1085 !(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) { 1104 !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
1105 !(iocbq->iocb_flag & DSS_SECURITY_OP)) {
1086 if (num_bde > LPFC_EXT_DATA_BDE_COUNT) { 1106 if (num_bde > LPFC_EXT_DATA_BDE_COUNT) {
1087 /* 1107 /*
1088 * The extended IOCB format can only fit 3 BDE or a BPL. 1108 * The extended IOCB format can only fit 3 BDE or a BPL.
@@ -1107,6 +1127,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1107 } else { 1127 } else {
1108 iocb_cmd->un.fcpi64.bdl.bdeSize = 1128 iocb_cmd->un.fcpi64.bdl.bdeSize =
1109 ((num_bde + 2) * sizeof(struct ulp_bde64)); 1129 ((num_bde + 2) * sizeof(struct ulp_bde64));
1130 iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1);
1110 } 1131 }
1111 fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); 1132 fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd));
1112 1133
@@ -2079,8 +2100,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
2079 2100
2080 if (resp_info & RSP_LEN_VALID) { 2101 if (resp_info & RSP_LEN_VALID) {
2081 rsplen = be32_to_cpu(fcprsp->rspRspLen); 2102 rsplen = be32_to_cpu(fcprsp->rspRspLen);
2082 if ((rsplen != 0 && rsplen != 4 && rsplen != 8) || 2103 if (rsplen != 0 && rsplen != 4 && rsplen != 8) {
2083 (fcprsp->rspInfo3 != RSP_NO_FAILURE)) {
2084 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 2104 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
2085 "2719 Invalid response length: " 2105 "2719 Invalid response length: "
2086 "tgt x%x lun x%x cmnd x%x rsplen x%x\n", 2106 "tgt x%x lun x%x cmnd x%x rsplen x%x\n",
@@ -2090,6 +2110,17 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
2090 host_status = DID_ERROR; 2110 host_status = DID_ERROR;
2091 goto out; 2111 goto out;
2092 } 2112 }
2113 if (fcprsp->rspInfo3 != RSP_NO_FAILURE) {
2114 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
2115 "2757 Protocol failure detected during "
2116 "processing of FCP I/O op: "
2117 "tgt x%x lun x%x cmnd x%x rspInfo3 x%x\n",
2118 cmnd->device->id,
2119 cmnd->device->lun, cmnd->cmnd[0],
2120 fcprsp->rspInfo3);
2121 host_status = DID_ERROR;
2122 goto out;
2123 }
2093 } 2124 }
2094 2125
2095 if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) { 2126 if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 35e3b96d4e07..fe6660ca6452 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -494,7 +494,7 @@ __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
494 * 494 *
495 * Returns sglq ponter = success, NULL = Failure. 495 * Returns sglq ponter = success, NULL = Failure.
496 **/ 496 **/
497static struct lpfc_sglq * 497struct lpfc_sglq *
498__lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) 498__lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
499{ 499{
500 uint16_t adj_xri; 500 uint16_t adj_xri;
@@ -526,6 +526,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba)
526 return NULL; 526 return NULL;
527 adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base; 527 adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base;
528 phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; 528 phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq;
529 sglq->state = SGL_ALLOCATED;
529 return sglq; 530 return sglq;
530} 531}
531 532
@@ -580,15 +581,18 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
580 else 581 else
581 sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); 582 sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag);
582 if (sglq) { 583 if (sglq) {
583 if (iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) { 584 if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) &&
585 (sglq->state != SGL_XRI_ABORTED)) {
584 spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, 586 spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock,
585 iflag); 587 iflag);
586 list_add(&sglq->list, 588 list_add(&sglq->list,
587 &phba->sli4_hba.lpfc_abts_els_sgl_list); 589 &phba->sli4_hba.lpfc_abts_els_sgl_list);
588 spin_unlock_irqrestore( 590 spin_unlock_irqrestore(
589 &phba->sli4_hba.abts_sgl_list_lock, iflag); 591 &phba->sli4_hba.abts_sgl_list_lock, iflag);
590 } else 592 } else {
593 sglq->state = SGL_FREED;
591 list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); 594 list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list);
595 }
592 } 596 }
593 597
594 598
@@ -2258,41 +2262,56 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
2258 spin_unlock_irqrestore(&phba->hbalock, 2262 spin_unlock_irqrestore(&phba->hbalock,
2259 iflag); 2263 iflag);
2260 } 2264 }
2261 if ((phba->sli_rev == LPFC_SLI_REV4) && 2265 if (phba->sli_rev == LPFC_SLI_REV4) {
2262 (saveq->iocb_flag & LPFC_EXCHANGE_BUSY)) { 2266 if (saveq->iocb_flag &
2263 /* Set cmdiocb flag for the exchange 2267 LPFC_EXCHANGE_BUSY) {
2264 * busy so sgl (xri) will not be 2268 /* Set cmdiocb flag for the
2265 * released until the abort xri is 2269 * exchange busy so sgl (xri)
2266 * received from hba, clear the 2270 * will not be released until
2267 * LPFC_DRIVER_ABORTED bit in case 2271 * the abort xri is received
2268 * it was driver initiated abort. 2272 * from hba.
2269 */ 2273 */
2270 spin_lock_irqsave(&phba->hbalock, 2274 spin_lock_irqsave(
2271 iflag); 2275 &phba->hbalock, iflag);
2272 cmdiocbp->iocb_flag &= 2276 cmdiocbp->iocb_flag |=
2273 ~LPFC_DRIVER_ABORTED; 2277 LPFC_EXCHANGE_BUSY;
2274 cmdiocbp->iocb_flag |= 2278 spin_unlock_irqrestore(
2275 LPFC_EXCHANGE_BUSY; 2279 &phba->hbalock, iflag);
2276 spin_unlock_irqrestore(&phba->hbalock, 2280 }
2277 iflag); 2281 if (cmdiocbp->iocb_flag &
2278 cmdiocbp->iocb.ulpStatus = 2282 LPFC_DRIVER_ABORTED) {
2279 IOSTAT_LOCAL_REJECT; 2283 /*
2280 cmdiocbp->iocb.un.ulpWord[4] = 2284 * Clear LPFC_DRIVER_ABORTED
2281 IOERR_ABORT_REQUESTED; 2285 * bit in case it was driver
2282 /* 2286 * initiated abort.
2283 * For SLI4, irsiocb contains NO_XRI 2287 */
2284 * in sli_xritag, it shall not affect 2288 spin_lock_irqsave(
2285 * releasing sgl (xri) process. 2289 &phba->hbalock, iflag);
2286 */ 2290 cmdiocbp->iocb_flag &=
2287 saveq->iocb.ulpStatus = 2291 ~LPFC_DRIVER_ABORTED;
2288 IOSTAT_LOCAL_REJECT; 2292 spin_unlock_irqrestore(
2289 saveq->iocb.un.ulpWord[4] = 2293 &phba->hbalock, iflag);
2290 IOERR_SLI_ABORTED; 2294 cmdiocbp->iocb.ulpStatus =
2291 spin_lock_irqsave(&phba->hbalock, 2295 IOSTAT_LOCAL_REJECT;
2292 iflag); 2296 cmdiocbp->iocb.un.ulpWord[4] =
2293 saveq->iocb_flag |= LPFC_DELAY_MEM_FREE; 2297 IOERR_ABORT_REQUESTED;
2294 spin_unlock_irqrestore(&phba->hbalock, 2298 /*
2295 iflag); 2299 * For SLI4, irsiocb contains
2300 * NO_XRI in sli_xritag, it
2301 * shall not affect releasing
2302 * sgl (xri) process.
2303 */
2304 saveq->iocb.ulpStatus =
2305 IOSTAT_LOCAL_REJECT;
2306 saveq->iocb.un.ulpWord[4] =
2307 IOERR_SLI_ABORTED;
2308 spin_lock_irqsave(
2309 &phba->hbalock, iflag);
2310 saveq->iocb_flag |=
2311 LPFC_DELAY_MEM_FREE;
2312 spin_unlock_irqrestore(
2313 &phba->hbalock, iflag);
2314 }
2296 } 2315 }
2297 } 2316 }
2298 (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); 2317 (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
@@ -2515,14 +2534,16 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
2515 2534
2516 cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, 2535 cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
2517 &rspiocbq); 2536 &rspiocbq);
2518 if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { 2537 if (unlikely(!cmdiocbq))
2519 spin_unlock_irqrestore(&phba->hbalock, 2538 break;
2520 iflag); 2539 if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED)
2521 (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, 2540 cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED;
2522 &rspiocbq); 2541 if (cmdiocbq->iocb_cmpl) {
2523 spin_lock_irqsave(&phba->hbalock, 2542 spin_unlock_irqrestore(&phba->hbalock, iflag);
2524 iflag); 2543 (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
2525 } 2544 &rspiocbq);
2545 spin_lock_irqsave(&phba->hbalock, iflag);
2546 }
2526 break; 2547 break;
2527 case LPFC_UNSOL_IOCB: 2548 case LPFC_UNSOL_IOCB:
2528 spin_unlock_irqrestore(&phba->hbalock, iflag); 2549 spin_unlock_irqrestore(&phba->hbalock, iflag);
@@ -3091,6 +3112,12 @@ lpfc_sli_brdready_s3(struct lpfc_hba *phba, uint32_t mask)
3091 3112
3092 /* Check to see if any errors occurred during init */ 3113 /* Check to see if any errors occurred during init */
3093 if ((status & HS_FFERM) || (i >= 20)) { 3114 if ((status & HS_FFERM) || (i >= 20)) {
3115 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
3116 "2751 Adapter failed to restart, "
3117 "status reg x%x, FW Data: A8 x%x AC x%x\n",
3118 status,
3119 readl(phba->MBslimaddr + 0xa8),
3120 readl(phba->MBslimaddr + 0xac));
3094 phba->link_state = LPFC_HBA_ERROR; 3121 phba->link_state = LPFC_HBA_ERROR;
3095 retval = 1; 3122 retval = 1;
3096 } 3123 }
@@ -3278,6 +3305,9 @@ lpfc_sli_brdkill(struct lpfc_hba *phba)
3278 if (retval != MBX_SUCCESS) { 3305 if (retval != MBX_SUCCESS) {
3279 if (retval != MBX_BUSY) 3306 if (retval != MBX_BUSY)
3280 mempool_free(pmb, phba->mbox_mem_pool); 3307 mempool_free(pmb, phba->mbox_mem_pool);
3308 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
3309 "2752 KILL_BOARD command failed retval %d\n",
3310 retval);
3281 spin_lock_irq(&phba->hbalock); 3311 spin_lock_irq(&phba->hbalock);
3282 phba->link_flag &= ~LS_IGNORE_ERATT; 3312 phba->link_flag &= ~LS_IGNORE_ERATT;
3283 spin_unlock_irq(&phba->hbalock); 3313 spin_unlock_irq(&phba->hbalock);
@@ -4035,7 +4065,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
4035 4065
4036lpfc_sli_hba_setup_error: 4066lpfc_sli_hba_setup_error:
4037 phba->link_state = LPFC_HBA_ERROR; 4067 phba->link_state = LPFC_HBA_ERROR;
4038 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, 4068 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4039 "0445 Firmware initialization failed\n"); 4069 "0445 Firmware initialization failed\n");
4040 return rc; 4070 return rc;
4041} 4071}
@@ -4388,7 +4418,13 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
4388 spin_unlock_irq(&phba->hbalock); 4418 spin_unlock_irq(&phba->hbalock);
4389 4419
4390 /* Read the port's service parameters. */ 4420 /* Read the port's service parameters. */
4391 lpfc_read_sparam(phba, mboxq, vport->vpi); 4421 rc = lpfc_read_sparam(phba, mboxq, vport->vpi);
4422 if (rc) {
4423 phba->link_state = LPFC_HBA_ERROR;
4424 rc = -ENOMEM;
4425 goto out_free_vpd;
4426 }
4427
4392 mboxq->vport = vport; 4428 mboxq->vport = vport;
4393 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); 4429 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
4394 mp = (struct lpfc_dmabuf *) mboxq->context1; 4430 mp = (struct lpfc_dmabuf *) mboxq->context1;
@@ -4483,6 +4519,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
4483 /* Post receive buffers to the device */ 4519 /* Post receive buffers to the device */
4484 lpfc_sli4_rb_setup(phba); 4520 lpfc_sli4_rb_setup(phba);
4485 4521
4522 /* Reset HBA FCF states after HBA reset */
4523 phba->fcf.fcf_flag = 0;
4524 phba->fcf.current_rec.flag = 0;
4525
4486 /* Start the ELS watchdog timer */ 4526 /* Start the ELS watchdog timer */
4487 mod_timer(&vport->els_tmofunc, 4527 mod_timer(&vport->els_tmofunc,
4488 jiffies + HZ * (phba->fc_ratov * 2)); 4528 jiffies + HZ * (phba->fc_ratov * 2));
@@ -7436,6 +7476,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
7436{ 7476{
7437 wait_queue_head_t *pdone_q; 7477 wait_queue_head_t *pdone_q;
7438 unsigned long iflags; 7478 unsigned long iflags;
7479 struct lpfc_scsi_buf *lpfc_cmd;
7439 7480
7440 spin_lock_irqsave(&phba->hbalock, iflags); 7481 spin_lock_irqsave(&phba->hbalock, iflags);
7441 cmdiocbq->iocb_flag |= LPFC_IO_WAKE; 7482 cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
@@ -7443,6 +7484,14 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
7443 memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, 7484 memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
7444 &rspiocbq->iocb, sizeof(IOCB_t)); 7485 &rspiocbq->iocb, sizeof(IOCB_t));
7445 7486
7487 /* Set the exchange busy flag for task management commands */
7488 if ((cmdiocbq->iocb_flag & LPFC_IO_FCP) &&
7489 !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) {
7490 lpfc_cmd = container_of(cmdiocbq, struct lpfc_scsi_buf,
7491 cur_iocbq);
7492 lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY;
7493 }
7494
7446 pdone_q = cmdiocbq->context_un.wait_queue; 7495 pdone_q = cmdiocbq->context_un.wait_queue;
7447 if (pdone_q) 7496 if (pdone_q)
7448 wake_up(pdone_q); 7497 wake_up(pdone_q);
@@ -9061,6 +9110,12 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba,
9061 /* Fake the irspiocb and copy necessary response information */ 9110 /* Fake the irspiocb and copy necessary response information */
9062 lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe); 9111 lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe);
9063 9112
9113 if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) {
9114 spin_lock_irqsave(&phba->hbalock, iflags);
9115 cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED;
9116 spin_unlock_irqrestore(&phba->hbalock, iflags);
9117 }
9118
9064 /* Pass the cmd_iocb and the rsp state to the upper layer */ 9119 /* Pass the cmd_iocb and the rsp state to the upper layer */
9065 (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq); 9120 (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq);
9066} 9121}
@@ -11941,15 +11996,19 @@ lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *phba,
11941} 11996}
11942 11997
11943/** 11998/**
11944 * lpfc_sli4_read_fcf_record - Read the driver's default FCF Record. 11999 * lpfc_sli4_fcf_scan_read_fcf_rec - Read hba fcf record for fcf scan.
11945 * @phba: pointer to lpfc hba data structure. 12000 * @phba: pointer to lpfc hba data structure.
11946 * @fcf_index: FCF table entry offset. 12001 * @fcf_index: FCF table entry offset.
11947 * 12002 *
11948 * This routine is invoked to read up to @fcf_num of FCF record from the 12003 * This routine is invoked to scan the entire FCF table by reading FCF
11949 * device starting with the given @fcf_index. 12004 * record and processing it one at a time starting from the @fcf_index
12005 * for initial FCF discovery or fast FCF failover rediscovery.
12006 *
12007 * Return 0 if the mailbox command is submitted sucessfully, none 0
12008 * otherwise.
11950 **/ 12009 **/
11951int 12010int
11952lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) 12011lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
11953{ 12012{
11954 int rc = 0, error; 12013 int rc = 0, error;
11955 LPFC_MBOXQ_t *mboxq; 12014 LPFC_MBOXQ_t *mboxq;
@@ -11961,17 +12020,17 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
11961 "2000 Failed to allocate mbox for " 12020 "2000 Failed to allocate mbox for "
11962 "READ_FCF cmd\n"); 12021 "READ_FCF cmd\n");
11963 error = -ENOMEM; 12022 error = -ENOMEM;
11964 goto fail_fcfscan; 12023 goto fail_fcf_scan;
11965 } 12024 }
11966 /* Construct the read FCF record mailbox command */ 12025 /* Construct the read FCF record mailbox command */
11967 rc = lpfc_sli4_mbx_read_fcf_record(phba, mboxq, fcf_index); 12026 rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
11968 if (rc) { 12027 if (rc) {
11969 error = -EINVAL; 12028 error = -EINVAL;
11970 goto fail_fcfscan; 12029 goto fail_fcf_scan;
11971 } 12030 }
11972 /* Issue the mailbox command asynchronously */ 12031 /* Issue the mailbox command asynchronously */
11973 mboxq->vport = phba->pport; 12032 mboxq->vport = phba->pport;
11974 mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record; 12033 mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_scan_read_fcf_rec;
11975 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); 12034 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
11976 if (rc == MBX_NOT_FINISHED) 12035 if (rc == MBX_NOT_FINISHED)
11977 error = -EIO; 12036 error = -EIO;
@@ -11979,9 +12038,13 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
11979 spin_lock_irq(&phba->hbalock); 12038 spin_lock_irq(&phba->hbalock);
11980 phba->hba_flag |= FCF_DISC_INPROGRESS; 12039 phba->hba_flag |= FCF_DISC_INPROGRESS;
11981 spin_unlock_irq(&phba->hbalock); 12040 spin_unlock_irq(&phba->hbalock);
12041 /* Reset FCF round robin index bmask for new scan */
12042 if (fcf_index == LPFC_FCOE_FCF_GET_FIRST)
12043 memset(phba->fcf.fcf_rr_bmask, 0,
12044 sizeof(*phba->fcf.fcf_rr_bmask));
11982 error = 0; 12045 error = 0;
11983 } 12046 }
11984fail_fcfscan: 12047fail_fcf_scan:
11985 if (error) { 12048 if (error) {
11986 if (mboxq) 12049 if (mboxq)
11987 lpfc_sli4_mbox_cmd_free(phba, mboxq); 12050 lpfc_sli4_mbox_cmd_free(phba, mboxq);
@@ -11994,6 +12057,181 @@ fail_fcfscan:
11994} 12057}
11995 12058
11996/** 12059/**
12060 * lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for round robin fcf.
12061 * @phba: pointer to lpfc hba data structure.
12062 * @fcf_index: FCF table entry offset.
12063 *
12064 * This routine is invoked to read an FCF record indicated by @fcf_index
12065 * and to use it for FLOGI round robin FCF failover.
12066 *
12067 * Return 0 if the mailbox command is submitted sucessfully, none 0
12068 * otherwise.
12069 **/
12070int
12071lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
12072{
12073 int rc = 0, error;
12074 LPFC_MBOXQ_t *mboxq;
12075
12076 mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
12077 if (!mboxq) {
12078 lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT,
12079 "2763 Failed to allocate mbox for "
12080 "READ_FCF cmd\n");
12081 error = -ENOMEM;
12082 goto fail_fcf_read;
12083 }
12084 /* Construct the read FCF record mailbox command */
12085 rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
12086 if (rc) {
12087 error = -EINVAL;
12088 goto fail_fcf_read;
12089 }
12090 /* Issue the mailbox command asynchronously */
12091 mboxq->vport = phba->pport;
12092 mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_rr_read_fcf_rec;
12093 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
12094 if (rc == MBX_NOT_FINISHED)
12095 error = -EIO;
12096 else
12097 error = 0;
12098
12099fail_fcf_read:
12100 if (error && mboxq)
12101 lpfc_sli4_mbox_cmd_free(phba, mboxq);
12102 return error;
12103}
12104
12105/**
12106 * lpfc_sli4_read_fcf_rec - Read hba fcf record for update eligible fcf bmask.
12107 * @phba: pointer to lpfc hba data structure.
12108 * @fcf_index: FCF table entry offset.
12109 *
12110 * This routine is invoked to read an FCF record indicated by @fcf_index to
12111 * determine whether it's eligible for FLOGI round robin failover list.
12112 *
12113 * Return 0 if the mailbox command is submitted sucessfully, none 0
12114 * otherwise.
12115 **/
12116int
12117lpfc_sli4_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
12118{
12119 int rc = 0, error;
12120 LPFC_MBOXQ_t *mboxq;
12121
12122 mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
12123 if (!mboxq) {
12124 lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT,
12125 "2758 Failed to allocate mbox for "
12126 "READ_FCF cmd\n");
12127 error = -ENOMEM;
12128 goto fail_fcf_read;
12129 }
12130 /* Construct the read FCF record mailbox command */
12131 rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
12132 if (rc) {
12133 error = -EINVAL;
12134 goto fail_fcf_read;
12135 }
12136 /* Issue the mailbox command asynchronously */
12137 mboxq->vport = phba->pport;
12138 mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_rec;
12139 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
12140 if (rc == MBX_NOT_FINISHED)
12141 error = -EIO;
12142 else
12143 error = 0;
12144
12145fail_fcf_read:
12146 if (error && mboxq)
12147 lpfc_sli4_mbox_cmd_free(phba, mboxq);
12148 return error;
12149}
12150
12151/**
12152 * lpfc_sli4_fcf_rr_next_index_get - Get next eligible fcf record index
12153 * @phba: pointer to lpfc hba data structure.
12154 *
12155 * This routine is to get the next eligible FCF record index in a round
12156 * robin fashion. If the next eligible FCF record index equals to the
12157 * initial round robin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF)
12158 * shall be returned, otherwise, the next eligible FCF record's index
12159 * shall be returned.
12160 **/
12161uint16_t
12162lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba)
12163{
12164 uint16_t next_fcf_index;
12165
12166 /* Search from the currently registered FCF index */
12167 next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask,
12168 LPFC_SLI4_FCF_TBL_INDX_MAX,
12169 phba->fcf.current_rec.fcf_indx);
12170 /* Wrap around condition on phba->fcf.fcf_rr_bmask */
12171 if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX)
12172 next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask,
12173 LPFC_SLI4_FCF_TBL_INDX_MAX, 0);
12174 /* Round robin failover stop condition */
12175 if (next_fcf_index == phba->fcf.fcf_rr_init_indx)
12176 return LPFC_FCOE_FCF_NEXT_NONE;
12177
12178 return next_fcf_index;
12179}
12180
12181/**
12182 * lpfc_sli4_fcf_rr_index_set - Set bmask with eligible fcf record index
12183 * @phba: pointer to lpfc hba data structure.
12184 *
12185 * This routine sets the FCF record index in to the eligible bmask for
12186 * round robin failover search. It checks to make sure that the index
12187 * does not go beyond the range of the driver allocated bmask dimension
12188 * before setting the bit.
12189 *
12190 * Returns 0 if the index bit successfully set, otherwise, it returns
12191 * -EINVAL.
12192 **/
12193int
12194lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index)
12195{
12196 if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
12197 lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
12198 "2610 HBA FCF index reached driver's "
12199 "book keeping dimension: fcf_index:%d, "
12200 "driver_bmask_max:%d\n",
12201 fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
12202 return -EINVAL;
12203 }
12204 /* Set the eligible FCF record index bmask */
12205 set_bit(fcf_index, phba->fcf.fcf_rr_bmask);
12206
12207 return 0;
12208}
12209
12210/**
12211 * lpfc_sli4_fcf_rr_index_set - Clear bmask from eligible fcf record index
12212 * @phba: pointer to lpfc hba data structure.
12213 *
12214 * This routine clears the FCF record index from the eligible bmask for
12215 * round robin failover search. It checks to make sure that the index
12216 * does not go beyond the range of the driver allocated bmask dimension
12217 * before clearing the bit.
12218 **/
12219void
12220lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index)
12221{
12222 if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
12223 lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
12224 "2762 HBA FCF index goes beyond driver's "
12225 "book keeping dimension: fcf_index:%d, "
12226 "driver_bmask_max:%d\n",
12227 fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
12228 return;
12229 }
12230 /* Clear the eligible FCF record index bmask */
12231 clear_bit(fcf_index, phba->fcf.fcf_rr_bmask);
12232}
12233
12234/**
11997 * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table 12235 * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table
11998 * @phba: pointer to lpfc hba data structure. 12236 * @phba: pointer to lpfc hba data structure.
11999 * 12237 *
@@ -12014,21 +12252,40 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
12014 shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, 12252 shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
12015 &redisc_fcf->header.cfg_shdr.response); 12253 &redisc_fcf->header.cfg_shdr.response);
12016 if (shdr_status || shdr_add_status) { 12254 if (shdr_status || shdr_add_status) {
12017 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 12255 lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
12018 "2746 Requesting for FCF rediscovery failed " 12256 "2746 Requesting for FCF rediscovery failed "
12019 "status x%x add_status x%x\n", 12257 "status x%x add_status x%x\n",
12020 shdr_status, shdr_add_status); 12258 shdr_status, shdr_add_status);
12021 /* 12259 if (phba->fcf.fcf_flag & FCF_ACVL_DISC) {
12022 * Request failed, last resort to re-try current 12260 spin_lock_irq(&phba->hbalock);
12023 * registered FCF entry 12261 phba->fcf.fcf_flag &= ~FCF_ACVL_DISC;
12024 */ 12262 spin_unlock_irq(&phba->hbalock);
12025 lpfc_retry_pport_discovery(phba); 12263 /*
12026 } else 12264 * CVL event triggered FCF rediscover request failed,
12265 * last resort to re-try current registered FCF entry.
12266 */
12267 lpfc_retry_pport_discovery(phba);
12268 } else {
12269 spin_lock_irq(&phba->hbalock);
12270 phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
12271 spin_unlock_irq(&phba->hbalock);
12272 /*
12273 * DEAD FCF event triggered FCF rediscover request
12274 * failed, last resort to fail over as a link down
12275 * to FCF registration.
12276 */
12277 lpfc_sli4_fcf_dead_failthrough(phba);
12278 }
12279 } else {
12280 lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
12281 "2775 Start FCF rediscovery quiescent period "
12282 "wait timer before scaning FCF table\n");
12027 /* 12283 /*
12028 * Start FCF rediscovery wait timer for pending FCF 12284 * Start FCF rediscovery wait timer for pending FCF
12029 * before rescan FCF record table. 12285 * before rescan FCF record table.
12030 */ 12286 */
12031 lpfc_fcf_redisc_wait_start_timer(phba); 12287 lpfc_fcf_redisc_wait_start_timer(phba);
12288 }
12032 12289
12033 mempool_free(mbox, phba->mbox_mem_pool); 12290 mempool_free(mbox, phba->mbox_mem_pool);
12034} 12291}
@@ -12047,6 +12304,9 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba)
12047 struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf; 12304 struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf;
12048 int rc, length; 12305 int rc, length;
12049 12306
12307 /* Cancel retry delay timers to all vports before FCF rediscover */
12308 lpfc_cancel_all_vport_retry_delay_timer(phba);
12309
12050 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 12310 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
12051 if (!mbox) { 12311 if (!mbox) {
12052 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 12312 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
@@ -12078,6 +12338,31 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba)
12078} 12338}
12079 12339
12080/** 12340/**
12341 * lpfc_sli4_fcf_dead_failthrough - Failthrough routine to fcf dead event
12342 * @phba: pointer to lpfc hba data structure.
12343 *
12344 * This function is the failover routine as a last resort to the FCF DEAD
12345 * event when driver failed to perform fast FCF failover.
12346 **/
12347void
12348lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *phba)
12349{
12350 uint32_t link_state;
12351
12352 /*
12353 * Last resort as FCF DEAD event failover will treat this as
12354 * a link down, but save the link state because we don't want
12355 * it to be changed to Link Down unless it is already down.
12356 */
12357 link_state = phba->link_state;
12358 lpfc_linkdown(phba);
12359 phba->link_state = link_state;
12360
12361 /* Unregister FCF if no devices connected to it */
12362 lpfc_unregister_unused_fcf(phba);
12363}
12364
12365/**
12081 * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. 12366 * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled.
12082 * @phba: pointer to lpfc hba data structure. 12367 * @phba: pointer to lpfc hba data structure.
12083 * 12368 *
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index dfcf5437d1f5..b4a639c47616 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -62,6 +62,7 @@ struct lpfc_iocbq {
62#define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */ 62#define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */
63#define LPFC_EXCHANGE_BUSY 0x40 /* SLI4 hba reported XB in response */ 63#define LPFC_EXCHANGE_BUSY 0x40 /* SLI4 hba reported XB in response */
64#define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */ 64#define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */
65#define DSS_SECURITY_OP 0x100 /* security IO */
65 66
66#define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */ 67#define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */
67#define LPFC_FIP_ELS_ID_SHIFT 14 68#define LPFC_FIP_ELS_ID_SHIFT 14
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 86308836600f..4a35e7b9bc5b 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -153,15 +153,27 @@ struct lpfc_fcf {
153#define FCF_REGISTERED 0x02 /* FCF registered with FW */ 153#define FCF_REGISTERED 0x02 /* FCF registered with FW */
154#define FCF_SCAN_DONE 0x04 /* FCF table scan done */ 154#define FCF_SCAN_DONE 0x04 /* FCF table scan done */
155#define FCF_IN_USE 0x08 /* Atleast one discovery completed */ 155#define FCF_IN_USE 0x08 /* Atleast one discovery completed */
156#define FCF_REDISC_PEND 0x10 /* FCF rediscovery pending */ 156#define FCF_INIT_DISC 0x10 /* Initial FCF discovery */
157#define FCF_REDISC_EVT 0x20 /* FCF rediscovery event to worker thread */ 157#define FCF_DEAD_DISC 0x20 /* FCF DEAD fast FCF failover discovery */
158#define FCF_REDISC_FOV 0x40 /* Post FCF rediscovery fast failover */ 158#define FCF_ACVL_DISC 0x40 /* All CVL fast FCF failover discovery */
159#define FCF_DISCOVERY (FCF_INIT_DISC | FCF_DEAD_DISC | FCF_ACVL_DISC)
160#define FCF_REDISC_PEND 0x80 /* FCF rediscovery pending */
161#define FCF_REDISC_EVT 0x100 /* FCF rediscovery event to worker thread */
162#define FCF_REDISC_FOV 0x200 /* Post FCF rediscovery fast failover */
159 uint32_t addr_mode; 163 uint32_t addr_mode;
164 uint16_t fcf_rr_init_indx;
160 struct lpfc_fcf_rec current_rec; 165 struct lpfc_fcf_rec current_rec;
161 struct lpfc_fcf_rec failover_rec; 166 struct lpfc_fcf_rec failover_rec;
162 struct timer_list redisc_wait; 167 struct timer_list redisc_wait;
168 unsigned long *fcf_rr_bmask; /* Eligible FCF indexes for RR failover */
163}; 169};
164 170
171/*
172 * Maximum FCF table index, it is for driver internal book keeping, it
173 * just needs to be no less than the supported HBA's FCF table size.
174 */
175#define LPFC_SLI4_FCF_TBL_INDX_MAX 32
176
165#define LPFC_REGION23_SIGNATURE "RG23" 177#define LPFC_REGION23_SIGNATURE "RG23"
166#define LPFC_REGION23_VERSION 1 178#define LPFC_REGION23_VERSION 1
167#define LPFC_REGION23_LAST_REC 0xff 179#define LPFC_REGION23_LAST_REC 0xff
@@ -431,11 +443,18 @@ enum lpfc_sge_type {
431 SCSI_BUFF_TYPE 443 SCSI_BUFF_TYPE
432}; 444};
433 445
446enum lpfc_sgl_state {
447 SGL_FREED,
448 SGL_ALLOCATED,
449 SGL_XRI_ABORTED
450};
451
434struct lpfc_sglq { 452struct lpfc_sglq {
435 /* lpfc_sglqs are used in double linked lists */ 453 /* lpfc_sglqs are used in double linked lists */
436 struct list_head list; 454 struct list_head list;
437 struct list_head clist; 455 struct list_head clist;
438 enum lpfc_sge_type buff_type; /* is this a scsi sgl */ 456 enum lpfc_sge_type buff_type; /* is this a scsi sgl */
457 enum lpfc_sgl_state state;
439 uint16_t iotag; /* pre-assigned IO tag */ 458 uint16_t iotag; /* pre-assigned IO tag */
440 uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */ 459 uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */
441 struct sli4_sge *sgl; /* pre-assigned SGL */ 460 struct sli4_sge *sgl; /* pre-assigned SGL */
@@ -463,8 +482,8 @@ void lpfc_sli4_mbox_cmd_free(struct lpfc_hba *, struct lpfcMboxq *);
463void lpfc_sli4_mbx_sge_set(struct lpfcMboxq *, uint32_t, dma_addr_t, uint32_t); 482void lpfc_sli4_mbx_sge_set(struct lpfcMboxq *, uint32_t, dma_addr_t, uint32_t);
464void lpfc_sli4_mbx_sge_get(struct lpfcMboxq *, uint32_t, 483void lpfc_sli4_mbx_sge_get(struct lpfcMboxq *, uint32_t,
465 struct lpfc_mbx_sge *); 484 struct lpfc_mbx_sge *);
466int lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *, struct lpfcMboxq *, 485int lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *, struct lpfcMboxq *,
467 uint16_t); 486 uint16_t);
468 487
469void lpfc_sli4_hba_reset(struct lpfc_hba *); 488void lpfc_sli4_hba_reset(struct lpfc_hba *);
470struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t, 489struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t,
@@ -523,8 +542,13 @@ int lpfc_sli4_init_vpi(struct lpfc_hba *, uint16_t);
523uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool); 542uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool);
524uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool); 543uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool);
525void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t); 544void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t);
526int lpfc_sli4_read_fcf_record(struct lpfc_hba *, uint16_t); 545int lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *, uint16_t);
527void lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *, LPFC_MBOXQ_t *); 546int lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *, uint16_t);
547int lpfc_sli4_read_fcf_rec(struct lpfc_hba *, uint16_t);
548void lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
549void lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
550void lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
551int lpfc_sli4_unregister_fcf(struct lpfc_hba *);
528int lpfc_sli4_post_status_check(struct lpfc_hba *); 552int lpfc_sli4_post_status_check(struct lpfc_hba *);
529uint8_t lpfc_sli4_mbox_opcode_get(struct lpfc_hba *, struct lpfcMboxq *); 553uint8_t lpfc_sli4_mbox_opcode_get(struct lpfc_hba *, struct lpfcMboxq *);
530 554
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index ac276aa46fba..013deec5dae8 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
18 * included with this package. * 18 * included with this package. *
19 *******************************************************************/ 19 *******************************************************************/
20 20
21#define LPFC_DRIVER_VERSION "8.3.9" 21#define LPFC_DRIVER_VERSION "8.3.10"
22#define LPFC_DRIVER_NAME "lpfc" 22#define LPFC_DRIVER_NAME "lpfc"
23#define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" 23#define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp"
24#define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" 24#define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp"
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index dc86e873102a..869f76cbc58a 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -123,7 +123,12 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport)
123 } 123 }
124 mb = &pmb->u.mb; 124 mb = &pmb->u.mb;
125 125
126 lpfc_read_sparam(phba, pmb, vport->vpi); 126 rc = lpfc_read_sparam(phba, pmb, vport->vpi);
127 if (rc) {
128 mempool_free(pmb, phba->mbox_mem_pool);
129 return -ENOMEM;
130 }
131
127 /* 132 /*
128 * Grab buffer pointer and clear context1 so we can use 133 * Grab buffer pointer and clear context1 so we can use
129 * lpfc_sli_issue_box_wait 134 * lpfc_sli_issue_box_wait
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 24223473f573..60de85091502 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -1433,6 +1433,10 @@ int osd_finalize_request(struct osd_request *or,
1433 cdbh->command_specific_options |= or->attributes_mode; 1433 cdbh->command_specific_options |= or->attributes_mode;
1434 if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) { 1434 if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) {
1435 ret = _osd_req_finalize_attr_page(or); 1435 ret = _osd_req_finalize_attr_page(or);
1436 if (ret) {
1437 OSD_DEBUG("_osd_req_finalize_attr_page failed\n");
1438 return ret;
1439 }
1436 } else { 1440 } else {
1437 /* TODO: I think that for the GET_ATTR command these 2 should 1441 /* TODO: I think that for the GET_ATTR command these 2 should
1438 * be reversed to keep them in execution order (for embeded 1442 * be reversed to keep them in execution order (for embeded
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
index bd88349b8526..2c146b44d95f 100644
--- a/drivers/scsi/raid_class.c
+++ b/drivers/scsi/raid_class.c
@@ -63,6 +63,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev)
63 * emulated RAID devices, so start with SCSI */ 63 * emulated RAID devices, so start with SCSI */
64 struct raid_internal *i = ac_to_raid_internal(cont); 64 struct raid_internal *i = ac_to_raid_internal(cont);
65 65
66#if defined(CONFIG_SCSI) || defined(CONFIG_SCSI_MODULE)
66 if (scsi_is_sdev_device(dev)) { 67 if (scsi_is_sdev_device(dev)) {
67 struct scsi_device *sdev = to_scsi_device(dev); 68 struct scsi_device *sdev = to_scsi_device(dev);
68 69
@@ -71,6 +72,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev)
71 72
72 return i->f->is_raid(dev); 73 return i->f->is_raid(dev);
73 } 74 }
75#endif
74 /* FIXME: look at other subsystems too */ 76 /* FIXME: look at other subsystems too */
75 return 0; 77 return 0;
76} 78}
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 79660ee3e211..1d5b72173dd8 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -1232,6 +1232,15 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr,
1232{ 1232{
1233 struct fc_vport *vport = transport_class_to_vport(dev); 1233 struct fc_vport *vport = transport_class_to_vport(dev);
1234 struct Scsi_Host *shost = vport_to_shost(vport); 1234 struct Scsi_Host *shost = vport_to_shost(vport);
1235 unsigned long flags;
1236
1237 spin_lock_irqsave(shost->host_lock, flags);
1238 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
1239 spin_unlock_irqrestore(shost->host_lock, flags);
1240 return -EBUSY;
1241 }
1242 vport->flags |= FC_VPORT_DELETING;
1243 spin_unlock_irqrestore(shost->host_lock, flags);
1235 1244
1236 fc_queue_work(shost, &vport->vport_delete_work); 1245 fc_queue_work(shost, &vport->vport_delete_work);
1237 return count; 1246 return count;
@@ -1821,6 +1830,9 @@ store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr,
1821 list_for_each_entry(vport, &fc_host->vports, peers) { 1830 list_for_each_entry(vport, &fc_host->vports, peers) {
1822 if ((vport->channel == 0) && 1831 if ((vport->channel == 0) &&
1823 (vport->port_name == wwpn) && (vport->node_name == wwnn)) { 1832 (vport->port_name == wwpn) && (vport->node_name == wwnn)) {
1833 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))
1834 break;
1835 vport->flags |= FC_VPORT_DELETING;
1824 match = 1; 1836 match = 1;
1825 break; 1837 break;
1826 } 1838 }
@@ -3370,18 +3382,6 @@ fc_vport_terminate(struct fc_vport *vport)
3370 unsigned long flags; 3382 unsigned long flags;
3371 int stat; 3383 int stat;
3372 3384
3373 spin_lock_irqsave(shost->host_lock, flags);
3374 if (vport->flags & FC_VPORT_CREATING) {
3375 spin_unlock_irqrestore(shost->host_lock, flags);
3376 return -EBUSY;
3377 }
3378 if (vport->flags & (FC_VPORT_DEL)) {
3379 spin_unlock_irqrestore(shost->host_lock, flags);
3380 return -EALREADY;
3381 }
3382 vport->flags |= FC_VPORT_DELETING;
3383 spin_unlock_irqrestore(shost->host_lock, flags);
3384
3385 if (i->f->vport_delete) 3385 if (i->f->vport_delete)
3386 stat = i->f->vport_delete(vport); 3386 stat = i->f->vport_delete(vport);
3387 else 3387 else
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 83881dfb33c0..7b75c8a2a49d 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1948,7 +1948,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
1948{ 1948{
1949 struct request_queue *q = sdkp->disk->queue; 1949 struct request_queue *q = sdkp->disk->queue;
1950 unsigned int sector_sz = sdkp->device->sector_size; 1950 unsigned int sector_sz = sdkp->device->sector_size;
1951 const int vpd_len = 32; 1951 const int vpd_len = 64;
1952 unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); 1952 unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL);
1953 1953
1954 if (!buffer || 1954 if (!buffer ||
@@ -1998,7 +1998,7 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
1998{ 1998{
1999 unsigned char *buffer; 1999 unsigned char *buffer;
2000 u16 rot; 2000 u16 rot;
2001 const int vpd_len = 32; 2001 const int vpd_len = 64;
2002 2002
2003 buffer = kmalloc(vpd_len, GFP_KERNEL); 2003 buffer = kmalloc(vpd_len, GFP_KERNEL);
2004 2004
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index ff92b46f5153..ae5196aae1a5 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -338,7 +338,8 @@ struct iscsi_host {
338extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, 338extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth,
339 int reason); 339 int reason);
340extern int iscsi_eh_abort(struct scsi_cmnd *sc); 340extern int iscsi_eh_abort(struct scsi_cmnd *sc);
341extern int iscsi_eh_target_reset(struct scsi_cmnd *sc); 341extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
342extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);
342extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); 343extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
343extern int iscsi_queuecommand(struct scsi_cmnd *sc, 344extern int iscsi_queuecommand(struct scsi_cmnd *sc,
344 void (*done)(struct scsi_cmnd *)); 345 void (*done)(struct scsi_cmnd *));