aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJitendra Bhivare <jitendra.bhivare@broadcom.com>2016-08-19 05:50:11 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-08-23 22:42:43 -0400
commit9122e991cebb90a7225109ed7627950f485c5f58 (patch)
tree9e4037cf4b5eaa4a4336d3e8b74d36ffa45b021c
parenta30950161954a046421b26fbf55a873ae27b1e25 (diff)
scsi: be2iscsi: Fix checks for HBA in error state
Save ue_detected and fw_timeout errors in state field of beiscsi_hba. BEISCSI_HBA_RUNNING BEISCSI_HBA_LINK_UP BEISCSI_HBA_BOOT_FOUND BEISCSI_HBA_PCI_ERR BEISCSI_HBA_FW_TIMEOUT BEISCSI_HBA_IN_UE Make sure no PCI transaction happens once in error state. Add checks in IO path to detect HBA in error. Skip hwi_purge_eq step which can't be done in error state. 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.c28
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c81
-rw-r--r--drivers/scsi/be2iscsi/be_main.c97
-rw-r--r--drivers/scsi/be2iscsi/be_main.h36
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c5
5 files changed, 134 insertions, 113 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 403296239ae9..f16de6cf2678 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -152,8 +152,11 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
152 struct be_cmd_resp_hdr *mbx_resp_hdr; 152 struct be_cmd_resp_hdr *mbx_resp_hdr;
153 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 153 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
154 154
155 if (beiscsi_error(phba)) 155 if (beiscsi_hba_in_error(phba)) {
156 return -EPERM; 156 clear_bit(MCC_TAG_STATE_RUNNING,
157 &phba->ctrl.ptag_state[tag].tag_state);
158 return -EIO;
159 }
157 160
158 /* wait for the mccq completion */ 161 /* wait for the mccq completion */
159 rc = wait_event_interruptible_timeout( 162 rc = wait_event_interruptible_timeout(
@@ -315,13 +318,16 @@ static void beiscsi_process_async_link(struct beiscsi_hba *phba,
315 * This has been newly introduced in SKH-R Firmware 10.0.338.45. 318 * This has been newly introduced in SKH-R Firmware 10.0.338.45.
316 **/ 319 **/
317 if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) { 320 if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) {
318 phba->state = BE_ADAPTER_LINK_UP | BE_ADAPTER_CHECK_BOOT;
319 phba->get_boot = BE_GET_BOOT_RETRIES; 321 phba->get_boot = BE_GET_BOOT_RETRIES;
322 /* first this needs to be visible to worker thread */
323 wmb();
324 set_bit(BEISCSI_HBA_LINK_UP | BEISCSI_HBA_BOOT_FOUND,
325 &phba->state);
320 __beiscsi_log(phba, KERN_ERR, 326 __beiscsi_log(phba, KERN_ERR,
321 "BC_%d : Link Up on Port %d tag 0x%x\n", 327 "BC_%d : Link Up on Port %d tag 0x%x\n",
322 evt->physical_port, evt->event_tag); 328 evt->physical_port, evt->event_tag);
323 } else { 329 } else {
324 phba->state = BE_ADAPTER_LINK_DOWN; 330 clear_bit(BEISCSI_HBA_LINK_UP, &phba->state);
325 __beiscsi_log(phba, KERN_ERR, 331 __beiscsi_log(phba, KERN_ERR,
326 "BC_%d : Link Down on Port %d tag 0x%x\n", 332 "BC_%d : Link Down on Port %d tag 0x%x\n",
327 evt->physical_port, evt->event_tag); 333 evt->physical_port, evt->event_tag);
@@ -406,8 +412,10 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
406 beiscsi_process_async_link(phba, compl); 412 beiscsi_process_async_link(phba, compl);
407 break; 413 break;
408 case ASYNC_EVENT_CODE_ISCSI: 414 case ASYNC_EVENT_CODE_ISCSI:
409 phba->state |= BE_ADAPTER_CHECK_BOOT;
410 phba->get_boot = BE_GET_BOOT_RETRIES; 415 phba->get_boot = BE_GET_BOOT_RETRIES;
416 /* first this needs to be visible to worker thread */
417 wmb();
418 set_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state);
411 sev = KERN_ERR; 419 sev = KERN_ERR;
412 break; 420 break;
413 case ASYNC_EVENT_CODE_SLI: 421 case ASYNC_EVENT_CODE_SLI:
@@ -504,7 +512,7 @@ int be_mcc_compl_poll(struct beiscsi_hba *phba, unsigned int tag)
504 return 0; 512 return 0;
505 } 513 }
506 for (i = 0; i < mcc_timeout; i++) { 514 for (i = 0; i < mcc_timeout; i++) {
507 if (beiscsi_error(phba)) 515 if (beiscsi_hba_in_error(phba))
508 return -EIO; 516 return -EIO;
509 517
510 beiscsi_process_mcc_cq(phba); 518 beiscsi_process_mcc_cq(phba);
@@ -522,7 +530,7 @@ int be_mcc_compl_poll(struct beiscsi_hba *phba, unsigned int tag)
522 530
523 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 531 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
524 "BC_%d : FW Timed Out\n"); 532 "BC_%d : FW Timed Out\n");
525 phba->fw_timeout = true; 533 set_bit(BEISCSI_HBA_FW_TIMEOUT, &phba->state);
526 beiscsi_ue_detect(phba); 534 beiscsi_ue_detect(phba);
527 return -EBUSY; 535 return -EBUSY;
528} 536}
@@ -566,7 +574,7 @@ static int be_mbox_db_ready_poll(struct be_ctrl_info *ctrl)
566 */ 574 */
567 timeout = jiffies + msecs_to_jiffies(BEISCSI_MBX_RDY_BIT_TIMEOUT); 575 timeout = jiffies + msecs_to_jiffies(BEISCSI_MBX_RDY_BIT_TIMEOUT);
568 do { 576 do {
569 if (beiscsi_error(phba)) 577 if (beiscsi_hba_in_error(phba))
570 return -EIO; 578 return -EIO;
571 579
572 ready = ioread32(db); 580 ready = ioread32(db);
@@ -586,10 +594,8 @@ static int be_mbox_db_ready_poll(struct be_ctrl_info *ctrl)
586 beiscsi_log(phba, KERN_ERR, 594 beiscsi_log(phba, KERN_ERR,
587 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 595 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
588 "BC_%d : FW Timed Out\n"); 596 "BC_%d : FW Timed Out\n");
589 597 set_bit(BEISCSI_HBA_FW_TIMEOUT, &phba->state);
590 phba->fw_timeout = true;
591 beiscsi_ue_detect(phba); 598 beiscsi_ue_detect(phba);
592
593 return -EBUSY; 599 return -EBUSY;
594} 600}
595 601
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index faa37f67a8e6..ddb458abbf59 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -52,22 +52,20 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
52 52
53 53
54 if (!ep) { 54 if (!ep) {
55 printk(KERN_ERR 55 pr_err("beiscsi_session_create: invalid ep\n");
56 "beiscsi_session_create: invalid ep\n");
57 return NULL; 56 return NULL;
58 } 57 }
59 beiscsi_ep = ep->dd_data; 58 beiscsi_ep = ep->dd_data;
60 phba = beiscsi_ep->phba; 59 phba = beiscsi_ep->phba;
61 60
62 if (phba->state & BE_ADAPTER_PCI_ERR) { 61 if (beiscsi_hba_in_error(phba)) {
63 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
64 "BS_%d : PCI_ERROR Recovery\n");
65 return NULL;
66 } else {
67 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 62 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
68 "BS_%d : In beiscsi_session_create\n"); 63 "BS_%d : HBA in error 0x%lx\n", phba->state);
64 return NULL;
69 } 65 }
70 66
67 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
68 "BS_%d : In beiscsi_session_create\n");
71 if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) { 69 if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) {
72 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 70 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
73 "BS_%d : Cannot handle %d cmds." 71 "BS_%d : Cannot handle %d cmds."
@@ -436,9 +434,9 @@ int beiscsi_iface_set_param(struct Scsi_Host *shost,
436 uint32_t rm_len = dt_len; 434 uint32_t rm_len = dt_len;
437 int ret; 435 int ret;
438 436
439 if (phba->state & BE_ADAPTER_PCI_ERR) { 437 if (beiscsi_hba_in_error(phba)) {
440 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 438 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
441 "BS_%d : In PCI_ERROR Recovery\n"); 439 "BS_%d : HBA in error 0x%lx\n", phba->state);
442 return -EBUSY; 440 return -EBUSY;
443 } 441 }
444 442
@@ -579,9 +577,9 @@ int beiscsi_iface_get_param(struct iscsi_iface *iface,
579 577
580 if (param_type != ISCSI_NET_PARAM) 578 if (param_type != ISCSI_NET_PARAM)
581 return 0; 579 return 0;
582 if (phba->state & BE_ADAPTER_PCI_ERR) { 580 if (beiscsi_hba_in_error(phba)) {
583 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 581 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
584 "BS_%d : In PCI_ERROR Recovery\n"); 582 "BS_%d : HBA in error 0x%lx\n", phba->state);
585 return -EBUSY; 583 return -EBUSY;
586 } 584 }
587 585
@@ -737,7 +735,7 @@ static void beiscsi_get_port_state(struct Scsi_Host *shost)
737 struct beiscsi_hba *phba = iscsi_host_priv(shost); 735 struct beiscsi_hba *phba = iscsi_host_priv(shost);
738 struct iscsi_cls_host *ihost = shost->shost_data; 736 struct iscsi_cls_host *ihost = shost->shost_data;
739 737
740 ihost->port_state = (phba->state & BE_ADAPTER_LINK_UP) ? 738 ihost->port_state = test_bit(BEISCSI_HBA_LINK_UP, &phba->state) ?
741 ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; 739 ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN;
742} 740}
743 741
@@ -789,16 +787,13 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
789 struct beiscsi_hba *phba = iscsi_host_priv(shost); 787 struct beiscsi_hba *phba = iscsi_host_priv(shost);
790 int status = 0; 788 int status = 0;
791 789
792 790 if (beiscsi_hba_in_error(phba)) {
793 if (phba->state & BE_ADAPTER_PCI_ERR) {
794 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
795 "BS_%d : In PCI_ERROR Recovery\n");
796 return -EBUSY;
797 } else {
798 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 791 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
799 "BS_%d : In beiscsi_get_host_param," 792 "BS_%d : HBA in error 0x%lx\n", phba->state);
800 " param = %d\n", param); 793 return -EBUSY;
801 } 794 }
795 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
796 "BS_%d : In beiscsi_get_host_param, param = %d\n", param);
802 797
803 switch (param) { 798 switch (param) {
804 case ISCSI_HOST_PARAM_HWADDRESS: 799 case ISCSI_HOST_PARAM_HWADDRESS:
@@ -940,15 +935,13 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
940 935
941 phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 936 phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
942 937
943 if (phba->state & BE_ADAPTER_PCI_ERR) { 938 if (beiscsi_hba_in_error(phba)) {
944 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 939 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
945 "BS_%d : In PCI_ERROR Recovery\n"); 940 "BS_%d : HBA in error 0x%lx\n", phba->state);
946 return -EBUSY; 941 return -EBUSY;
947 } else {
948 beiscsi_log(beiscsi_conn->phba, KERN_INFO,
949 BEISCSI_LOG_CONFIG,
950 "BS_%d : In beiscsi_conn_start\n");
951 } 942 }
943 beiscsi_log(beiscsi_conn->phba, KERN_INFO, BEISCSI_LOG_CONFIG,
944 "BS_%d : In beiscsi_conn_start\n");
952 945
953 memset(&params, 0, sizeof(struct beiscsi_offload_params)); 946 memset(&params, 0, sizeof(struct beiscsi_offload_params));
954 beiscsi_ep = beiscsi_conn->ep; 947 beiscsi_ep = beiscsi_conn->ep;
@@ -1165,28 +1158,20 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
1165 struct iscsi_endpoint *ep; 1158 struct iscsi_endpoint *ep;
1166 int ret; 1159 int ret;
1167 1160
1168 if (shost) 1161 if (!shost) {
1169 phba = iscsi_host_priv(shost);
1170 else {
1171 ret = -ENXIO; 1162 ret = -ENXIO;
1172 printk(KERN_ERR 1163 pr_err("beiscsi_ep_connect shost is NULL\n");
1173 "beiscsi_ep_connect shost is NULL\n");
1174 return ERR_PTR(ret); 1164 return ERR_PTR(ret);
1175 } 1165 }
1176 1166
1177 if (beiscsi_error(phba)) { 1167 phba = iscsi_host_priv(shost);
1168 if (beiscsi_hba_in_error(phba)) {
1178 ret = -EIO; 1169 ret = -EIO;
1179 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 1170 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1180 "BS_%d : The FW state Not Stable!!!\n"); 1171 "BS_%d : HBA in error 0x%lx\n", phba->state);
1181 return ERR_PTR(ret); 1172 return ERR_PTR(ret);
1182 } 1173 }
1183 1174 if (!test_bit(BEISCSI_HBA_LINK_UP, &phba->state)) {
1184 if (phba->state & BE_ADAPTER_PCI_ERR) {
1185 ret = -EBUSY;
1186 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1187 "BS_%d : In PCI_ERROR Recovery\n");
1188 return ERR_PTR(ret);
1189 } else if (phba->state & BE_ADAPTER_LINK_DOWN) {
1190 ret = -EBUSY; 1175 ret = -EBUSY;
1191 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 1176 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1192 "BS_%d : The Adapter Port state is Down!!!\n"); 1177 "BS_%d : The Adapter Port state is Down!!!\n");
@@ -1340,9 +1325,9 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
1340 tcp_upload_flag = CONNECTION_UPLOAD_ABORT; 1325 tcp_upload_flag = CONNECTION_UPLOAD_ABORT;
1341 } 1326 }
1342 1327
1343 if (phba->state & BE_ADAPTER_PCI_ERR) { 1328 if (beiscsi_hba_in_error(phba)) {
1344 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1329 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1345 "BS_%d : PCI_ERROR Recovery\n"); 1330 "BS_%d : HBA in error 0x%lx\n", phba->state);
1346 goto free_ep; 1331 goto free_ep;
1347 } 1332 }
1348 1333
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 6179c4e512a6..22fcbea6894d 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -2017,6 +2017,9 @@ void beiscsi_process_mcc_cq(struct beiscsi_hba *phba)
2017 mcc_compl = queue_tail_node(mcc_cq); 2017 mcc_compl = queue_tail_node(mcc_cq);
2018 mcc_compl->flags = le32_to_cpu(mcc_compl->flags); 2018 mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
2019 while (mcc_compl->flags & CQE_FLAGS_VALID_MASK) { 2019 while (mcc_compl->flags & CQE_FLAGS_VALID_MASK) {
2020 if (beiscsi_hba_in_error(phba))
2021 return;
2022
2020 if (num_processed >= 32) { 2023 if (num_processed >= 32) {
2021 hwi_ring_cq_db(phba, mcc_cq->id, 2024 hwi_ring_cq_db(phba, mcc_cq->id,
2022 num_processed, 0); 2025 num_processed, 0);
@@ -2048,7 +2051,8 @@ static void beiscsi_mcc_work(struct work_struct *work)
2048 phba = pbe_eq->phba; 2051 phba = pbe_eq->phba;
2049 beiscsi_process_mcc_cq(phba); 2052 beiscsi_process_mcc_cq(phba);
2050 /* rearm EQ for further interrupts */ 2053 /* rearm EQ for further interrupts */
2051 hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1); 2054 if (!beiscsi_hba_in_error(phba))
2055 hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1);
2052} 2056}
2053 2057
2054/** 2058/**
@@ -2079,6 +2083,9 @@ unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq, int budget)
2079 2083
2080 while (sol->dw[offsetof(struct amap_sol_cqe, valid) / 32] & 2084 while (sol->dw[offsetof(struct amap_sol_cqe, valid) / 32] &
2081 CQE_VALID_MASK) { 2085 CQE_VALID_MASK) {
2086 if (beiscsi_hba_in_error(phba))
2087 return 0;
2088
2082 be_dws_le_to_cpu(sol, sizeof(struct sol_cqe)); 2089 be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));
2083 2090
2084 code = (sol->dw[offsetof(struct amap_sol_cqe, code) / 2091 code = (sol->dw[offsetof(struct amap_sol_cqe, code) /
@@ -2248,12 +2255,16 @@ static int be_iopoll(struct irq_poll *iop, int budget)
2248 struct be_eq_entry *eqe = NULL; 2255 struct be_eq_entry *eqe = NULL;
2249 struct be_queue_info *eq; 2256 struct be_queue_info *eq;
2250 2257
2251 io_events = 0;
2252 pbe_eq = container_of(iop, struct be_eq_obj, iopoll); 2258 pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
2253 phba = pbe_eq->phba; 2259 phba = pbe_eq->phba;
2260 if (beiscsi_hba_in_error(phba)) {
2261 irq_poll_complete(iop);
2262 return 0;
2263 }
2264
2265 io_events = 0;
2254 eq = &pbe_eq->q; 2266 eq = &pbe_eq->q;
2255 eqe = queue_tail_node(eq); 2267 eqe = queue_tail_node(eq);
2256
2257 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] & 2268 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] &
2258 EQE_VALID_MASK) { 2269 EQE_VALID_MASK) {
2259 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); 2270 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
@@ -2261,7 +2272,6 @@ static int be_iopoll(struct irq_poll *iop, int budget)
2261 eqe = queue_tail_node(eq); 2272 eqe = queue_tail_node(eq);
2262 io_events++; 2273 io_events++;
2263 } 2274 }
2264
2265 hwi_ring_eq_db(phba, eq->id, 1, io_events, 0, 1); 2275 hwi_ring_eq_db(phba, eq->id, 1, io_events, 0, 1);
2266 2276
2267 ret = beiscsi_process_cq(pbe_eq, budget); 2277 ret = beiscsi_process_cq(pbe_eq, budget);
@@ -2272,7 +2282,8 @@ static int be_iopoll(struct irq_poll *iop, int budget)
2272 BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO, 2282 BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
2273 "BM_%d : rearm pbe_eq->q.id =%d ret %d\n", 2283 "BM_%d : rearm pbe_eq->q.id =%d ret %d\n",
2274 pbe_eq->q.id, ret); 2284 pbe_eq->q.id, ret);
2275 hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1); 2285 if (!beiscsi_hba_in_error(phba))
2286 hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1);
2276 } 2287 }
2277 return ret; 2288 return ret;
2278} 2289}
@@ -4633,7 +4644,8 @@ static void beiscsi_cleanup_task(struct iscsi_task *task)
4633 } 4644 }
4634 4645
4635 if (io_task->scsi_cmnd) { 4646 if (io_task->scsi_cmnd) {
4636 scsi_dma_unmap(io_task->scsi_cmnd); 4647 if (io_task->num_sg)
4648 scsi_dma_unmap(io_task->scsi_cmnd);
4637 io_task->scsi_cmnd = NULL; 4649 io_task->scsi_cmnd = NULL;
4638 } 4650 }
4639 } else { 4651 } else {
@@ -5112,6 +5124,15 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
5112 int num_sg; 5124 int num_sg;
5113 unsigned int writedir = 0, xferlen = 0; 5125 unsigned int writedir = 0, xferlen = 0;
5114 5126
5127 phba = io_task->conn->phba;
5128 /**
5129 * HBA in error includes BEISCSI_HBA_FW_TIMEOUT. IO path might be
5130 * operational if FW still gets heartbeat from EP FW. Is management
5131 * path really needed to continue further?
5132 */
5133 if (beiscsi_hba_in_error(phba))
5134 return -EIO;
5135
5115 if (!io_task->conn->login_in_progress) 5136 if (!io_task->conn->login_in_progress)
5116 task->hdr->exp_statsn = 0; 5137 task->hdr->exp_statsn = 0;
5117 5138
@@ -5119,8 +5140,8 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
5119 return beiscsi_mtask(task); 5140 return beiscsi_mtask(task);
5120 5141
5121 io_task->scsi_cmnd = sc; 5142 io_task->scsi_cmnd = sc;
5143 io_task->num_sg = 0;
5122 num_sg = scsi_dma_map(sc); 5144 num_sg = scsi_dma_map(sc);
5123 phba = io_task->conn->phba;
5124 if (num_sg < 0) { 5145 if (num_sg < 0) {
5125 beiscsi_log(phba, KERN_ERR, 5146 beiscsi_log(phba, KERN_ERR,
5126 BEISCSI_LOG_IO | BEISCSI_LOG_ISCSI, 5147 BEISCSI_LOG_IO | BEISCSI_LOG_ISCSI,
@@ -5131,6 +5152,11 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
5131 5152
5132 return num_sg; 5153 return num_sg;
5133 } 5154 }
5155 /**
5156 * For scsi cmd task, check num_sg before unmapping in cleanup_task.
5157 * For management task, cleanup_task checks mtask_addr before unmapping.
5158 */
5159 io_task->num_sg = num_sg;
5134 xferlen = scsi_bufflen(sc); 5160 xferlen = scsi_bufflen(sc);
5135 sg = scsi_sglist(sc); 5161 sg = scsi_sglist(sc);
5136 if (sc->sc_data_direction == DMA_TO_DEVICE) 5162 if (sc->sc_data_direction == DMA_TO_DEVICE)
@@ -5160,6 +5186,12 @@ static int beiscsi_bsg_request(struct bsg_job *job)
5160 shost = iscsi_job_to_shost(job); 5186 shost = iscsi_job_to_shost(job);
5161 phba = iscsi_host_priv(shost); 5187 phba = iscsi_host_priv(shost);
5162 5188
5189 if (beiscsi_hba_in_error(phba)) {
5190 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
5191 "BM_%d : HBA in error 0x%lx\n", phba->state);
5192 return -ENXIO;
5193 }
5194
5163 switch (bsg_req->msgcode) { 5195 switch (bsg_req->msgcode) {
5164 case ISCSI_BSG_HST_VENDOR: 5196 case ISCSI_BSG_HST_VENDOR:
5165 nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, 5197 nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
@@ -5233,12 +5265,10 @@ void beiscsi_hba_attrs_init(struct beiscsi_hba *phba)
5233/* 5265/*
5234 * beiscsi_quiesce()- Cleanup Driver resources 5266 * beiscsi_quiesce()- Cleanup Driver resources
5235 * @phba: Instance Priv structure 5267 * @phba: Instance Priv structure
5236 * @unload_state:i Clean or EEH unload state
5237 * 5268 *
5238 * Free the OS and HW resources held by the driver 5269 * Free the OS and HW resources held by the driver
5239 **/ 5270 **/
5240static void beiscsi_quiesce(struct beiscsi_hba *phba, 5271static void beiscsi_quiesce(struct beiscsi_hba *phba)
5241 uint32_t unload_state)
5242{ 5272{
5243 struct hwi_controller *phwi_ctrlr; 5273 struct hwi_controller *phwi_ctrlr;
5244 struct hwi_context_memory *phwi_context; 5274 struct hwi_context_memory *phwi_context;
@@ -5265,21 +5295,22 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba,
5265 irq_poll_disable(&pbe_eq->iopoll); 5295 irq_poll_disable(&pbe_eq->iopoll);
5266 } 5296 }
5267 5297
5268 if (unload_state == BEISCSI_CLEAN_UNLOAD) { 5298 /* PCI_ERR is set then check if driver is not unloading */
5269 destroy_workqueue(phba->wq); 5299 if (test_bit(BEISCSI_HBA_RUNNING, &phba->state) &&
5270 beiscsi_clean_port(phba); 5300 test_bit(BEISCSI_HBA_PCI_ERR, &phba->state)) {
5271 beiscsi_free_mem(phba);
5272
5273 beiscsi_unmap_pci_function(phba);
5274 pci_free_consistent(phba->pcidev,
5275 phba->ctrl.mbox_mem_alloced.size,
5276 phba->ctrl.mbox_mem_alloced.va,
5277 phba->ctrl.mbox_mem_alloced.dma);
5278 } else {
5279 hwi_purge_eq(phba);
5280 hwi_cleanup(phba); 5301 hwi_cleanup(phba);
5302 return;
5281 } 5303 }
5282 5304
5305 destroy_workqueue(phba->wq);
5306 beiscsi_clean_port(phba);
5307 beiscsi_free_mem(phba);
5308
5309 beiscsi_unmap_pci_function(phba);
5310 pci_free_consistent(phba->pcidev,
5311 phba->ctrl.mbox_mem_alloced.size,
5312 phba->ctrl.mbox_mem_alloced.va,
5313 phba->ctrl.mbox_mem_alloced.dma);
5283} 5314}
5284 5315
5285static void beiscsi_remove(struct pci_dev *pcidev) 5316static void beiscsi_remove(struct pci_dev *pcidev)
@@ -5292,10 +5323,11 @@ static void beiscsi_remove(struct pci_dev *pcidev)
5292 return; 5323 return;
5293 } 5324 }
5294 5325
5326 clear_bit(BEISCSI_HBA_RUNNING, &phba->state);
5295 beiscsi_iface_destroy_default(phba); 5327 beiscsi_iface_destroy_default(phba);
5296 iscsi_boot_destroy_kset(phba->boot_kset); 5328 iscsi_boot_destroy_kset(phba->boot_kset);
5297 iscsi_host_remove(phba->shost); 5329 iscsi_host_remove(phba->shost);
5298 beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD); 5330 beiscsi_quiesce(phba);
5299 pci_dev_put(phba->pcidev); 5331 pci_dev_put(phba->pcidev);
5300 iscsi_host_free(phba->shost); 5332 iscsi_host_free(phba->shost);
5301 pci_disable_pcie_error_reporting(pcidev); 5333 pci_disable_pcie_error_reporting(pcidev);
@@ -5331,6 +5363,9 @@ static void be_eqd_update(struct beiscsi_hba *phba)
5331 u32 pps, delta; 5363 u32 pps, delta;
5332 unsigned int tag; 5364 unsigned int tag;
5333 5365
5366 if (beiscsi_hba_in_error(phba))
5367 return;
5368
5334 phwi_ctrlr = phba->phwi_ctrlr; 5369 phwi_ctrlr = phba->phwi_ctrlr;
5335 phwi_context = phwi_ctrlr->phwi_ctxt; 5370 phwi_context = phwi_ctrlr->phwi_ctxt;
5336 5371
@@ -5372,6 +5407,9 @@ static void be_eqd_update(struct beiscsi_hba *phba)
5372 5407
5373static void be_check_boot_session(struct beiscsi_hba *phba) 5408static void be_check_boot_session(struct beiscsi_hba *phba)
5374{ 5409{
5410 if (beiscsi_hba_in_error(phba))
5411 return;
5412
5375 if (beiscsi_setup_boot_info(phba)) 5413 if (beiscsi_setup_boot_info(phba))
5376 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 5414 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
5377 "BM_%d : Could not set up " 5415 "BM_%d : Could not set up "
@@ -5393,13 +5431,13 @@ beiscsi_hw_health_check(struct work_struct *work)
5393 5431
5394 be_eqd_update(phba); 5432 be_eqd_update(phba);
5395 5433
5396 if (phba->state & BE_ADAPTER_CHECK_BOOT) { 5434 if (test_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state)) {
5397 if ((phba->get_boot > 0) && (!phba->boot_kset)) { 5435 if ((phba->get_boot > 0) && (!phba->boot_kset)) {
5398 phba->get_boot--; 5436 phba->get_boot--;
5399 if (!(phba->get_boot % BE_GET_BOOT_TO)) 5437 if (!(phba->get_boot % BE_GET_BOOT_TO))
5400 be_check_boot_session(phba); 5438 be_check_boot_session(phba);
5401 } else { 5439 } else {
5402 phba->state &= ~BE_ADAPTER_CHECK_BOOT; 5440 clear_bit(BEISCSI_HBA_BOOT_FOUND, &phba->state);
5403 phba->get_boot = 0; 5441 phba->get_boot = 0;
5404 } 5442 }
5405 } 5443 }
@@ -5417,12 +5455,12 @@ static pci_ers_result_t beiscsi_eeh_err_detected(struct pci_dev *pdev,
5417 struct beiscsi_hba *phba = NULL; 5455 struct beiscsi_hba *phba = NULL;
5418 5456
5419 phba = (struct beiscsi_hba *)pci_get_drvdata(pdev); 5457 phba = (struct beiscsi_hba *)pci_get_drvdata(pdev);
5420 phba->state |= BE_ADAPTER_PCI_ERR; 5458 set_bit(BEISCSI_HBA_PCI_ERR, &phba->state);
5421 5459
5422 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 5460 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
5423 "BM_%d : EEH error detected\n"); 5461 "BM_%d : EEH error detected\n");
5424 5462
5425 beiscsi_quiesce(phba, BEISCSI_EEH_UNLOAD); 5463 beiscsi_quiesce(phba);
5426 5464
5427 if (state == pci_channel_io_perm_failure) { 5465 if (state == pci_channel_io_perm_failure) {
5428 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, 5466 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -5554,7 +5592,7 @@ static void beiscsi_eeh_resume(struct pci_dev *pdev)
5554 } 5592 }
5555 5593
5556 hwi_enable_intr(phba); 5594 hwi_enable_intr(phba);
5557 phba->state &= ~BE_ADAPTER_PCI_ERR; 5595 clear_bit(BEISCSI_HBA_PCI_ERR, &phba->state);
5558 5596
5559 return; 5597 return;
5560ret_err: 5598ret_err:
@@ -5597,10 +5635,8 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5597 /* Initialize Driver configuration Paramters */ 5635 /* Initialize Driver configuration Paramters */
5598 beiscsi_hba_attrs_init(phba); 5636 beiscsi_hba_attrs_init(phba);
5599 5637
5600 phba->fw_timeout = false;
5601 phba->mac_addr_set = false; 5638 phba->mac_addr_set = false;
5602 5639
5603
5604 switch (pcidev->device) { 5640 switch (pcidev->device) {
5605 case BE_DEVICE_ID1: 5641 case BE_DEVICE_ID1:
5606 case OC_DEVICE_ID1: 5642 case OC_DEVICE_ID1:
@@ -5629,6 +5665,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
5629 goto hba_free; 5665 goto hba_free;
5630 } 5666 }
5631 5667
5668 set_bit(BEISCSI_HBA_RUNNING, &phba->state);
5632 /* 5669 /*
5633 * FUNCTION_RESET should clean up any stale info in FW for this fn 5670 * FUNCTION_RESET should clean up any stale info in FW for this fn
5634 */ 5671 */
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 90cdc10c01fb..8ab16516ae9a 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -98,20 +98,9 @@
98 98
99#define INVALID_SESS_HANDLE 0xFFFFFFFF 99#define INVALID_SESS_HANDLE 0xFFFFFFFF
100 100
101/**
102 * Adapter States
103 **/
104#define BE_ADAPTER_LINK_UP 0x001
105#define BE_ADAPTER_LINK_DOWN 0x002
106#define BE_ADAPTER_PCI_ERR 0x004
107#define BE_ADAPTER_CHECK_BOOT 0x008
108
109
110#define BEISCSI_CLEAN_UNLOAD 0x01
111#define BEISCSI_EEH_UNLOAD 0x02
112
113#define BE_GET_BOOT_RETRIES 45 101#define BE_GET_BOOT_RETRIES 45
114#define BE_GET_BOOT_TO 20 102#define BE_GET_BOOT_TO 20
103
115/** 104/**
116 * hardware needs the async PDU buffers to be posted in multiples of 8 105 * hardware needs the async PDU buffers to be posted in multiples of 8
117 * So have atleast 8 of them by default 106 * So have atleast 8 of them by default
@@ -417,11 +406,20 @@ struct beiscsi_hba {
417 unsigned long ulp_supported; 406 unsigned long ulp_supported;
418 } fw_config; 407 } fw_config;
419 408
420 unsigned int state; 409 unsigned long state;
410#define BEISCSI_HBA_RUNNING 0
411#define BEISCSI_HBA_LINK_UP 1
412#define BEISCSI_HBA_BOOT_FOUND 2
413#define BEISCSI_HBA_PCI_ERR 3
414#define BEISCSI_HBA_FW_TIMEOUT 4
415#define BEISCSI_HBA_IN_UE 5
416/* error bits */
417#define BEISCSI_HBA_IN_ERR ((1 << BEISCSI_HBA_PCI_ERR) | \
418 (1 << BEISCSI_HBA_FW_TIMEOUT) | \
419 (1 << BEISCSI_HBA_IN_UE))
420
421 u8 optic_state; 421 u8 optic_state;
422 int get_boot; 422 int get_boot;
423 bool fw_timeout;
424 bool ue_detected;
425 struct delayed_work beiscsi_hw_check_task; 423 struct delayed_work beiscsi_hw_check_task;
426 424
427 bool mac_addr_set; 425 bool mac_addr_set;
@@ -445,6 +443,8 @@ struct beiscsi_hba {
445 uint32_t writedir); 443 uint32_t writedir);
446}; 444};
447 445
446#define beiscsi_hba_in_error(phba) ((phba)->state & BEISCSI_HBA_IN_ERR)
447
448struct beiscsi_session { 448struct beiscsi_session {
449 struct pci_pool *bhs_pool; 449 struct pci_pool *bhs_pool;
450}; 450};
@@ -507,6 +507,7 @@ struct beiscsi_io_task {
507 struct sgl_handle *psgl_handle; 507 struct sgl_handle *psgl_handle;
508 struct beiscsi_conn *conn; 508 struct beiscsi_conn *conn;
509 struct scsi_cmnd *scsi_cmnd; 509 struct scsi_cmnd *scsi_cmnd;
510 int num_sg;
510 struct hwi_wrb_context *pwrb_context; 511 struct hwi_wrb_context *pwrb_context;
511 unsigned int cmd_sn; 512 unsigned int cmd_sn;
512 unsigned int flags; 513 unsigned int flags;
@@ -854,11 +855,6 @@ void hwi_ring_cq_db(struct beiscsi_hba *phba,
854unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq, int budget); 855unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq, int budget);
855void beiscsi_process_mcc_cq(struct beiscsi_hba *phba); 856void beiscsi_process_mcc_cq(struct beiscsi_hba *phba);
856 857
857static inline bool beiscsi_error(struct beiscsi_hba *phba)
858{
859 return phba->ue_detected || phba->fw_timeout;
860}
861
862struct pdu_nop_out { 858struct pdu_nop_out {
863 u32 dw[12]; 859 u32 dw[12];
864}; 860};
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 8069ef0ce533..4f2194e324ae 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -108,9 +108,6 @@ void beiscsi_ue_detect(struct beiscsi_hba *phba)
108 uint32_t ue_mask_hi = 0, ue_mask_lo = 0; 108 uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
109 uint8_t i = 0; 109 uint8_t i = 0;
110 110
111 if (phba->ue_detected)
112 return;
113
114 pci_read_config_dword(phba->pcidev, 111 pci_read_config_dword(phba->pcidev,
115 PCICFG_UE_STATUS_LOW, &ue_lo); 112 PCICFG_UE_STATUS_LOW, &ue_lo);
116 pci_read_config_dword(phba->pcidev, 113 pci_read_config_dword(phba->pcidev,
@@ -128,7 +125,7 @@ void beiscsi_ue_detect(struct beiscsi_hba *phba)
128 125
129 126
130 if (ue_lo || ue_hi) { 127 if (ue_lo || ue_hi) {
131 phba->ue_detected = true; 128 set_bit(BEISCSI_HBA_IN_UE, &phba->state);
132 beiscsi_log(phba, KERN_ERR, 129 beiscsi_log(phba, KERN_ERR,
133 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 130 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
134 "BG_%d : Error detected on the adapter\n"); 131 "BG_%d : Error detected on the adapter\n");