.. | .. |
---|
24 | 24 | static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req); |
---|
25 | 25 | static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, |
---|
26 | 26 | struct fcoe_fcp_rsp_payload *fcp_rsp, |
---|
27 | | - u8 num_rq); |
---|
| 27 | + u8 num_rq, unsigned char *rq_data); |
---|
28 | 28 | |
---|
29 | 29 | void bnx2fc_cmd_timer_set(struct bnx2fc_cmd *io_req, |
---|
30 | 30 | unsigned int timer_msec) |
---|
.. | .. |
---|
70 | 70 | &io_req->req_flags)) { |
---|
71 | 71 | /* Handle eh_abort timeout */ |
---|
72 | 72 | BNX2FC_IO_DBG(io_req, "eh_abort timed out\n"); |
---|
73 | | - complete(&io_req->tm_done); |
---|
| 73 | + complete(&io_req->abts_done); |
---|
74 | 74 | } else if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, |
---|
75 | 75 | &io_req->req_flags)) { |
---|
76 | 76 | /* Handle internally generated ABTS timeout */ |
---|
.. | .. |
---|
775 | 775 | io_req->on_tmf_queue = 1; |
---|
776 | 776 | list_add_tail(&io_req->link, &tgt->active_tm_queue); |
---|
777 | 777 | |
---|
778 | | - init_completion(&io_req->tm_done); |
---|
779 | | - io_req->wait_for_comp = 1; |
---|
| 778 | + init_completion(&io_req->abts_done); |
---|
| 779 | + io_req->wait_for_abts_comp = 1; |
---|
780 | 780 | |
---|
781 | 781 | /* Ring doorbell */ |
---|
782 | 782 | bnx2fc_ring_doorbell(tgt); |
---|
783 | 783 | spin_unlock_bh(&tgt->tgt_lock); |
---|
784 | 784 | |
---|
785 | | - rc = wait_for_completion_timeout(&io_req->tm_done, |
---|
| 785 | + rc = wait_for_completion_timeout(&io_req->abts_done, |
---|
786 | 786 | interface->tm_timeout * HZ); |
---|
787 | 787 | spin_lock_bh(&tgt->tgt_lock); |
---|
788 | 788 | |
---|
789 | | - io_req->wait_for_comp = 0; |
---|
| 789 | + io_req->wait_for_abts_comp = 0; |
---|
790 | 790 | if (!(test_bit(BNX2FC_FLAG_TM_COMPL, &io_req->req_flags))) { |
---|
791 | 791 | set_bit(BNX2FC_FLAG_TM_TIMEOUT, &io_req->req_flags); |
---|
792 | 792 | if (io_req->on_tmf_queue) { |
---|
793 | 793 | list_del_init(&io_req->link); |
---|
794 | 794 | io_req->on_tmf_queue = 0; |
---|
795 | 795 | } |
---|
796 | | - io_req->wait_for_comp = 1; |
---|
| 796 | + io_req->wait_for_cleanup_comp = 1; |
---|
| 797 | + init_completion(&io_req->cleanup_done); |
---|
797 | 798 | bnx2fc_initiate_cleanup(io_req); |
---|
798 | 799 | spin_unlock_bh(&tgt->tgt_lock); |
---|
799 | | - rc = wait_for_completion_timeout(&io_req->tm_done, |
---|
| 800 | + rc = wait_for_completion_timeout(&io_req->cleanup_done, |
---|
800 | 801 | BNX2FC_FW_TIMEOUT); |
---|
801 | 802 | spin_lock_bh(&tgt->tgt_lock); |
---|
802 | | - io_req->wait_for_comp = 0; |
---|
| 803 | + io_req->wait_for_cleanup_comp = 0; |
---|
803 | 804 | if (!rc) |
---|
804 | 805 | kref_put(&io_req->refcount, bnx2fc_cmd_release); |
---|
805 | 806 | } |
---|
.. | .. |
---|
863 | 864 | |
---|
864 | 865 | abts_io_req = bnx2fc_elstm_alloc(tgt, BNX2FC_ABTS); |
---|
865 | 866 | if (!abts_io_req) { |
---|
866 | | - printk(KERN_ERR PFX "abts: couldnt allocate cmd\n"); |
---|
| 867 | + printk(KERN_ERR PFX "abts: couldn't allocate cmd\n"); |
---|
867 | 868 | rc = FAILED; |
---|
868 | 869 | goto abts_err; |
---|
869 | 870 | } |
---|
.. | .. |
---|
929 | 930 | int bnx2fc_initiate_seq_cleanup(struct bnx2fc_cmd *orig_io_req, u32 offset, |
---|
930 | 931 | enum fc_rctl r_ctl) |
---|
931 | 932 | { |
---|
932 | | - struct fc_lport *lport; |
---|
933 | 933 | struct bnx2fc_rport *tgt = orig_io_req->tgt; |
---|
934 | 934 | struct bnx2fc_interface *interface; |
---|
935 | 935 | struct fcoe_port *port; |
---|
.. | .. |
---|
947 | 947 | |
---|
948 | 948 | port = orig_io_req->port; |
---|
949 | 949 | interface = port->priv; |
---|
950 | | - lport = port->lport; |
---|
951 | 950 | |
---|
952 | 951 | cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC); |
---|
953 | 952 | if (!cb_arg) { |
---|
.. | .. |
---|
958 | 957 | |
---|
959 | 958 | seq_clnp_req = bnx2fc_elstm_alloc(tgt, BNX2FC_SEQ_CLEANUP); |
---|
960 | 959 | if (!seq_clnp_req) { |
---|
961 | | - printk(KERN_ERR PFX "cleanup: couldnt allocate cmd\n"); |
---|
| 960 | + printk(KERN_ERR PFX "cleanup: couldn't allocate cmd\n"); |
---|
962 | 961 | rc = -ENOMEM; |
---|
963 | 962 | kfree(cb_arg); |
---|
964 | 963 | goto cleanup_err; |
---|
.. | .. |
---|
998 | 997 | |
---|
999 | 998 | int bnx2fc_initiate_cleanup(struct bnx2fc_cmd *io_req) |
---|
1000 | 999 | { |
---|
1001 | | - struct fc_lport *lport; |
---|
1002 | 1000 | struct bnx2fc_rport *tgt = io_req->tgt; |
---|
1003 | 1001 | struct bnx2fc_interface *interface; |
---|
1004 | 1002 | struct fcoe_port *port; |
---|
.. | .. |
---|
1014 | 1012 | |
---|
1015 | 1013 | port = io_req->port; |
---|
1016 | 1014 | interface = port->priv; |
---|
1017 | | - lport = port->lport; |
---|
1018 | 1015 | |
---|
1019 | 1016 | cleanup_io_req = bnx2fc_elstm_alloc(tgt, BNX2FC_CLEANUP); |
---|
1020 | 1017 | if (!cleanup_io_req) { |
---|
1021 | | - printk(KERN_ERR PFX "cleanup: couldnt allocate cmd\n"); |
---|
| 1018 | + printk(KERN_ERR PFX "cleanup: couldn't allocate cmd\n"); |
---|
1022 | 1019 | rc = -1; |
---|
1023 | 1020 | goto cleanup_err; |
---|
1024 | 1021 | } |
---|
.. | .. |
---|
1046 | 1043 | |
---|
1047 | 1044 | /* Obtain free SQ entry */ |
---|
1048 | 1045 | bnx2fc_add_2_sq(tgt, xid); |
---|
| 1046 | + |
---|
| 1047 | + /* Set flag that cleanup request is pending with the firmware */ |
---|
| 1048 | + set_bit(BNX2FC_FLAG_ISSUE_CLEANUP_REQ, &io_req->req_flags); |
---|
1049 | 1049 | |
---|
1050 | 1050 | /* Ring doorbell */ |
---|
1051 | 1051 | bnx2fc_ring_doorbell(tgt); |
---|
.. | .. |
---|
1081 | 1081 | } |
---|
1082 | 1082 | |
---|
1083 | 1083 | static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req) |
---|
| 1084 | + __must_hold(&tgt->tgt_lock) |
---|
1084 | 1085 | { |
---|
1085 | 1086 | struct bnx2fc_rport *tgt = io_req->tgt; |
---|
1086 | | - int rc = SUCCESS; |
---|
1087 | 1087 | unsigned int time_left; |
---|
1088 | 1088 | |
---|
1089 | | - io_req->wait_for_comp = 1; |
---|
| 1089 | + init_completion(&io_req->cleanup_done); |
---|
| 1090 | + io_req->wait_for_cleanup_comp = 1; |
---|
1090 | 1091 | bnx2fc_initiate_cleanup(io_req); |
---|
1091 | 1092 | |
---|
1092 | 1093 | spin_unlock_bh(&tgt->tgt_lock); |
---|
.. | .. |
---|
1095 | 1096 | * Can't wait forever on cleanup response lest we let the SCSI error |
---|
1096 | 1097 | * handler wait forever |
---|
1097 | 1098 | */ |
---|
1098 | | - time_left = wait_for_completion_timeout(&io_req->tm_done, |
---|
| 1099 | + time_left = wait_for_completion_timeout(&io_req->cleanup_done, |
---|
1099 | 1100 | BNX2FC_FW_TIMEOUT); |
---|
1100 | | - io_req->wait_for_comp = 0; |
---|
1101 | | - if (!time_left) |
---|
| 1101 | + if (!time_left) { |
---|
1102 | 1102 | BNX2FC_IO_DBG(io_req, "%s(): Wait for cleanup timed out.\n", |
---|
1103 | 1103 | __func__); |
---|
1104 | 1104 | |
---|
1105 | | - /* |
---|
1106 | | - * Release reference held by SCSI command the cleanup completion |
---|
1107 | | - * hits the BNX2FC_CLEANUP case in bnx2fc_process_cq_compl() and |
---|
1108 | | - * thus the SCSI command is not returnedi by bnx2fc_scsi_done(). |
---|
1109 | | - */ |
---|
1110 | | - kref_put(&io_req->refcount, bnx2fc_cmd_release); |
---|
| 1105 | + /* |
---|
| 1106 | + * Put the extra reference to the SCSI command since it would |
---|
| 1107 | + * not have been returned in this case. |
---|
| 1108 | + */ |
---|
| 1109 | + kref_put(&io_req->refcount, bnx2fc_cmd_release); |
---|
| 1110 | + } |
---|
1111 | 1111 | |
---|
1112 | 1112 | spin_lock_bh(&tgt->tgt_lock); |
---|
1113 | | - return rc; |
---|
| 1113 | + io_req->wait_for_cleanup_comp = 0; |
---|
| 1114 | + return SUCCESS; |
---|
1114 | 1115 | } |
---|
1115 | 1116 | |
---|
1116 | 1117 | /** |
---|
.. | .. |
---|
1198 | 1199 | /* Move IO req to retire queue */ |
---|
1199 | 1200 | list_add_tail(&io_req->link, &tgt->io_retire_queue); |
---|
1200 | 1201 | |
---|
1201 | | - init_completion(&io_req->tm_done); |
---|
| 1202 | + init_completion(&io_req->abts_done); |
---|
| 1203 | + init_completion(&io_req->cleanup_done); |
---|
1202 | 1204 | |
---|
1203 | 1205 | if (test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags)) { |
---|
1204 | 1206 | printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) " |
---|
.. | .. |
---|
1227 | 1229 | kref_put(&io_req->refcount, |
---|
1228 | 1230 | bnx2fc_cmd_release); /* drop timer hold */ |
---|
1229 | 1231 | set_bit(BNX2FC_FLAG_EH_ABORT, &io_req->req_flags); |
---|
1230 | | - io_req->wait_for_comp = 1; |
---|
| 1232 | + io_req->wait_for_abts_comp = 1; |
---|
1231 | 1233 | rc = bnx2fc_initiate_abts(io_req); |
---|
1232 | 1234 | if (rc == FAILED) { |
---|
| 1235 | + io_req->wait_for_cleanup_comp = 1; |
---|
1233 | 1236 | bnx2fc_initiate_cleanup(io_req); |
---|
1234 | 1237 | spin_unlock_bh(&tgt->tgt_lock); |
---|
1235 | | - wait_for_completion(&io_req->tm_done); |
---|
| 1238 | + wait_for_completion(&io_req->cleanup_done); |
---|
1236 | 1239 | spin_lock_bh(&tgt->tgt_lock); |
---|
1237 | | - io_req->wait_for_comp = 0; |
---|
| 1240 | + io_req->wait_for_cleanup_comp = 0; |
---|
1238 | 1241 | goto done; |
---|
1239 | 1242 | } |
---|
1240 | 1243 | spin_unlock_bh(&tgt->tgt_lock); |
---|
1241 | 1244 | |
---|
1242 | 1245 | /* Wait 2 * RA_TOV + 1 to be sure timeout function hasn't fired */ |
---|
1243 | | - time_left = wait_for_completion_timeout(&io_req->tm_done, |
---|
1244 | | - (2 * rp->r_a_tov + 1) * HZ); |
---|
| 1246 | + time_left = wait_for_completion_timeout(&io_req->abts_done, |
---|
| 1247 | + msecs_to_jiffies(2 * rp->r_a_tov + 1)); |
---|
1245 | 1248 | if (time_left) |
---|
1246 | | - BNX2FC_IO_DBG(io_req, "Timed out in eh_abort waiting for tm_done"); |
---|
| 1249 | + BNX2FC_IO_DBG(io_req, |
---|
| 1250 | + "Timed out in eh_abort waiting for abts_done"); |
---|
1247 | 1251 | |
---|
1248 | 1252 | spin_lock_bh(&tgt->tgt_lock); |
---|
1249 | | - io_req->wait_for_comp = 0; |
---|
| 1253 | + io_req->wait_for_abts_comp = 0; |
---|
1250 | 1254 | if (test_bit(BNX2FC_FLAG_IO_COMPL, &io_req->req_flags)) { |
---|
1251 | 1255 | BNX2FC_IO_DBG(io_req, "IO completed in a different context\n"); |
---|
1252 | 1256 | rc = SUCCESS; |
---|
.. | .. |
---|
1321 | 1325 | BNX2FC_IO_DBG(io_req, "Entered process_cleanup_compl " |
---|
1322 | 1326 | "refcnt = %d, cmd_type = %d\n", |
---|
1323 | 1327 | kref_read(&io_req->refcount), io_req->cmd_type); |
---|
| 1328 | + /* |
---|
| 1329 | + * Test whether there is a cleanup request pending. If not just |
---|
| 1330 | + * exit. |
---|
| 1331 | + */ |
---|
| 1332 | + if (!test_and_clear_bit(BNX2FC_FLAG_ISSUE_CLEANUP_REQ, |
---|
| 1333 | + &io_req->req_flags)) |
---|
| 1334 | + return; |
---|
| 1335 | + /* |
---|
| 1336 | + * If we receive a cleanup completion for this request then the |
---|
| 1337 | + * firmware will not give us an abort completion for this request |
---|
| 1338 | + * so clear any ABTS pending flags. |
---|
| 1339 | + */ |
---|
| 1340 | + if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags) && |
---|
| 1341 | + !test_bit(BNX2FC_FLAG_ABTS_DONE, &io_req->req_flags)) { |
---|
| 1342 | + set_bit(BNX2FC_FLAG_ABTS_DONE, &io_req->req_flags); |
---|
| 1343 | + if (io_req->wait_for_abts_comp) |
---|
| 1344 | + complete(&io_req->abts_done); |
---|
| 1345 | + } |
---|
| 1346 | + |
---|
1324 | 1347 | bnx2fc_scsi_done(io_req, DID_ERROR); |
---|
1325 | 1348 | kref_put(&io_req->refcount, bnx2fc_cmd_release); |
---|
1326 | | - if (io_req->wait_for_comp) |
---|
1327 | | - complete(&io_req->tm_done); |
---|
| 1349 | + if (io_req->wait_for_cleanup_comp) |
---|
| 1350 | + complete(&io_req->cleanup_done); |
---|
1328 | 1351 | } |
---|
1329 | 1352 | |
---|
1330 | 1353 | void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req, |
---|
.. | .. |
---|
1346 | 1369 | BNX2FC_IO_DBG(io_req, "Timer context finished processing" |
---|
1347 | 1370 | " this io\n"); |
---|
1348 | 1371 | return; |
---|
| 1372 | + } |
---|
| 1373 | + |
---|
| 1374 | + /* |
---|
| 1375 | + * If we receive an ABTS completion here then we will not receive |
---|
| 1376 | + * a cleanup completion so clear any cleanup pending flags. |
---|
| 1377 | + */ |
---|
| 1378 | + if (test_bit(BNX2FC_FLAG_ISSUE_CLEANUP_REQ, &io_req->req_flags)) { |
---|
| 1379 | + clear_bit(BNX2FC_FLAG_ISSUE_CLEANUP_REQ, &io_req->req_flags); |
---|
| 1380 | + if (io_req->wait_for_cleanup_comp) |
---|
| 1381 | + complete(&io_req->cleanup_done); |
---|
1349 | 1382 | } |
---|
1350 | 1383 | |
---|
1351 | 1384 | /* Do not issue RRQ as this IO is already cleanedup */ |
---|
.. | .. |
---|
1392 | 1425 | bnx2fc_cmd_timer_set(io_req, r_a_tov); |
---|
1393 | 1426 | |
---|
1394 | 1427 | io_compl: |
---|
1395 | | - if (io_req->wait_for_comp) { |
---|
| 1428 | + if (io_req->wait_for_abts_comp) { |
---|
1396 | 1429 | if (test_and_clear_bit(BNX2FC_FLAG_EH_ABORT, |
---|
1397 | 1430 | &io_req->req_flags)) |
---|
1398 | | - complete(&io_req->tm_done); |
---|
| 1431 | + complete(&io_req->abts_done); |
---|
1399 | 1432 | } else { |
---|
1400 | 1433 | /* |
---|
1401 | 1434 | * We end up here when ABTS is issued as |
---|
.. | .. |
---|
1487 | 1520 | } |
---|
1488 | 1521 | |
---|
1489 | 1522 | void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req, |
---|
1490 | | - struct fcoe_task_ctx_entry *task, u8 num_rq) |
---|
| 1523 | + struct fcoe_task_ctx_entry *task, u8 num_rq, |
---|
| 1524 | + unsigned char *rq_data) |
---|
1491 | 1525 | { |
---|
1492 | 1526 | struct bnx2fc_mp_req *tm_req; |
---|
1493 | 1527 | struct fc_frame_header *fc_hdr; |
---|
.. | .. |
---|
1526 | 1560 | if (fc_hdr->fh_r_ctl == FC_RCTL_DD_CMD_STATUS) { |
---|
1527 | 1561 | bnx2fc_parse_fcp_rsp(io_req, |
---|
1528 | 1562 | (struct fcoe_fcp_rsp_payload *) |
---|
1529 | | - rsp_buf, num_rq); |
---|
| 1563 | + rsp_buf, num_rq, rq_data); |
---|
1530 | 1564 | if (io_req->fcp_rsp_code == 0) { |
---|
1531 | 1565 | /* TM successful */ |
---|
1532 | 1566 | if (tm_req->tm_flags & FCP_TMF_LUN_RESET) |
---|
.. | .. |
---|
1579 | 1613 | sc_cmd->scsi_done(sc_cmd); |
---|
1580 | 1614 | |
---|
1581 | 1615 | kref_put(&io_req->refcount, bnx2fc_cmd_release); |
---|
1582 | | - if (io_req->wait_for_comp) { |
---|
| 1616 | + if (io_req->wait_for_abts_comp) { |
---|
1583 | 1617 | BNX2FC_IO_DBG(io_req, "tm_compl - wake up the waiter\n"); |
---|
1584 | | - complete(&io_req->tm_done); |
---|
| 1618 | + complete(&io_req->abts_done); |
---|
1585 | 1619 | } |
---|
1586 | 1620 | } |
---|
1587 | 1621 | |
---|
.. | .. |
---|
1625 | 1659 | u64 addr; |
---|
1626 | 1660 | int i; |
---|
1627 | 1661 | |
---|
| 1662 | + WARN_ON(scsi_sg_count(sc) > BNX2FC_MAX_BDS_PER_CMD); |
---|
1628 | 1663 | /* |
---|
1629 | 1664 | * Use dma_map_sg directly to ensure we're using the correct |
---|
1630 | 1665 | * dev struct off of pcidev. |
---|
.. | .. |
---|
1672 | 1707 | } |
---|
1673 | 1708 | io_req->bd_tbl->bd_valid = bd_count; |
---|
1674 | 1709 | |
---|
| 1710 | + /* |
---|
| 1711 | + * Return the command to ML if BD count exceeds the max number |
---|
| 1712 | + * that can be handled by FW. |
---|
| 1713 | + */ |
---|
| 1714 | + if (bd_count > BNX2FC_FW_MAX_BDS_PER_CMD) { |
---|
| 1715 | + pr_err("bd_count = %d exceeded FW supported max BD(255), task_id = 0x%x\n", |
---|
| 1716 | + bd_count, io_req->xid); |
---|
| 1717 | + return -ENOMEM; |
---|
| 1718 | + } |
---|
| 1719 | + |
---|
1675 | 1720 | return 0; |
---|
1676 | 1721 | } |
---|
1677 | 1722 | |
---|
.. | .. |
---|
1713 | 1758 | |
---|
1714 | 1759 | static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, |
---|
1715 | 1760 | struct fcoe_fcp_rsp_payload *fcp_rsp, |
---|
1716 | | - u8 num_rq) |
---|
| 1761 | + u8 num_rq, unsigned char *rq_data) |
---|
1717 | 1762 | { |
---|
1718 | 1763 | struct scsi_cmnd *sc_cmd = io_req->sc_cmd; |
---|
1719 | | - struct bnx2fc_rport *tgt = io_req->tgt; |
---|
1720 | 1764 | u8 rsp_flags = fcp_rsp->fcp_flags.flags; |
---|
1721 | 1765 | u32 rq_buff_len = 0; |
---|
1722 | | - int i; |
---|
1723 | | - unsigned char *rq_data; |
---|
1724 | | - unsigned char *dummy; |
---|
1725 | 1766 | int fcp_sns_len = 0; |
---|
1726 | 1767 | int fcp_rsp_len = 0; |
---|
1727 | 1768 | |
---|
.. | .. |
---|
1767 | 1808 | rq_buff_len = num_rq * BNX2FC_RQ_BUF_SZ; |
---|
1768 | 1809 | } |
---|
1769 | 1810 | |
---|
1770 | | - rq_data = bnx2fc_get_next_rqe(tgt, 1); |
---|
1771 | | - |
---|
1772 | | - if (num_rq > 1) { |
---|
1773 | | - /* We do not need extra sense data */ |
---|
1774 | | - for (i = 1; i < num_rq; i++) |
---|
1775 | | - dummy = bnx2fc_get_next_rqe(tgt, 1); |
---|
1776 | | - } |
---|
1777 | | - |
---|
1778 | 1811 | /* fetch fcp_rsp_code */ |
---|
1779 | 1812 | if ((fcp_rsp_len == 4) || (fcp_rsp_len == 8)) { |
---|
1780 | 1813 | /* Only for task management function */ |
---|
.. | .. |
---|
1795 | 1828 | if (fcp_sns_len) |
---|
1796 | 1829 | memcpy(sc_cmd->sense_buffer, rq_data, fcp_sns_len); |
---|
1797 | 1830 | |
---|
1798 | | - /* return RQ entries */ |
---|
1799 | | - for (i = 0; i < num_rq; i++) |
---|
1800 | | - bnx2fc_return_rqe(tgt, 1); |
---|
1801 | 1831 | } |
---|
1802 | 1832 | } |
---|
1803 | 1833 | |
---|
.. | .. |
---|
1876 | 1906 | |
---|
1877 | 1907 | void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req, |
---|
1878 | 1908 | struct fcoe_task_ctx_entry *task, |
---|
1879 | | - u8 num_rq) |
---|
| 1909 | + u8 num_rq, unsigned char *rq_data) |
---|
1880 | 1910 | { |
---|
1881 | 1911 | struct fcoe_fcp_rsp_payload *fcp_rsp; |
---|
1882 | 1912 | struct bnx2fc_rport *tgt = io_req->tgt; |
---|
1883 | 1913 | struct scsi_cmnd *sc_cmd; |
---|
1884 | | - struct Scsi_Host *host; |
---|
1885 | | - |
---|
| 1914 | + u16 scope = 0, qualifier = 0; |
---|
1886 | 1915 | |
---|
1887 | 1916 | /* scsi_cmd_cmpl is called with tgt lock held */ |
---|
1888 | 1917 | |
---|
.. | .. |
---|
1890 | 1919 | /* we will not receive ABTS response for this IO */ |
---|
1891 | 1920 | BNX2FC_IO_DBG(io_req, "Timer context finished processing " |
---|
1892 | 1921 | "this scsi cmd\n"); |
---|
| 1922 | + if (test_and_clear_bit(BNX2FC_FLAG_IO_CLEANUP, |
---|
| 1923 | + &io_req->req_flags)) { |
---|
| 1924 | + BNX2FC_IO_DBG(io_req, |
---|
| 1925 | + "Actual completion after cleanup request cleaning up\n"); |
---|
| 1926 | + bnx2fc_process_cleanup_compl(io_req, task, num_rq); |
---|
| 1927 | + } |
---|
1893 | 1928 | return; |
---|
1894 | 1929 | } |
---|
1895 | 1930 | |
---|
.. | .. |
---|
1909 | 1944 | &(task->rxwr_only.union_ctx.comp_info.fcp_rsp.payload); |
---|
1910 | 1945 | |
---|
1911 | 1946 | /* parse fcp_rsp and obtain sense data from RQ if available */ |
---|
1912 | | - bnx2fc_parse_fcp_rsp(io_req, fcp_rsp, num_rq); |
---|
| 1947 | + bnx2fc_parse_fcp_rsp(io_req, fcp_rsp, num_rq, rq_data); |
---|
1913 | 1948 | |
---|
1914 | | - host = sc_cmd->device->host; |
---|
1915 | 1949 | if (!sc_cmd->SCp.ptr) { |
---|
1916 | 1950 | printk(KERN_ERR PFX "SCp.ptr is NULL\n"); |
---|
1917 | 1951 | return; |
---|
.. | .. |
---|
1928 | 1962 | * between command abort and (late) completion. |
---|
1929 | 1963 | */ |
---|
1930 | 1964 | BNX2FC_IO_DBG(io_req, "xid not on active_cmd_queue\n"); |
---|
1931 | | - if (io_req->wait_for_comp) |
---|
| 1965 | + if (io_req->wait_for_abts_comp) |
---|
1932 | 1966 | if (test_and_clear_bit(BNX2FC_FLAG_EH_ABORT, |
---|
1933 | 1967 | &io_req->req_flags)) |
---|
1934 | | - complete(&io_req->tm_done); |
---|
| 1968 | + complete(&io_req->abts_done); |
---|
1935 | 1969 | } |
---|
1936 | 1970 | |
---|
1937 | 1971 | bnx2fc_unmap_sg_list(io_req); |
---|
.. | .. |
---|
1951 | 1985 | |
---|
1952 | 1986 | if (io_req->cdb_status == SAM_STAT_TASK_SET_FULL || |
---|
1953 | 1987 | io_req->cdb_status == SAM_STAT_BUSY) { |
---|
1954 | | - /* Set the jiffies + retry_delay_timer * 100ms |
---|
1955 | | - for the rport/tgt */ |
---|
1956 | | - tgt->retry_delay_timestamp = jiffies + |
---|
1957 | | - fcp_rsp->retry_delay_timer * HZ / 10; |
---|
| 1988 | + /* Newer array firmware with BUSY or |
---|
| 1989 | + * TASK_SET_FULL may return a status that needs |
---|
| 1990 | + * the scope bits masked. |
---|
| 1991 | + * Or a huge delay timestamp up to 27 minutes |
---|
| 1992 | + * can result. |
---|
| 1993 | + */ |
---|
| 1994 | + if (fcp_rsp->retry_delay_timer) { |
---|
| 1995 | + /* Upper 2 bits */ |
---|
| 1996 | + scope = fcp_rsp->retry_delay_timer |
---|
| 1997 | + & 0xC000; |
---|
| 1998 | + /* Lower 14 bits */ |
---|
| 1999 | + qualifier = fcp_rsp->retry_delay_timer |
---|
| 2000 | + & 0x3FFF; |
---|
| 2001 | + } |
---|
| 2002 | + if (scope > 0 && qualifier > 0 && |
---|
| 2003 | + qualifier <= 0x3FEF) { |
---|
| 2004 | + /* Set the jiffies + |
---|
| 2005 | + * retry_delay_timer * 100ms |
---|
| 2006 | + * for the rport/tgt |
---|
| 2007 | + */ |
---|
| 2008 | + tgt->retry_delay_timestamp = jiffies + |
---|
| 2009 | + (qualifier * HZ / 10); |
---|
| 2010 | + } |
---|
1958 | 2011 | } |
---|
1959 | | - |
---|
1960 | 2012 | } |
---|
1961 | 2013 | if (io_req->fcp_resid) |
---|
1962 | 2014 | scsi_set_resid(sc_cmd, io_req->fcp_resid); |
---|