aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i/bnx2i_hwi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bnx2i/bnx2i_hwi.c')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c96
1 files changed, 69 insertions, 27 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 2f9622ebbd84..96505e3ab986 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1,6 +1,6 @@
1/* bnx2i_hwi.c: Broadcom NetXtreme II iSCSI driver. 1/* bnx2i_hwi.c: Broadcom NetXtreme II iSCSI driver.
2 * 2 *
3 * Copyright (c) 2006 - 2009 Broadcom Corporation 3 * Copyright (c) 2006 - 2010 Broadcom Corporation
4 * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved. 4 * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
5 * Copyright (c) 2007, 2008 Mike Christie 5 * Copyright (c) 2007, 2008 Mike Christie
6 * 6 *
@@ -9,6 +9,7 @@
9 * the Free Software Foundation. 9 * the Free Software Foundation.
10 * 10 *
11 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com) 11 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
12 * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
12 */ 13 */
13 14
14#include <linux/gfp.h> 15#include <linux/gfp.h>
@@ -385,6 +386,7 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
385 struct bnx2i_cmd *bnx2i_cmd; 386 struct bnx2i_cmd *bnx2i_cmd;
386 struct bnx2i_tmf_request *tmfabort_wqe; 387 struct bnx2i_tmf_request *tmfabort_wqe;
387 u32 dword; 388 u32 dword;
389 u32 scsi_lun[2];
388 390
389 bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data; 391 bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data;
390 tmfabort_hdr = (struct iscsi_tm *)mtask->hdr; 392 tmfabort_hdr = (struct iscsi_tm *)mtask->hdr;
@@ -426,7 +428,10 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
426 default: 428 default:
427 tmfabort_wqe->ref_itt = RESERVED_ITT; 429 tmfabort_wqe->ref_itt = RESERVED_ITT;
428 } 430 }
429 memcpy(tmfabort_wqe->lun, tmfabort_hdr->lun, sizeof(struct scsi_lun)); 431 memcpy(scsi_lun, tmfabort_hdr->lun, sizeof(struct scsi_lun));
432 tmfabort_wqe->lun[0] = be32_to_cpu(scsi_lun[0]);
433 tmfabort_wqe->lun[1] = be32_to_cpu(scsi_lun[1]);
434
430 tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn); 435 tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn);
431 436
432 tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma; 437 tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma;
@@ -697,10 +702,11 @@ void bnx2i_send_cmd_cleanup_req(struct bnx2i_hba *hba, struct bnx2i_cmd *cmd)
697 * this routine prepares and posts CONN_OFLD_REQ1/2 KWQE to initiate 702 * this routine prepares and posts CONN_OFLD_REQ1/2 KWQE to initiate
698 * iscsi connection context clean-up process 703 * iscsi connection context clean-up process
699 */ 704 */
700void bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep) 705int bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
701{ 706{
702 struct kwqe *kwqe_arr[2]; 707 struct kwqe *kwqe_arr[2];
703 struct iscsi_kwqe_conn_destroy conn_cleanup; 708 struct iscsi_kwqe_conn_destroy conn_cleanup;
709 int rc = -EINVAL;
704 710
705 memset(&conn_cleanup, 0x00, sizeof(struct iscsi_kwqe_conn_destroy)); 711 memset(&conn_cleanup, 0x00, sizeof(struct iscsi_kwqe_conn_destroy));
706 712
@@ -717,7 +723,9 @@ void bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
717 723
718 kwqe_arr[0] = (struct kwqe *) &conn_cleanup; 724 kwqe_arr[0] = (struct kwqe *) &conn_cleanup;
719 if (hba->cnic && hba->cnic->submit_kwqes) 725 if (hba->cnic && hba->cnic->submit_kwqes)
720 hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, 1); 726 rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, 1);
727
728 return rc;
721} 729}
722 730
723 731
@@ -728,8 +736,8 @@ void bnx2i_send_conn_destroy(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
728 * 736 *
729 * 5706/5708/5709 specific - prepares and posts CONN_OFLD_REQ1/2 KWQE 737 * 5706/5708/5709 specific - prepares and posts CONN_OFLD_REQ1/2 KWQE
730 */ 738 */
731static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba, 739static int bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
732 struct bnx2i_endpoint *ep) 740 struct bnx2i_endpoint *ep)
733{ 741{
734 struct kwqe *kwqe_arr[2]; 742 struct kwqe *kwqe_arr[2];
735 struct iscsi_kwqe_conn_offload1 ofld_req1; 743 struct iscsi_kwqe_conn_offload1 ofld_req1;
@@ -737,6 +745,7 @@ static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
737 dma_addr_t dma_addr; 745 dma_addr_t dma_addr;
738 int num_kwqes = 2; 746 int num_kwqes = 2;
739 u32 *ptbl; 747 u32 *ptbl;
748 int rc = -EINVAL;
740 749
741 ofld_req1.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN1; 750 ofld_req1.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN1;
742 ofld_req1.hdr.flags = 751 ofld_req1.hdr.flags =
@@ -774,7 +783,9 @@ static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
774 ofld_req2.num_additional_wqes = 0; 783 ofld_req2.num_additional_wqes = 0;
775 784
776 if (hba->cnic && hba->cnic->submit_kwqes) 785 if (hba->cnic && hba->cnic->submit_kwqes)
777 hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes); 786 rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
787
788 return rc;
778} 789}
779 790
780 791
@@ -785,8 +796,8 @@ static void bnx2i_570x_send_conn_ofld_req(struct bnx2i_hba *hba,
785 * 796 *
786 * 57710 specific - prepares and posts CONN_OFLD_REQ1/2 KWQE 797 * 57710 specific - prepares and posts CONN_OFLD_REQ1/2 KWQE
787 */ 798 */
788static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba, 799static int bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
789 struct bnx2i_endpoint *ep) 800 struct bnx2i_endpoint *ep)
790{ 801{
791 struct kwqe *kwqe_arr[5]; 802 struct kwqe *kwqe_arr[5];
792 struct iscsi_kwqe_conn_offload1 ofld_req1; 803 struct iscsi_kwqe_conn_offload1 ofld_req1;
@@ -795,6 +806,7 @@ static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
795 dma_addr_t dma_addr; 806 dma_addr_t dma_addr;
796 int num_kwqes = 2; 807 int num_kwqes = 2;
797 u32 *ptbl; 808 u32 *ptbl;
809 int rc = -EINVAL;
798 810
799 ofld_req1.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN1; 811 ofld_req1.hdr.op_code = ISCSI_KWQE_OPCODE_OFFLOAD_CONN1;
800 ofld_req1.hdr.flags = 812 ofld_req1.hdr.flags =
@@ -840,7 +852,9 @@ static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
840 num_kwqes += 1; 852 num_kwqes += 1;
841 853
842 if (hba->cnic && hba->cnic->submit_kwqes) 854 if (hba->cnic && hba->cnic->submit_kwqes)
843 hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes); 855 rc = hba->cnic->submit_kwqes(hba->cnic, kwqe_arr, num_kwqes);
856
857 return rc;
844} 858}
845 859
846/** 860/**
@@ -851,12 +865,16 @@ static void bnx2i_5771x_send_conn_ofld_req(struct bnx2i_hba *hba,
851 * 865 *
852 * this routine prepares and posts CONN_OFLD_REQ1/2 KWQE 866 * this routine prepares and posts CONN_OFLD_REQ1/2 KWQE
853 */ 867 */
854void bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep) 868int bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep)
855{ 869{
870 int rc;
871
856 if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) 872 if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
857 bnx2i_5771x_send_conn_ofld_req(hba, ep); 873 rc = bnx2i_5771x_send_conn_ofld_req(hba, ep);
858 else 874 else
859 bnx2i_570x_send_conn_ofld_req(hba, ep); 875 rc = bnx2i_570x_send_conn_ofld_req(hba, ep);
876
877 return rc;
860} 878}
861 879
862 880
@@ -1513,7 +1531,7 @@ static void bnx2i_process_nopin_local_cmpl(struct iscsi_session *session,
1513 task = iscsi_itt_to_task(conn, 1531 task = iscsi_itt_to_task(conn,
1514 nop_in->itt & ISCSI_NOP_IN_MSG_INDEX); 1532 nop_in->itt & ISCSI_NOP_IN_MSG_INDEX);
1515 if (task) 1533 if (task)
1516 iscsi_put_task(task); 1534 __iscsi_put_task(task);
1517 spin_unlock(&session->lock); 1535 spin_unlock(&session->lock);
1518} 1536}
1519 1537
@@ -1549,11 +1567,9 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
1549 struct iscsi_task *task; 1567 struct iscsi_task *task;
1550 struct bnx2i_nop_in_msg *nop_in; 1568 struct bnx2i_nop_in_msg *nop_in;
1551 struct iscsi_nopin *hdr; 1569 struct iscsi_nopin *hdr;
1552 u32 itt;
1553 int tgt_async_nop = 0; 1570 int tgt_async_nop = 0;
1554 1571
1555 nop_in = (struct bnx2i_nop_in_msg *)cqe; 1572 nop_in = (struct bnx2i_nop_in_msg *)cqe;
1556 itt = nop_in->itt & ISCSI_NOP_IN_MSG_INDEX;
1557 1573
1558 spin_lock(&session->lock); 1574 spin_lock(&session->lock);
1559 hdr = (struct iscsi_nopin *)&bnx2i_conn->gen_pdu.resp_hdr; 1575 hdr = (struct iscsi_nopin *)&bnx2i_conn->gen_pdu.resp_hdr;
@@ -1563,7 +1579,7 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
1563 hdr->exp_cmdsn = cpu_to_be32(nop_in->exp_cmd_sn); 1579 hdr->exp_cmdsn = cpu_to_be32(nop_in->exp_cmd_sn);
1564 hdr->ttt = cpu_to_be32(nop_in->ttt); 1580 hdr->ttt = cpu_to_be32(nop_in->ttt);
1565 1581
1566 if (itt == (u16) RESERVED_ITT) { 1582 if (nop_in->itt == (u16) RESERVED_ITT) {
1567 bnx2i_unsol_pdu_adjust_rq(bnx2i_conn); 1583 bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
1568 hdr->itt = RESERVED_ITT; 1584 hdr->itt = RESERVED_ITT;
1569 tgt_async_nop = 1; 1585 tgt_async_nop = 1;
@@ -1571,7 +1587,8 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
1571 } 1587 }
1572 1588
1573 /* this is a response to one of our nop-outs */ 1589 /* this is a response to one of our nop-outs */
1574 task = iscsi_itt_to_task(conn, itt); 1590 task = iscsi_itt_to_task(conn,
1591 (itt_t) (nop_in->itt & ISCSI_NOP_IN_MSG_INDEX));
1575 if (task) { 1592 if (task) {
1576 hdr->flags = ISCSI_FLAG_CMD_FINAL; 1593 hdr->flags = ISCSI_FLAG_CMD_FINAL;
1577 hdr->itt = task->hdr->itt; 1594 hdr->itt = task->hdr->itt;
@@ -1721,9 +1738,18 @@ static void bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
1721 if (nopin->cq_req_sn != qp->cqe_exp_seq_sn) 1738 if (nopin->cq_req_sn != qp->cqe_exp_seq_sn)
1722 break; 1739 break;
1723 1740
1724 if (unlikely(test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx))) 1741 if (unlikely(test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx))) {
1742 if (nopin->op_code == ISCSI_OP_NOOP_IN &&
1743 nopin->itt == (u16) RESERVED_ITT) {
1744 printk(KERN_ALERT "bnx2i: Unsolicited "
1745 "NOP-In detected for suspended "
1746 "connection dev=%s!\n",
1747 bnx2i_conn->hba->netdev->name);
1748 bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
1749 goto cqe_out;
1750 }
1725 break; 1751 break;
1726 1752 }
1727 tgt_async_msg = 0; 1753 tgt_async_msg = 0;
1728 1754
1729 switch (nopin->op_code) { 1755 switch (nopin->op_code) {
@@ -1770,10 +1796,9 @@ static void bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
1770 printk(KERN_ALERT "bnx2i: unknown opcode 0x%x\n", 1796 printk(KERN_ALERT "bnx2i: unknown opcode 0x%x\n",
1771 nopin->op_code); 1797 nopin->op_code);
1772 } 1798 }
1773
1774 if (!tgt_async_msg) 1799 if (!tgt_async_msg)
1775 bnx2i_conn->ep->num_active_cmds--; 1800 bnx2i_conn->ep->num_active_cmds--;
1776 1801cqe_out:
1777 /* clear out in production version only, till beta keep opcode 1802 /* clear out in production version only, till beta keep opcode
1778 * field intact, will be helpful in debugging (context dump) 1803 * field intact, will be helpful in debugging (context dump)
1779 * nopin->op_code = 0; 1804 * nopin->op_code = 0;
@@ -2154,11 +2179,24 @@ static void bnx2i_process_ofld_cmpl(struct bnx2i_hba *hba,
2154 } 2179 }
2155 2180
2156 if (ofld_kcqe->completion_status) { 2181 if (ofld_kcqe->completion_status) {
2182 ep->state = EP_STATE_OFLD_FAILED;
2157 if (ofld_kcqe->completion_status == 2183 if (ofld_kcqe->completion_status ==
2158 ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE) 2184 ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE)
2159 printk(KERN_ALERT "bnx2i: unable to allocate" 2185 printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - unable "
2160 " iSCSI context resources\n"); 2186 "to allocate iSCSI context resources\n",
2161 ep->state = EP_STATE_OFLD_FAILED; 2187 hba->netdev->name);
2188 else if (ofld_kcqe->completion_status ==
2189 ISCSI_KCQE_COMPLETION_STATUS_INVALID_OPCODE)
2190 printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - invalid "
2191 "opcode\n", hba->netdev->name);
2192 else if (ofld_kcqe->completion_status ==
2193 ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY)
2194 /* error status code valid only for 5771x chipset */
2195 ep->state = EP_STATE_OFLD_FAILED_CID_BUSY;
2196 else
2197 printk(KERN_ALERT "bnx2i (%s): ofld1 cmpl - invalid "
2198 "error code %d\n", hba->netdev->name,
2199 ofld_kcqe->completion_status);
2162 } else { 2200 } else {
2163 ep->state = EP_STATE_OFLD_COMPL; 2201 ep->state = EP_STATE_OFLD_COMPL;
2164 cid_addr = ofld_kcqe->iscsi_conn_context_id; 2202 cid_addr = ofld_kcqe->iscsi_conn_context_id;
@@ -2339,10 +2377,14 @@ static void bnx2i_cm_remote_close(struct cnic_sock *cm_sk)
2339static void bnx2i_cm_remote_abort(struct cnic_sock *cm_sk) 2377static void bnx2i_cm_remote_abort(struct cnic_sock *cm_sk)
2340{ 2378{
2341 struct bnx2i_endpoint *ep = (struct bnx2i_endpoint *) cm_sk->context; 2379 struct bnx2i_endpoint *ep = (struct bnx2i_endpoint *) cm_sk->context;
2380 u32 old_state = ep->state;
2342 2381
2343 ep->state = EP_STATE_TCP_RST_RCVD; 2382 ep->state = EP_STATE_TCP_RST_RCVD;
2344 if (ep->conn) 2383 if (old_state == EP_STATE_DISCONN_START)
2345 bnx2i_recovery_que_add_conn(ep->hba, ep->conn); 2384 wake_up_interruptible(&ep->ofld_wait);
2385 else
2386 if (ep->conn)
2387 bnx2i_recovery_que_add_conn(ep->hba, ep->conn);
2346} 2388}
2347 2389
2348 2390