aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJitendra Bhivare <jitendra.bhivare@broadcom.com>2016-08-19 05:50:18 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-08-23 22:42:44 -0400
commitd1d5ca887c0ee60ec6c6e42db0c1073155a09d32 (patch)
treec0c8d6ebf44cf776fb5beb5c351068e8ae6890bf
parentf79929deb56e1b8053c36adf7ee8d34b39e673a8 (diff)
scsi: be2iscsi: Add TPE recovery feature
After UE is detected, check for recoverable error by reading SLIPORT SEMAPHORE register. If transient parity error i.e. 0xExxx then schedule recovery work on driver wq. FLag this error to prevent any transactions for the duration of ue2rp to restart polling. After that, if FW becomes ready then recover port. Wake up processes in wq before going offline. Wait for process to execute before cleaning up. Signed-off-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c173
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h4
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c14
-rw-r--r--drivers/scsi/be2iscsi/be_main.c733
-rw-r--r--drivers/scsi/be2iscsi/be_main.h6
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c128
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h1
7 files changed, 629 insertions, 430 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 6f3cd82c4295..ad7405d6821f 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -21,6 +21,78 @@
21#include "be.h" 21#include "be.h"
22#include "be_mgmt.h" 22#include "be_mgmt.h"
23 23
24/* UE Status Low CSR */
25static const char * const desc_ue_status_low[] = {
26 "CEV",
27 "CTX",
28 "DBUF",
29 "ERX",
30 "Host",
31 "MPU",
32 "NDMA",
33 "PTC ",
34 "RDMA ",
35 "RXF ",
36 "RXIPS ",
37 "RXULP0 ",
38 "RXULP1 ",
39 "RXULP2 ",
40 "TIM ",
41 "TPOST ",
42 "TPRE ",
43 "TXIPS ",
44 "TXULP0 ",
45 "TXULP1 ",
46 "UC ",
47 "WDMA ",
48 "TXULP2 ",
49 "HOST1 ",
50 "P0_OB_LINK ",
51 "P1_OB_LINK ",
52 "HOST_GPIO ",
53 "MBOX ",
54 "AXGMAC0",
55 "AXGMAC1",
56 "JTAG",
57 "MPU_INTPEND"
58};
59
60/* UE Status High CSR */
61static const char * const desc_ue_status_hi[] = {
62 "LPCMEMHOST",
63 "MGMT_MAC",
64 "PCS0ONLINE",
65 "MPU_IRAM",
66 "PCS1ONLINE",
67 "PCTL0",
68 "PCTL1",
69 "PMEM",
70 "RR",
71 "TXPB",
72 "RXPP",
73 "XAUI",
74 "TXP",
75 "ARM",
76 "IPC",
77 "HOST2",
78 "HOST3",
79 "HOST4",
80 "HOST5",
81 "HOST6",
82 "HOST7",
83 "HOST8",
84 "HOST9",
85 "NETC",
86 "Unknown",
87 "Unknown",
88 "Unknown",
89 "Unknown",
90 "Unknown",
91 "Unknown",
92 "Unknown",
93 "Unknown"
94};
95
24struct be_mcc_wrb *alloc_mcc_wrb(struct beiscsi_hba *phba, 96struct be_mcc_wrb *alloc_mcc_wrb(struct beiscsi_hba *phba,
25 unsigned int *ref_tag) 97 unsigned int *ref_tag)
26{ 98{
@@ -185,6 +257,16 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
185 phba->ctrl.mcc_tag_status[tag], 257 phba->ctrl.mcc_tag_status[tag],
186 msecs_to_jiffies( 258 msecs_to_jiffies(
187 BEISCSI_HOST_MBX_TIMEOUT)); 259 BEISCSI_HOST_MBX_TIMEOUT));
260 /**
261 * Return EIO if port is being disabled. Associated DMA memory, if any,
262 * is freed by the caller. When port goes offline, MCCQ is cleaned up
263 * so does WRB.
264 */
265 if (!test_bit(BEISCSI_HBA_ONLINE, &phba->state)) {
266 clear_bit(MCC_TAG_STATE_RUNNING,
267 &phba->ctrl.ptag_state[tag].tag_state);
268 return -EIO;
269 }
188 270
189 /** 271 /**
190 * If MBOX cmd timeout expired, tag and resource allocated 272 * If MBOX cmd timeout expired, tag and resource allocated
@@ -538,7 +620,6 @@ static int be_mbox_db_ready_poll(struct be_ctrl_info *ctrl)
538 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 620 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
539 "BC_%d : FW Timed Out\n"); 621 "BC_%d : FW Timed Out\n");
540 set_bit(BEISCSI_HBA_FW_TIMEOUT, &phba->state); 622 set_bit(BEISCSI_HBA_FW_TIMEOUT, &phba->state);
541 beiscsi_ue_detect(phba);
542 return -EBUSY; 623 return -EBUSY;
543} 624}
544 625
@@ -1584,6 +1665,12 @@ int beiscsi_init_sliport(struct beiscsi_hba *phba)
1584 if (!status) 1665 if (!status)
1585 return -EIO; 1666 return -EIO;
1586 1667
1668 /* clear all error states after checking FW rdy */
1669 phba->state &= ~BEISCSI_HBA_IN_ERR;
1670
1671 /* check again UER support */
1672 phba->state &= ~BEISCSI_HBA_UER_SUPP;
1673
1587 /* 1674 /*
1588 * SLI COMMON_FUNCTION_RESET completion is indicated by BMBX RDY bit. 1675 * SLI COMMON_FUNCTION_RESET completion is indicated by BMBX RDY bit.
1589 * It should clean up any stale info in FW for this fn. 1676 * It should clean up any stale info in FW for this fn.
@@ -1647,3 +1734,87 @@ int beiscsi_cmd_iscsi_cleanup(struct beiscsi_hba *phba, unsigned short ulp)
1647 mutex_unlock(&ctrl->mbox_lock); 1734 mutex_unlock(&ctrl->mbox_lock);
1648 return status; 1735 return status;
1649} 1736}
1737
1738/*
1739 * beiscsi_detect_ue()- Detect Unrecoverable Error on adapter
1740 * @phba: Driver priv structure
1741 *
1742 * Read registers linked to UE and check for the UE status
1743 **/
1744int beiscsi_detect_ue(struct beiscsi_hba *phba)
1745{
1746 uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
1747 uint32_t ue_hi = 0, ue_lo = 0;
1748 uint8_t i = 0;
1749 int ret = 0;
1750
1751 pci_read_config_dword(phba->pcidev,
1752 PCICFG_UE_STATUS_LOW, &ue_lo);
1753 pci_read_config_dword(phba->pcidev,
1754 PCICFG_UE_STATUS_MASK_LOW,
1755 &ue_mask_lo);
1756 pci_read_config_dword(phba->pcidev,
1757 PCICFG_UE_STATUS_HIGH,
1758 &ue_hi);
1759 pci_read_config_dword(phba->pcidev,
1760 PCICFG_UE_STATUS_MASK_HI,
1761 &ue_mask_hi);
1762
1763 ue_lo = (ue_lo & ~ue_mask_lo);
1764 ue_hi = (ue_hi & ~ue_mask_hi);
1765
1766
1767 if (ue_lo || ue_hi) {
1768 set_bit(BEISCSI_HBA_IN_UE, &phba->state);
1769 __beiscsi_log(phba, KERN_ERR,
1770 "BC_%d : HBA error detected\n");
1771 ret = 1;
1772 }
1773
1774 if (ue_lo) {
1775 for (i = 0; ue_lo; ue_lo >>= 1, i++) {
1776 if (ue_lo & 1)
1777 __beiscsi_log(phba, KERN_ERR,
1778 "BC_%d : UE_LOW %s bit set\n",
1779 desc_ue_status_low[i]);
1780 }
1781 }
1782
1783 if (ue_hi) {
1784 for (i = 0; ue_hi; ue_hi >>= 1, i++) {
1785 if (ue_hi & 1)
1786 __beiscsi_log(phba, KERN_ERR,
1787 "BC_%d : UE_HIGH %s bit set\n",
1788 desc_ue_status_hi[i]);
1789 }
1790 }
1791 return ret;
1792}
1793
1794/*
1795 * beiscsi_detect_tpe()- Detect Transient Parity Error on adapter
1796 * @phba: Driver priv structure
1797 *
1798 * Read SLIPORT SEMAPHORE register to check for UER
1799 *
1800 **/
1801int beiscsi_detect_tpe(struct beiscsi_hba *phba)
1802{
1803 u32 post, status;
1804 int ret = 0;
1805
1806 post = beiscsi_get_post_stage(phba);
1807 status = post & POST_STAGE_MASK;
1808 if ((status & POST_ERR_RECOVERY_CODE_MASK) ==
1809 POST_STAGE_RECOVERABLE_ERR) {
1810 set_bit(BEISCSI_HBA_IN_TPE, &phba->state);
1811 __beiscsi_log(phba, KERN_INFO,
1812 "BC_%d : HBA error recoverable: 0x%x\n", post);
1813 ret = 1;
1814 } else {
1815 __beiscsi_log(phba, KERN_INFO,
1816 "BC_%d : HBA in UE: 0x%x\n", post);
1817 }
1818
1819 return ret;
1820}
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index cf4239987acf..26d7921f48a4 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -770,6 +770,10 @@ int beiscsi_init_sliport(struct beiscsi_hba *phba);
770 770
771int beiscsi_cmd_iscsi_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num); 771int beiscsi_cmd_iscsi_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num);
772 772
773int beiscsi_detect_ue(struct beiscsi_hba *phba);
774
775int beiscsi_detect_tpe(struct beiscsi_hba *phba);
776
773int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl, 777int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
774 struct be_queue_info *eq, int eq_delay); 778 struct be_queue_info *eq, int eq_delay);
775 779
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 677491a4b0b4..35f7d3aab366 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -58,7 +58,7 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
58 beiscsi_ep = ep->dd_data; 58 beiscsi_ep = ep->dd_data;
59 phba = beiscsi_ep->phba; 59 phba = beiscsi_ep->phba;
60 60
61 if (beiscsi_hba_in_error(phba)) { 61 if (!beiscsi_hba_is_online(phba)) {
62 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 62 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
63 "BS_%d : HBA in error 0x%lx\n", phba->state); 63 "BS_%d : HBA in error 0x%lx\n", phba->state);
64 return NULL; 64 return NULL;
@@ -444,7 +444,7 @@ int beiscsi_iface_set_param(struct Scsi_Host *shost,
444 uint32_t rm_len = dt_len; 444 uint32_t rm_len = dt_len;
445 int ret; 445 int ret;
446 446
447 if (beiscsi_hba_in_error(phba)) { 447 if (!beiscsi_hba_is_online(phba)) {
448 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 448 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
449 "BS_%d : HBA in error 0x%lx\n", phba->state); 449 "BS_%d : HBA in error 0x%lx\n", phba->state);
450 return -EBUSY; 450 return -EBUSY;
@@ -587,7 +587,7 @@ int beiscsi_iface_get_param(struct iscsi_iface *iface,
587 587
588 if (param_type != ISCSI_NET_PARAM) 588 if (param_type != ISCSI_NET_PARAM)
589 return 0; 589 return 0;
590 if (beiscsi_hba_in_error(phba)) { 590 if (!beiscsi_hba_is_online(phba)) {
591 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 591 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
592 "BS_%d : HBA in error 0x%lx\n", phba->state); 592 "BS_%d : HBA in error 0x%lx\n", phba->state);
593 return -EBUSY; 593 return -EBUSY;
@@ -797,7 +797,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
797 struct beiscsi_hba *phba = iscsi_host_priv(shost); 797 struct beiscsi_hba *phba = iscsi_host_priv(shost);
798 int status = 0; 798 int status = 0;
799 799
800 if (beiscsi_hba_in_error(phba)) { 800 if (!beiscsi_hba_is_online(phba)) {
801 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 801 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
802 "BS_%d : HBA in error 0x%lx\n", phba->state); 802 "BS_%d : HBA in error 0x%lx\n", phba->state);
803 return -EBUSY; 803 return -EBUSY;
@@ -945,7 +945,7 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
945 945
946 phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 946 phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
947 947
948 if (beiscsi_hba_in_error(phba)) { 948 if (!beiscsi_hba_is_online(phba)) {
949 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 949 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
950 "BS_%d : HBA in error 0x%lx\n", phba->state); 950 "BS_%d : HBA in error 0x%lx\n", phba->state);
951 return -EBUSY; 951 return -EBUSY;
@@ -1175,7 +1175,7 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
1175 } 1175 }
1176 1176
1177 phba = iscsi_host_priv(shost); 1177 phba = iscsi_host_priv(shost);
1178 if (beiscsi_hba_in_error(phba)) { 1178 if (!beiscsi_hba_is_online(phba)) {
1179 ret = -EIO; 1179 ret = -EIO;
1180 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1180 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1181 "BS_%d : HBA in error 0x%lx\n", phba->state); 1181 "BS_%d : HBA in error 0x%lx\n", phba->state);
@@ -1335,7 +1335,7 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
1335 tcp_upload_flag = CONNECTION_UPLOAD_ABORT; 1335 tcp_upload_flag = CONNECTION_UPLOAD_ABORT;
1336 } 1336 }
1337 1337
1338 if (beiscsi_hba_in_error(phba)) { 1338 if (!beiscsi_hba_is_online(phba)) {
1339 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1339 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1340 "BS_%d : HBA in error 0x%lx\n", phba->state); 1340 "BS_%d : HBA in error 0x%lx\n", phba->state);
1341 goto free_ep; 1341 goto free_ep;
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index e7741072995a..0625bd0c449f 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -3525,10 +3525,53 @@ static void free_wrb_handles(struct beiscsi_hba *phba)
3525 3525
3526static void be_mcc_queues_destroy(struct beiscsi_hba *phba) 3526static void be_mcc_queues_destroy(struct beiscsi_hba *phba)
3527{ 3527{
3528 struct be_queue_info *q;
3529 struct be_ctrl_info *ctrl = &phba->ctrl; 3528 struct be_ctrl_info *ctrl = &phba->ctrl;
3529 struct be_dma_mem *ptag_mem;
3530 struct be_queue_info *q;
3531 int i, tag;
3530 3532
3531 q = &phba->ctrl.mcc_obj.q; 3533 q = &phba->ctrl.mcc_obj.q;
3534 for (i = 0; i < MAX_MCC_CMD; i++) {
3535 tag = i + 1;
3536 if (!test_bit(MCC_TAG_STATE_RUNNING,
3537 &ctrl->ptag_state[tag].tag_state))
3538 continue;
3539
3540 if (test_bit(MCC_TAG_STATE_TIMEOUT,
3541 &ctrl->ptag_state[tag].tag_state)) {
3542 ptag_mem = &ctrl->ptag_state[tag].tag_mem_state;
3543 if (ptag_mem->size) {
3544 pci_free_consistent(ctrl->pdev,
3545 ptag_mem->size,
3546 ptag_mem->va,
3547 ptag_mem->dma);
3548 ptag_mem->size = 0;
3549 }
3550 continue;
3551 }
3552 /**
3553 * If MCC is still active and waiting then wake up the process.
3554 * We are here only because port is going offline. The process
3555 * sees that (BEISCSI_HBA_ONLINE is cleared) and EIO error is
3556 * returned for the operation and allocated memory cleaned up.
3557 */
3558 if (waitqueue_active(&ctrl->mcc_wait[tag])) {
3559 ctrl->mcc_tag_status[tag] = MCC_STATUS_FAILED;
3560 ctrl->mcc_tag_status[tag] |= CQE_VALID_MASK;
3561 wake_up_interruptible(&ctrl->mcc_wait[tag]);
3562 /*
3563 * Control tag info gets reinitialized in enable
3564 * so wait for the process to clear running state.
3565 */
3566 while (test_bit(MCC_TAG_STATE_RUNNING,
3567 &ctrl->ptag_state[tag].tag_state))
3568 schedule_timeout_uninterruptible(HZ);
3569 }
3570 /**
3571 * For MCC with tag_states MCC_TAG_STATE_ASYNC and
3572 * MCC_TAG_STATE_IGNORE nothing needs to done.
3573 */
3574 }
3532 if (q->created) { 3575 if (q->created) {
3533 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_MCCQ); 3576 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_MCCQ);
3534 be_queue_free(phba, q); 3577 be_queue_free(phba, q);
@@ -3541,69 +3584,6 @@ static void be_mcc_queues_destroy(struct beiscsi_hba *phba)
3541 } 3584 }
3542} 3585}
3543 3586
3544static void hwi_cleanup_port(struct beiscsi_hba *phba)
3545{
3546 struct be_queue_info *q;
3547 struct be_ctrl_info *ctrl = &phba->ctrl;
3548 struct hwi_controller *phwi_ctrlr;
3549 struct hwi_context_memory *phwi_context;
3550 struct hwi_async_pdu_context *pasync_ctx;
3551 int i, eq_for_mcc, ulp_num;
3552
3553 phwi_ctrlr = phba->phwi_ctrlr;
3554 phwi_context = phwi_ctrlr->phwi_ctxt;
3555
3556 be_cmd_iscsi_remove_template_hdr(ctrl);
3557
3558 for (i = 0; i < phba->params.cxns_per_ctrl; i++) {
3559 q = &phwi_context->be_wrbq[i];
3560 if (q->created)
3561 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_WRBQ);
3562 }
3563 kfree(phwi_context->be_wrbq);
3564 free_wrb_handles(phba);
3565
3566 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
3567 if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
3568
3569 q = &phwi_context->be_def_hdrq[ulp_num];
3570 if (q->created)
3571 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ);
3572
3573 q = &phwi_context->be_def_dataq[ulp_num];
3574 if (q->created)
3575 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ);
3576
3577 pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx[ulp_num];
3578 }
3579 }
3580
3581 beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL);
3582
3583 for (i = 0; i < (phba->num_cpus); i++) {
3584 q = &phwi_context->be_cq[i];
3585 if (q->created) {
3586 be_queue_free(phba, q);
3587 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
3588 }
3589 }
3590
3591 be_mcc_queues_destroy(phba);
3592 if (phba->msix_enabled)
3593 eq_for_mcc = 1;
3594 else
3595 eq_for_mcc = 0;
3596 for (i = 0; i < (phba->num_cpus + eq_for_mcc); i++) {
3597 q = &phwi_context->be_eq[i].q;
3598 if (q->created) {
3599 be_queue_free(phba, q);
3600 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
3601 }
3602 }
3603 /* last communication, indicate driver is unloading */
3604 beiscsi_cmd_special_wrb(&phba->ctrl, 0);
3605}
3606
3607static int be_mcc_queues_create(struct beiscsi_hba *phba, 3587static int be_mcc_queues_create(struct beiscsi_hba *phba,
3608 struct hwi_context_memory *phwi_context) 3588 struct hwi_context_memory *phwi_context)
3609{ 3589{
@@ -3685,6 +3665,115 @@ static void find_num_cpus(struct beiscsi_hba *phba)
3685 } 3665 }
3686} 3666}
3687 3667
3668static void hwi_purge_eq(struct beiscsi_hba *phba)
3669{
3670 struct hwi_controller *phwi_ctrlr;
3671 struct hwi_context_memory *phwi_context;
3672 struct be_queue_info *eq;
3673 struct be_eq_entry *eqe = NULL;
3674 int i, eq_msix;
3675 unsigned int num_processed;
3676
3677 if (beiscsi_hba_in_error(phba))
3678 return;
3679
3680 phwi_ctrlr = phba->phwi_ctrlr;
3681 phwi_context = phwi_ctrlr->phwi_ctxt;
3682 if (phba->msix_enabled)
3683 eq_msix = 1;
3684 else
3685 eq_msix = 0;
3686
3687 for (i = 0; i < (phba->num_cpus + eq_msix); i++) {
3688 eq = &phwi_context->be_eq[i].q;
3689 eqe = queue_tail_node(eq);
3690 num_processed = 0;
3691 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
3692 & EQE_VALID_MASK) {
3693 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
3694 queue_tail_inc(eq);
3695 eqe = queue_tail_node(eq);
3696 num_processed++;
3697 }
3698
3699 if (num_processed)
3700 hwi_ring_eq_db(phba, eq->id, 1, num_processed, 1, 1);
3701 }
3702}
3703
3704static void hwi_cleanup_port(struct beiscsi_hba *phba)
3705{
3706 struct be_queue_info *q;
3707 struct be_ctrl_info *ctrl = &phba->ctrl;
3708 struct hwi_controller *phwi_ctrlr;
3709 struct hwi_context_memory *phwi_context;
3710 struct hwi_async_pdu_context *pasync_ctx;
3711 int i, eq_for_mcc, ulp_num;
3712
3713 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
3714 if (test_bit(ulp_num, &phba->fw_config.ulp_supported))
3715 beiscsi_cmd_iscsi_cleanup(phba, ulp_num);
3716
3717 /**
3718 * Purge all EQ entries that may have been left out. This is to
3719 * workaround a problem we've seen occasionally where driver gets an
3720 * interrupt with EQ entry bit set after stopping the controller.
3721 */
3722 hwi_purge_eq(phba);
3723
3724 phwi_ctrlr = phba->phwi_ctrlr;
3725 phwi_context = phwi_ctrlr->phwi_ctxt;
3726
3727 be_cmd_iscsi_remove_template_hdr(ctrl);
3728
3729 for (i = 0; i < phba->params.cxns_per_ctrl; i++) {
3730 q = &phwi_context->be_wrbq[i];
3731 if (q->created)
3732 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_WRBQ);
3733 }
3734 kfree(phwi_context->be_wrbq);
3735 free_wrb_handles(phba);
3736
3737 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
3738 if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
3739
3740 q = &phwi_context->be_def_hdrq[ulp_num];
3741 if (q->created)
3742 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ);
3743
3744 q = &phwi_context->be_def_dataq[ulp_num];
3745 if (q->created)
3746 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ);
3747
3748 pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx[ulp_num];
3749 }
3750 }
3751
3752 beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL);
3753
3754 for (i = 0; i < (phba->num_cpus); i++) {
3755 q = &phwi_context->be_cq[i];
3756 if (q->created) {
3757 be_queue_free(phba, q);
3758 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
3759 }
3760 }
3761
3762 be_mcc_queues_destroy(phba);
3763 if (phba->msix_enabled)
3764 eq_for_mcc = 1;
3765 else
3766 eq_for_mcc = 0;
3767 for (i = 0; i < (phba->num_cpus + eq_for_mcc); i++) {
3768 q = &phwi_context->be_eq[i].q;
3769 if (q->created) {
3770 be_queue_free(phba, q);
3771 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
3772 }
3773 }
3774 /* last communication, indicate driver is unloading */
3775 beiscsi_cmd_special_wrb(&phba->ctrl, 0);
3776}
3688static int hwi_init_port(struct beiscsi_hba *phba) 3777static int hwi_init_port(struct beiscsi_hba *phba)
3689{ 3778{
3690 struct hwi_controller *phwi_ctrlr; 3779 struct hwi_controller *phwi_ctrlr;
@@ -4206,50 +4295,11 @@ do_cleanup_ctrlr:
4206 return ret; 4295 return ret;
4207} 4296}
4208 4297
4209static void hwi_purge_eq(struct beiscsi_hba *phba)
4210{
4211 struct hwi_controller *phwi_ctrlr;
4212 struct hwi_context_memory *phwi_context;
4213 struct be_queue_info *eq;
4214 struct be_eq_entry *eqe = NULL;
4215 int i, eq_msix;
4216 unsigned int num_processed;
4217
4218 phwi_ctrlr = phba->phwi_ctrlr;
4219 phwi_context = phwi_ctrlr->phwi_ctxt;
4220 if (phba->msix_enabled)
4221 eq_msix = 1;
4222 else
4223 eq_msix = 0;
4224
4225 for (i = 0; i < (phba->num_cpus + eq_msix); i++) {
4226 eq = &phwi_context->be_eq[i].q;
4227 eqe = queue_tail_node(eq);
4228 num_processed = 0;
4229 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
4230 & EQE_VALID_MASK) {
4231 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
4232 queue_tail_inc(eq);
4233 eqe = queue_tail_node(eq);
4234 num_processed++;
4235 }
4236
4237 if (num_processed)
4238 hwi_ring_eq_db(phba, eq->id, 1, num_processed, 1, 1);
4239 }
4240}
4241
4242static void beiscsi_cleanup_port(struct beiscsi_hba *phba) 4298static void beiscsi_cleanup_port(struct beiscsi_hba *phba)
4243{ 4299{
4244 struct ulp_cid_info *ptr_cid_info = NULL; 4300 struct ulp_cid_info *ptr_cid_info = NULL;
4245 int ulp_num; 4301 int ulp_num;
4246 4302
4247 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
4248 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
4249 beiscsi_cmd_iscsi_cleanup(phba, ulp_num);
4250
4251 hwi_purge_eq(phba);
4252 hwi_cleanup_port(phba);
4253 kfree(phba->io_sgl_hndl_base); 4303 kfree(phba->io_sgl_hndl_base);
4254 kfree(phba->eh_sgl_hndl_base); 4304 kfree(phba->eh_sgl_hndl_base);
4255 kfree(phba->ep_array); 4305 kfree(phba->ep_array);
@@ -4266,7 +4316,6 @@ static void beiscsi_cleanup_port(struct beiscsi_hba *phba)
4266 } 4316 }
4267 } 4317 }
4268 } 4318 }
4269
4270} 4319}
4271 4320
4272/** 4321/**
@@ -4840,7 +4889,7 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
4840 * operational if FW still gets heartbeat from EP FW. Is management 4889 * operational if FW still gets heartbeat from EP FW. Is management
4841 * path really needed to continue further? 4890 * path really needed to continue further?
4842 */ 4891 */
4843 if (beiscsi_hba_in_error(phba)) 4892 if (!beiscsi_hba_is_online(phba))
4844 return -EIO; 4893 return -EIO;
4845 4894
4846 if (!io_task->conn->login_in_progress) 4895 if (!io_task->conn->login_in_progress)
@@ -4896,7 +4945,7 @@ static int beiscsi_bsg_request(struct bsg_job *job)
4896 shost = iscsi_job_to_shost(job); 4945 shost = iscsi_job_to_shost(job);
4897 phba = iscsi_host_priv(shost); 4946 phba = iscsi_host_priv(shost);
4898 4947
4899 if (beiscsi_hba_in_error(phba)) { 4948 if (!beiscsi_hba_is_online(phba)) {
4900 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 4949 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
4901 "BM_%d : HBA in error 0x%lx\n", phba->state); 4950 "BM_%d : HBA in error 0x%lx\n", phba->state);
4902 return -ENXIO; 4951 return -ENXIO;
@@ -4929,6 +4978,14 @@ static int beiscsi_bsg_request(struct bsg_job *job)
4929 phba->ctrl.mcc_tag_status[tag], 4978 phba->ctrl.mcc_tag_status[tag],
4930 msecs_to_jiffies( 4979 msecs_to_jiffies(
4931 BEISCSI_HOST_MBX_TIMEOUT)); 4980 BEISCSI_HOST_MBX_TIMEOUT));
4981
4982 if (!test_bit(BEISCSI_HBA_ONLINE, &phba->state)) {
4983 clear_bit(MCC_TAG_STATE_RUNNING,
4984 &phba->ctrl.ptag_state[tag].tag_state);
4985 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
4986 nonemb_cmd.va, nonemb_cmd.dma);
4987 return -EIO;
4988 }
4932 extd_status = (phba->ctrl.mcc_tag_status[tag] & 4989 extd_status = (phba->ctrl.mcc_tag_status[tag] &
4933 CQE_STATUS_ADDL_MASK) >> CQE_STATUS_ADDL_SHIFT; 4990 CQE_STATUS_ADDL_MASK) >> CQE_STATUS_ADDL_SHIFT;
4934 status = phba->ctrl.mcc_tag_status[tag] & CQE_STATUS_MASK; 4991 status = phba->ctrl.mcc_tag_status[tag] & CQE_STATUS_MASK;
@@ -4972,98 +5029,6 @@ void beiscsi_hba_attrs_init(struct beiscsi_hba *phba)
4972 beiscsi_log_enable_init(phba, beiscsi_log_enable); 5029 beiscsi_log_enable_init(phba, beiscsi_log_enable);
4973} 5030}
4974 5031
4975/*
4976 * beiscsi_quiesce()- Cleanup Driver resources
4977 * @phba: Instance Priv structure
4978 *
4979 * Free the OS and HW resources held by the driver
4980 **/
4981static void beiscsi_quiesce(struct beiscsi_hba *phba)
4982{
4983 struct hwi_controller *phwi_ctrlr;
4984 struct hwi_context_memory *phwi_context;
4985 struct be_eq_obj *pbe_eq;
4986 unsigned int i, msix_vec;
4987
4988 phwi_ctrlr = phba->phwi_ctrlr;
4989 phwi_context = phwi_ctrlr->phwi_ctxt;
4990 hwi_disable_intr(phba);
4991 if (phba->msix_enabled) {
4992 for (i = 0; i <= phba->num_cpus; i++) {
4993 msix_vec = phba->msix_entries[i].vector;
4994 free_irq(msix_vec, &phwi_context->be_eq[i]);
4995 kfree(phba->msi_name[i]);
4996 }
4997 } else
4998 if (phba->pcidev->irq)
4999 free_irq(phba->pcidev->irq, phba);
5000 pci_disable_msix(phba->pcidev);
5001 cancel_delayed_work_sync(&phba->eqd_update);
5002 cancel_work_sync(&phba->boot_work);
5003 del_timer_sync(&phba->hw_check);
5004
5005 for (i = 0; i < phba->num_cpus; i++) {
5006 pbe_eq = &phwi_context->be_eq[i];
5007 irq_poll_disable(&pbe_eq->iopoll);
5008 }
5009
5010 /* PCI_ERR is set then check if driver is not unloading */
5011 if (test_bit(BEISCSI_HBA_RUNNING, &phba->state) &&
5012 test_bit(BEISCSI_HBA_PCI_ERR, &phba->state)) {
5013 hwi_cleanup_port(phba);
5014 return;
5015 }
5016
5017 destroy_workqueue(phba->wq);
5018 beiscsi_cleanup_port(phba);
5019 beiscsi_free_mem(phba);
5020
5021 beiscsi_unmap_pci_function(phba);
5022 pci_free_consistent(phba->pcidev,
5023 phba->ctrl.mbox_mem_alloced.size,
5024 phba->ctrl.mbox_mem_alloced.va,
5025 phba->ctrl.mbox_mem_alloced.dma);
5026}
5027
5028static void beiscsi_remove(struct pci_dev *pcidev)
5029{
5030 struct beiscsi_hba *phba = NULL;
5031
5032 phba = pci_get_drvdata(pcidev);
5033 if (!phba) {
5034 dev_err(&pcidev->dev, "beiscsi_remove called with no phba\n");
5035 return;
5036 }
5037
5038 clear_bit(BEISCSI_HBA_RUNNING, &phba->state);
5039 beiscsi_iface_destroy_default(phba);
5040 iscsi_host_remove(phba->shost);
5041 beiscsi_quiesce(phba);
5042 /* after cancelling boot_work */
5043 iscsi_boot_destroy_kset(phba->boot_struct.boot_kset);
5044 pci_dev_put(phba->pcidev);
5045 iscsi_host_free(phba->shost);
5046 pci_disable_pcie_error_reporting(pcidev);
5047 pci_set_drvdata(pcidev, NULL);
5048 pci_release_regions(pcidev);
5049 pci_disable_device(pcidev);
5050}
5051
5052static void beiscsi_msix_enable(struct beiscsi_hba *phba)
5053{
5054 int i, status;
5055
5056 for (i = 0; i <= phba->num_cpus; i++)
5057 phba->msix_entries[i].entry = i;
5058
5059 status = pci_enable_msix_range(phba->pcidev, phba->msix_entries,
5060 phba->num_cpus + 1, phba->num_cpus + 1);
5061 if (status > 0)
5062 phba->msix_enabled = true;
5063
5064 return;
5065}
5066
5067void beiscsi_start_boot_work(struct beiscsi_hba *phba, unsigned int s_handle) 5032void beiscsi_start_boot_work(struct beiscsi_hba *phba, unsigned int s_handle)
5068{ 5033{
5069 if (phba->boot_struct.boot_kset) 5034 if (phba->boot_struct.boot_kset)
@@ -5179,7 +5144,6 @@ static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf)
5179 return rc; 5144 return rc;
5180} 5145}
5181 5146
5182
5183static umode_t beiscsi_tgt_get_attr_visibility(void *data, int type) 5147static umode_t beiscsi_tgt_get_attr_visibility(void *data, int type)
5184{ 5148{
5185 umode_t rc = 0; 5149 umode_t rc = 0;
@@ -5212,7 +5176,6 @@ static umode_t beiscsi_ini_get_attr_visibility(void *data, int type)
5212 return rc; 5176 return rc;
5213} 5177}
5214 5178
5215
5216static umode_t beiscsi_eth_get_attr_visibility(void *data, int type) 5179static umode_t beiscsi_eth_get_attr_visibility(void *data, int type)
5217{ 5180{
5218 umode_t rc = 0; 5181 umode_t rc = 0;
@@ -5300,7 +5263,7 @@ static void beiscsi_boot_work(struct work_struct *work)
5300 struct boot_struct *bs = &phba->boot_struct; 5263 struct boot_struct *bs = &phba->boot_struct;
5301 unsigned int tag = 0; 5264 unsigned int tag = 0;
5302 5265
5303 if (beiscsi_hba_in_error(phba)) 5266 if (!beiscsi_hba_is_online(phba))
5304 return; 5267 return;
5305 5268
5306 beiscsi_log(phba, KERN_INFO, 5269 beiscsi_log(phba, KERN_INFO,
@@ -5339,19 +5302,6 @@ static void beiscsi_boot_work(struct work_struct *work)
5339 } 5302 }
5340} 5303}
5341 5304
5342static void beiscsi_hw_health_check(unsigned long ptr)
5343{
5344 struct beiscsi_hba *phba;
5345
5346 phba = (struct beiscsi_hba *)ptr;
5347 beiscsi_ue_detect(phba);
5348 if (test_bit(BEISCSI_HBA_IN_UE, &phba->state))
5349 return;
5350
5351 mod_timer(&phba->hw_check,
5352 jiffies + msecs_to_jiffies(BEISCSI_UE_DETECT_INTERVAL));
5353}
5354
5355static void beiscsi_eqd_update_work(struct work_struct *work) 5305static void beiscsi_eqd_update_work(struct work_struct *work)
5356{ 5306{
5357 struct hwi_context_memory *phwi_context; 5307 struct hwi_context_memory *phwi_context;
@@ -5365,7 +5315,7 @@ static void beiscsi_eqd_update_work(struct work_struct *work)
5365 unsigned long now; 5315 unsigned long now;
5366 5316
5367 phba = container_of(work, struct beiscsi_hba, eqd_update.work); 5317 phba = container_of(work, struct beiscsi_hba, eqd_update.work);
5368 if (beiscsi_hba_in_error(phba)) 5318 if (!beiscsi_hba_is_online(phba))
5369 return; 5319 return;
5370 5320
5371 phwi_ctrlr = phba->phwi_ctrlr; 5321 phwi_ctrlr = phba->phwi_ctrlr;
@@ -5408,6 +5358,219 @@ static void beiscsi_eqd_update_work(struct work_struct *work)
5408 msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL)); 5358 msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL));
5409} 5359}
5410 5360
5361static void beiscsi_msix_enable(struct beiscsi_hba *phba)
5362{
5363 int i, status;
5364
5365 for (i = 0; i <= phba->num_cpus; i++)
5366 phba->msix_entries[i].entry = i;
5367
5368 status = pci_enable_msix_range(phba->pcidev, phba->msix_entries,
5369 phba->num_cpus + 1, phba->num_cpus + 1);
5370 if (status > 0)
5371 phba->msix_enabled = true;
5372}
5373
5374static void beiscsi_hw_tpe_check(unsigned long ptr)
5375{
5376 struct beiscsi_hba *phba;
5377 u32 wait;
5378
5379 phba = (struct beiscsi_hba *)ptr;
5380 /* if not TPE, do nothing */
5381 if (!beiscsi_detect_tpe(phba))
5382 return;
5383
5384 /* wait default 4000ms before recovering */
5385 wait = 4000;
5386 if (phba->ue2rp > BEISCSI_UE_DETECT_INTERVAL)
5387 wait = phba->ue2rp - BEISCSI_UE_DETECT_INTERVAL;
5388 queue_delayed_work(phba->wq, &phba->recover_port,
5389 msecs_to_jiffies(wait));
5390}
5391
5392static void beiscsi_hw_health_check(unsigned long ptr)
5393{
5394 struct beiscsi_hba *phba;
5395
5396 phba = (struct beiscsi_hba *)ptr;
5397 beiscsi_detect_ue(phba);
5398 if (beiscsi_detect_ue(phba)) {
5399 __beiscsi_log(phba, KERN_ERR,
5400 "BM_%d : port in error: %lx\n", phba->state);
5401 /* detect TPE if UER supported */
5402 if (!test_bit(BEISCSI_HBA_UER_SUPP, &phba->state))
5403 return;
5404 /* modify this timer to check TPE */
5405 phba->hw_check.function = beiscsi_hw_tpe_check;
5406 }
5407
5408 mod_timer(&phba->hw_check,
5409 jiffies + msecs_to_jiffies(BEISCSI_UE_DETECT_INTERVAL));
5410}
5411
5412/*
5413 * beiscsi_enable_port()- Enables the disabled port.
5414 * Only port resources freed in disable function are reallocated.
5415 * This is called in HBA error handling path.
5416 *
5417 * @phba: Instance of driver private structure
5418 *
5419 **/
5420static int beiscsi_enable_port(struct beiscsi_hba *phba)
5421{
5422 struct hwi_context_memory *phwi_context;
5423 struct hwi_controller *phwi_ctrlr;
5424 struct be_eq_obj *pbe_eq;
5425 int ret, i;
5426
5427 if (test_bit(BEISCSI_HBA_ONLINE, &phba->state)) {
5428 __beiscsi_log(phba, KERN_ERR,
5429 "BM_%d : %s : port is online %lx\n",
5430 __func__, phba->state);
5431 return 0;
5432 }
5433
5434 ret = beiscsi_init_sliport(phba);
5435 if (ret)
5436 return ret;
5437
5438 if (enable_msix)
5439 find_num_cpus(phba);
5440 else
5441 phba->num_cpus = 1;
5442 if (enable_msix) {
5443 beiscsi_msix_enable(phba);
5444 if (!phba->msix_enabled)
5445 phba->num_cpus = 1;
5446 }
5447
5448 beiscsi_get_params(phba);
5449 /* Re-enable UER. If different TPE occurs then it is recoverable. */
5450 beiscsi_set_uer_feature(phba);
5451
5452 phba->shost->max_id = phba->params.cxns_per_ctrl;
5453 phba->shost->can_queue = phba->params.ios_per_ctrl;
5454 ret = hwi_init_controller(phba);
5455 if (ret) {
5456 __beiscsi_log(phba, KERN_ERR,
5457 "BM_%d : init controller failed %d\n", ret);
5458 goto disable_msix;
5459 }
5460
5461 for (i = 0; i < MAX_MCC_CMD; i++) {
5462 init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]);
5463 phba->ctrl.mcc_tag[i] = i + 1;
5464 phba->ctrl.mcc_tag_status[i + 1] = 0;
5465 phba->ctrl.mcc_tag_available++;
5466 }
5467
5468 phwi_ctrlr = phba->phwi_ctrlr;
5469 phwi_context = phwi_ctrlr->phwi_ctxt;
5470 for (i = 0; i < phba->num_cpus; i++) {
5471 pbe_eq = &phwi_context->be_eq[i];
5472 irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget, be_iopoll);
5473 }
5474
5475 i = (phba->msix_enabled) ? i : 0;
5476 /* Work item for MCC handling */
5477 pbe_eq = &phwi_context->be_eq[i];
5478 INIT_WORK(&pbe_eq->mcc_work, beiscsi_mcc_work);
5479
5480 ret = beiscsi_init_irqs(phba);
5481 if (ret < 0) {
5482 __beiscsi_log(phba, KERN_ERR,
5483 "BM_%d : setup IRQs failed %d\n", ret);
5484 goto cleanup_port;
5485 }
5486 hwi_enable_intr(phba);
5487 /* port operational: clear all error bits */
5488 set_bit(BEISCSI_HBA_ONLINE, &phba->state);
5489 __beiscsi_log(phba, KERN_INFO,
5490 "BM_%d : port online: 0x%lx\n", phba->state);
5491
5492 /* start hw_check timer and eqd_update work */
5493 schedule_delayed_work(&phba->eqd_update,
5494 msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL));
5495
5496 /**
5497 * Timer function gets modified for TPE detection.
5498 * Always reinit to do health check first.
5499 */
5500 phba->hw_check.function = beiscsi_hw_health_check;
5501 mod_timer(&phba->hw_check,
5502 jiffies + msecs_to_jiffies(BEISCSI_UE_DETECT_INTERVAL));
5503 return 0;
5504
5505cleanup_port:
5506 for (i = 0; i < phba->num_cpus; i++) {
5507 pbe_eq = &phwi_context->be_eq[i];
5508 irq_poll_disable(&pbe_eq->iopoll);
5509 }
5510 hwi_cleanup_port(phba);
5511
5512disable_msix:
5513 if (phba->msix_enabled)
5514 pci_disable_msix(phba->pcidev);
5515
5516 return ret;
5517}
5518
5519/*
5520 * beiscsi_disable_port()- Disable port and cleanup driver resources.
5521 * This is called in HBA error handling and driver removal.
5522 * @phba: Instance Priv structure
5523 * @unload: indicate driver is unloading
5524 *
5525 * Free the OS and HW resources held by the driver
5526 **/
5527static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload)
5528{
5529 struct hwi_context_memory *phwi_context;
5530 struct hwi_controller *phwi_ctrlr;
5531 struct be_eq_obj *pbe_eq;
5532 unsigned int i, msix_vec;
5533
5534 if (!test_and_clear_bit(BEISCSI_HBA_ONLINE, &phba->state))
5535 return;
5536
5537 phwi_ctrlr = phba->phwi_ctrlr;
5538 phwi_context = phwi_ctrlr->phwi_ctxt;
5539 hwi_disable_intr(phba);
5540 if (phba->msix_enabled) {
5541 for (i = 0; i <= phba->num_cpus; i++) {
5542 msix_vec = phba->msix_entries[i].vector;
5543 free_irq(msix_vec, &phwi_context->be_eq[i]);
5544 kfree(phba->msi_name[i]);
5545 }
5546 } else
5547 if (phba->pcidev->irq)
5548 free_irq(phba->pcidev->irq, phba);
5549 pci_disable_msix(phba->pcidev);
5550
5551 for (i = 0; i < phba->num_cpus; i++) {
5552 pbe_eq = &phwi_context->be_eq[i];
5553 irq_poll_disable(&pbe_eq->iopoll);
5554 }
5555 cancel_delayed_work_sync(&phba->eqd_update);
5556 cancel_work_sync(&phba->boot_work);
5557 /* WQ might be running cancel queued mcc_work if we are not exiting */
5558 if (!unload && beiscsi_hba_in_error(phba)) {
5559 pbe_eq = &phwi_context->be_eq[i];
5560 cancel_work_sync(&pbe_eq->mcc_work);
5561 }
5562 hwi_cleanup_port(phba);
5563}
5564
5565static void beiscsi_recover_port(struct work_struct *work)
5566{
5567 struct beiscsi_hba *phba;
5568
5569 phba = container_of(work, struct beiscsi_hba, recover_port.work);
5570 iscsi_host_for_each_session(phba->shost, beiscsi_session_fail);
5571 beiscsi_disable_port(phba, 0);
5572 beiscsi_enable_port(phba);
5573}
5411 5574
5412static pci_ers_result_t beiscsi_eeh_err_detected(struct pci_dev *pdev, 5575static pci_ers_result_t beiscsi_eeh_err_detected(struct pci_dev *pdev,
5413 pci_channel_state_t state) 5576 pci_channel_state_t state)
@@ -5420,7 +5583,11 @@ static pci_ers_result_t beiscsi_eeh_err_detected(struct pci_dev *pdev,
5420 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 5583 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
5421 "BM_%d : EEH error detected\n"); 5584 "BM_%d : EEH error detected\n");
5422 5585
5423 beiscsi_quiesce(phba); 5586 /* first stop UE detection when PCI error detected */
5587 del_timer_sync(&phba->hw_check);
5588 cancel_delayed_work_sync(&phba->recover_port);
5589
5590 beiscsi_disable_port(phba, 0);
5424 5591
5425 if (state == pci_channel_io_perm_failure) { 5592 if (state == pci_channel_io_perm_failure) {
5426 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 5593 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -5476,82 +5643,16 @@ static pci_ers_result_t beiscsi_eeh_reset(struct pci_dev *pdev)
5476 5643
5477static void beiscsi_eeh_resume(struct pci_dev *pdev) 5644static void beiscsi_eeh_resume(struct pci_dev *pdev)
5478{ 5645{
5479 int ret, i; 5646 struct beiscsi_hba *phba;
5480 struct be_eq_obj *pbe_eq; 5647 int ret;
5481 struct beiscsi_hba *phba = NULL;
5482 struct hwi_controller *phwi_ctrlr;
5483 struct hwi_context_memory *phwi_context;
5484 5648
5485 phba = (struct beiscsi_hba *)pci_get_drvdata(pdev); 5649 phba = (struct beiscsi_hba *)pci_get_drvdata(pdev);
5486 pci_save_state(pdev); 5650 pci_save_state(pdev);
5487 5651
5488 if (enable_msix) 5652 ret = beiscsi_enable_port(phba);
5489 find_num_cpus(phba);
5490 else
5491 phba->num_cpus = 1;
5492
5493 if (enable_msix) {
5494 beiscsi_msix_enable(phba);
5495 if (!phba->msix_enabled)
5496 phba->num_cpus = 1;
5497 }
5498
5499 ret = beiscsi_init_sliport(phba);
5500 if (ret) 5653 if (ret)
5501 goto ret_err; 5654 __beiscsi_log(phba, KERN_ERR,
5502 5655 "BM_%d : AER EEH resume failed\n");
5503 beiscsi_get_params(phba);
5504 phba->shost->max_id = phba->params.cxns_per_ctrl;
5505 phba->shost->can_queue = phba->params.ios_per_ctrl;
5506 ret = hwi_init_controller(phba);
5507 if (ret) {
5508 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
5509 "BM_%d : beiscsi_eeh_resume -"
5510 "Failed to initialize beiscsi_hba.\n");
5511 goto ret_err;
5512 }
5513
5514 for (i = 0; i < MAX_MCC_CMD; i++) {
5515 init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]);
5516 phba->ctrl.mcc_tag[i] = i + 1;
5517 phba->ctrl.mcc_tag_status[i + 1] = 0;
5518 phba->ctrl.mcc_tag_available++;
5519 }
5520
5521 phwi_ctrlr = phba->phwi_ctrlr;
5522 phwi_context = phwi_ctrlr->phwi_ctxt;
5523
5524 for (i = 0; i < phba->num_cpus; i++) {
5525 pbe_eq = &phwi_context->be_eq[i];
5526 irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget,
5527 be_iopoll);
5528 }
5529
5530 i = (phba->msix_enabled) ? i : 0;
5531 /* Work item for MCC handling */
5532 pbe_eq = &phwi_context->be_eq[i];
5533 INIT_WORK(&pbe_eq->mcc_work, beiscsi_mcc_work);
5534
5535 ret = beiscsi_init_irqs(phba);
5536 if (ret < 0) {
5537 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
5538 "BM_%d : beiscsi_eeh_resume - "
5539 "Failed to beiscsi_init_irqs\n");
5540 goto ret_err;
5541 }
5542
5543 hwi_enable_intr(phba);
5544 clear_bit(BEISCSI_HBA_PCI_ERR, &phba->state);
5545
5546 /* start hw_check timer and eqd_update work */
5547 schedule_delayed_work(&phba->eqd_update,
5548 msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL));
5549 mod_timer(&phba->hw_check,
5550 jiffies + msecs_to_jiffies(BEISCSI_UE_DETECT_INTERVAL));
5551 return;
5552ret_err:
5553 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
5554 "BM_%d : AER EEH Resume Failed\n");
5555} 5656}
5556 5657
5557static int beiscsi_dev_probe(struct pci_dev *pcidev, 5658static int beiscsi_dev_probe(struct pci_dev *pcidev,
@@ -5623,7 +5724,6 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5623 if (ret) 5724 if (ret)
5624 goto hba_free; 5725 goto hba_free;
5625 5726
5626 set_bit(BEISCSI_HBA_RUNNING, &phba->state);
5627 spin_lock_init(&phba->io_sgl_lock); 5727 spin_lock_init(&phba->io_sgl_lock);
5628 spin_lock_init(&phba->mgmt_sgl_lock); 5728 spin_lock_init(&phba->mgmt_sgl_lock);
5629 spin_lock_init(&phba->async_pdu_lock); 5729 spin_lock_init(&phba->async_pdu_lock);
@@ -5690,8 +5790,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5690 5790
5691 for (i = 0; i < phba->num_cpus; i++) { 5791 for (i = 0; i < phba->num_cpus; i++) {
5692 pbe_eq = &phwi_context->be_eq[i]; 5792 pbe_eq = &phwi_context->be_eq[i];
5693 irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget, 5793 irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget, be_iopoll);
5694 be_iopoll);
5695 } 5794 }
5696 5795
5697 i = (phba->msix_enabled) ? i : 0; 5796 i = (phba->msix_enabled) ? i : 0;
@@ -5708,9 +5807,15 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5708 } 5807 }
5709 hwi_enable_intr(phba); 5808 hwi_enable_intr(phba);
5710 5809
5711 if (iscsi_host_add(phba->shost, &phba->pcidev->dev)) 5810 ret = iscsi_host_add(phba->shost, &phba->pcidev->dev);
5811 if (ret)
5712 goto free_blkenbld; 5812 goto free_blkenbld;
5713 5813
5814 /* set online bit after port is operational */
5815 set_bit(BEISCSI_HBA_ONLINE, &phba->state);
5816 __beiscsi_log(phba, KERN_INFO,
5817 "BM_%d : port online: 0x%lx\n", phba->state);
5818
5714 INIT_WORK(&phba->boot_work, beiscsi_boot_work); 5819 INIT_WORK(&phba->boot_work, beiscsi_boot_work);
5715 ret = beiscsi_boot_get_shandle(phba, &s_handle); 5820 ret = beiscsi_boot_get_shandle(phba, &s_handle);
5716 if (ret > 0) { 5821 if (ret > 0) {
@@ -5726,6 +5831,8 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5726 beiscsi_iface_create_default(phba); 5831 beiscsi_iface_create_default(phba);
5727 schedule_delayed_work(&phba->eqd_update, 5832 schedule_delayed_work(&phba->eqd_update,
5728 msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL)); 5833 msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL));
5834
5835 INIT_DELAYED_WORK(&phba->recover_port, beiscsi_recover_port);
5729 /** 5836 /**
5730 * Start UE detection here. UE before this will cause stall in probe 5837 * Start UE detection here. UE before this will cause stall in probe
5731 * and eventually fail the probe. 5838 * and eventually fail the probe.
@@ -5747,6 +5854,7 @@ free_blkenbld:
5747 irq_poll_disable(&pbe_eq->iopoll); 5854 irq_poll_disable(&pbe_eq->iopoll);
5748 } 5855 }
5749free_twq: 5856free_twq:
5857 hwi_cleanup_port(phba);
5750 beiscsi_cleanup_port(phba); 5858 beiscsi_cleanup_port(phba);
5751 beiscsi_free_mem(phba); 5859 beiscsi_free_mem(phba);
5752free_port: 5860free_port:
@@ -5767,6 +5875,48 @@ disable_pci:
5767 return ret; 5875 return ret;
5768} 5876}
5769 5877
5878static void beiscsi_remove(struct pci_dev *pcidev)
5879{
5880 struct beiscsi_hba *phba = NULL;
5881
5882 phba = pci_get_drvdata(pcidev);
5883 if (!phba) {
5884 dev_err(&pcidev->dev, "beiscsi_remove called with no phba\n");
5885 return;
5886 }
5887
5888 /* first stop UE detection before unloading */
5889 del_timer_sync(&phba->hw_check);
5890 cancel_delayed_work_sync(&phba->recover_port);
5891
5892 beiscsi_iface_destroy_default(phba);
5893 iscsi_host_remove(phba->shost);
5894 beiscsi_disable_port(phba, 1);
5895
5896 /* after cancelling boot_work */
5897 iscsi_boot_destroy_kset(phba->boot_struct.boot_kset);
5898
5899 /* free all resources */
5900 destroy_workqueue(phba->wq);
5901 beiscsi_cleanup_port(phba);
5902 beiscsi_free_mem(phba);
5903
5904 /* ctrl uninit */
5905 beiscsi_unmap_pci_function(phba);
5906 pci_free_consistent(phba->pcidev,
5907 phba->ctrl.mbox_mem_alloced.size,
5908 phba->ctrl.mbox_mem_alloced.va,
5909 phba->ctrl.mbox_mem_alloced.dma);
5910
5911 pci_dev_put(phba->pcidev);
5912 iscsi_host_free(phba->shost);
5913 pci_disable_pcie_error_reporting(pcidev);
5914 pci_set_drvdata(pcidev, NULL);
5915 pci_release_regions(pcidev);
5916 pci_disable_device(pcidev);
5917}
5918
5919
5770static struct pci_error_handlers beiscsi_eeh_handlers = { 5920static struct pci_error_handlers beiscsi_eeh_handlers = {
5771 .error_detected = beiscsi_eeh_err_detected, 5921 .error_detected = beiscsi_eeh_err_detected,
5772 .slot_reset = beiscsi_eeh_reset, 5922 .slot_reset = beiscsi_eeh_reset,
@@ -5814,7 +5964,6 @@ static struct pci_driver beiscsi_pci_driver = {
5814 .err_handler = &beiscsi_eeh_handlers 5964 .err_handler = &beiscsi_eeh_handlers
5815}; 5965};
5816 5966
5817
5818static int __init beiscsi_module_init(void) 5967static int __init beiscsi_module_init(void)
5819{ 5968{
5820 int ret; 5969 int ret;
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 4cdb34c3de5d..1fd6c1868366 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -393,7 +393,7 @@ struct beiscsi_hba {
393 } fw_config; 393 } fw_config;
394 394
395 unsigned long state; 395 unsigned long state;
396#define BEISCSI_HBA_RUNNING 0 396#define BEISCSI_HBA_ONLINE 0
397#define BEISCSI_HBA_LINK_UP 1 397#define BEISCSI_HBA_LINK_UP 1
398#define BEISCSI_HBA_BOOT_FOUND 2 398#define BEISCSI_HBA_BOOT_FOUND 2
399#define BEISCSI_HBA_BOOT_WORK 3 399#define BEISCSI_HBA_BOOT_WORK 3
@@ -417,6 +417,7 @@ struct beiscsi_hba {
417 /* check for UE every 1000ms */ 417 /* check for UE every 1000ms */
418#define BEISCSI_UE_DETECT_INTERVAL 1000 418#define BEISCSI_UE_DETECT_INTERVAL 1000
419 u32 ue2rp; 419 u32 ue2rp;
420 struct delayed_work recover_port;
420 421
421 bool mac_addr_set; 422 bool mac_addr_set;
422 u8 mac_address[ETH_ALEN]; 423 u8 mac_address[ETH_ALEN];
@@ -455,6 +456,9 @@ struct beiscsi_hba {
455}; 456};
456 457
457#define beiscsi_hba_in_error(phba) ((phba)->state & BEISCSI_HBA_IN_ERR) 458#define beiscsi_hba_in_error(phba) ((phba)->state & BEISCSI_HBA_IN_ERR)
459#define beiscsi_hba_is_online(phba) \
460 (!beiscsi_hba_in_error((phba)) && \
461 test_bit(BEISCSI_HBA_ONLINE, &phba->state))
458 462
459struct beiscsi_session { 463struct beiscsi_session {
460 struct pci_pool *bhs_pool; 464 struct pci_pool *bhs_pool;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index a844299ea979..736eca38ea0b 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -24,134 +24,6 @@
24#include "be_iscsi.h" 24#include "be_iscsi.h"
25#include "be_main.h" 25#include "be_main.h"
26 26
27/* UE Status Low CSR */
28static const char * const desc_ue_status_low[] = {
29 "CEV",
30 "CTX",
31 "DBUF",
32 "ERX",
33 "Host",
34 "MPU",
35 "NDMA",
36 "PTC ",
37 "RDMA ",
38 "RXF ",
39 "RXIPS ",
40 "RXULP0 ",
41 "RXULP1 ",
42 "RXULP2 ",
43 "TIM ",
44 "TPOST ",
45 "TPRE ",
46 "TXIPS ",
47 "TXULP0 ",
48 "TXULP1 ",
49 "UC ",
50 "WDMA ",
51 "TXULP2 ",
52 "HOST1 ",
53 "P0_OB_LINK ",
54 "P1_OB_LINK ",
55 "HOST_GPIO ",
56 "MBOX ",
57 "AXGMAC0",
58 "AXGMAC1",
59 "JTAG",
60 "MPU_INTPEND"
61};
62
63/* UE Status High CSR */
64static const char * const desc_ue_status_hi[] = {
65 "LPCMEMHOST",
66 "MGMT_MAC",
67 "PCS0ONLINE",
68 "MPU_IRAM",
69 "PCS1ONLINE",
70 "PCTL0",
71 "PCTL1",
72 "PMEM",
73 "RR",
74 "TXPB",
75 "RXPP",
76 "XAUI",
77 "TXP",
78 "ARM",
79 "IPC",
80 "HOST2",
81 "HOST3",
82 "HOST4",
83 "HOST5",
84 "HOST6",
85 "HOST7",
86 "HOST8",
87 "HOST9",
88 "NETC",
89 "Unknown",
90 "Unknown",
91 "Unknown",
92 "Unknown",
93 "Unknown",
94 "Unknown",
95 "Unknown",
96 "Unknown"
97};
98
99/*
100 * beiscsi_ue_detect()- Detect Unrecoverable Error on adapter
101 * @phba: Driver priv structure
102 *
103 * Read registers linked to UE and check for the UE status
104 **/
105void beiscsi_ue_detect(struct beiscsi_hba *phba)
106{
107 uint32_t ue_hi = 0, ue_lo = 0;
108 uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
109 uint8_t i = 0;
110
111 pci_read_config_dword(phba->pcidev,
112 PCICFG_UE_STATUS_LOW, &ue_lo);
113 pci_read_config_dword(phba->pcidev,
114 PCICFG_UE_STATUS_MASK_LOW,
115 &ue_mask_lo);
116 pci_read_config_dword(phba->pcidev,
117 PCICFG_UE_STATUS_HIGH,
118 &ue_hi);
119 pci_read_config_dword(phba->pcidev,
120 PCICFG_UE_STATUS_MASK_HI,
121 &ue_mask_hi);
122
123 ue_lo = (ue_lo & ~ue_mask_lo);
124 ue_hi = (ue_hi & ~ue_mask_hi);
125
126
127 if (ue_lo || ue_hi) {
128 set_bit(BEISCSI_HBA_IN_UE, &phba->state);
129 beiscsi_log(phba, KERN_ERR,
130 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
131 "BG_%d : HBA error detected\n");
132 }
133
134 if (ue_lo) {
135 for (i = 0; ue_lo; ue_lo >>= 1, i++) {
136 if (ue_lo & 1)
137 beiscsi_log(phba, KERN_ERR,
138 BEISCSI_LOG_CONFIG,
139 "BG_%d : UE_LOW %s bit set\n",
140 desc_ue_status_low[i]);
141 }
142 }
143
144 if (ue_hi) {
145 for (i = 0; ue_hi; ue_hi >>= 1, i++) {
146 if (ue_hi & 1)
147 beiscsi_log(phba, KERN_ERR,
148 BEISCSI_LOG_CONFIG,
149 "BG_%d : UE_HIGH %s bit set\n",
150 desc_ue_status_hi[i]);
151 }
152 }
153}
154
155int beiscsi_modify_eq_delay(struct beiscsi_hba *phba, 27int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
156 struct be_set_eqd *set_eqd, 28 struct be_set_eqd *set_eqd,
157 int num) 29 int num)
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index dab128fb2ce3..ee6fd7e663cd 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -329,7 +329,6 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
329 struct wrb_handle *pwrb_handle, 329 struct wrb_handle *pwrb_handle,
330 struct hwi_wrb_context *pwrb_context); 330 struct hwi_wrb_context *pwrb_context);
331 331
332void beiscsi_ue_detect(struct beiscsi_hba *phba);
333int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, 332int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
334 struct be_set_eqd *, int num); 333 struct be_set_eqd *, int num);
335 334