aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-07 15:47:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-07 15:47:02 -0500
commitda40d036fd716f0efb2917076220814b1e927ae1 (patch)
tree567893573a48e2954d82421e77606034d3b32f84 /drivers/scsi/bnx2i
parentaa58abc20fa85328a9f048e2626c0893691ff284 (diff)
parentc32e061fa19893ce4acf95d97d5613a161f0f1b7 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (147 commits) [SCSI] arcmsr: fix write to device check [SCSI] lpfc: lower stack use in lpfc_fc_frame_check [SCSI] eliminate an unnecessary local variable from scsi_remove_target() [SCSI] libiscsi: use bh locking instead of irq with session lock [SCSI] libiscsi: do not take host lock in queuecommand [SCSI] be2iscsi: fix null ptr when accessing task hdr [SCSI] be2iscsi: fix gfp use in alloc_pdu [SCSI] libiscsi: add more informative failure message during iscsi scsi eh [SCSI] gdth: Add missing call to gdth_ioctl_free [SCSI] bfa: remove unused defintions and misc cleanups [SCSI] bfa: remove inactive functions [SCSI] bfa: replace bfa_assert with WARN_ON [SCSI] qla2xxx: Use sg_next to fetch next sg element while walking sg list. [SCSI] qla2xxx: Fix to avoid recursive lock failure during BSG timeout. [SCSI] qla2xxx: Remove code to not reset ISP82xx on failure. [SCSI] qla2xxx: Display mailbox register 4 during 8012 AEN for ISP82XX parts. [SCSI] qla2xxx: Don't perform a BIG_HAMMER if Get-ID (0x20) mailbox command fails on CNAs. [SCSI] qla2xxx: Remove redundant module parameter permission bits [SCSI] qla2xxx: Add sysfs node for displaying board temperature. [SCSI] qla2xxx: Code cleanup to remove unwanted comments and code. ...
Diffstat (limited to 'drivers/scsi/bnx2i')
-rw-r--r--drivers/scsi/bnx2i/57xx_iscsi_constants.h3
-rw-r--r--drivers/scsi/bnx2i/57xx_iscsi_hsi.h3
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h15
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c96
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c108
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c148
-rw-r--r--drivers/scsi/bnx2i/bnx2i_sysfs.c3
7 files changed, 195 insertions, 181 deletions
diff --git a/drivers/scsi/bnx2i/57xx_iscsi_constants.h b/drivers/scsi/bnx2i/57xx_iscsi_constants.h
index 1b6f86b2482d..30e6bdbd65af 100644
--- a/drivers/scsi/bnx2i/57xx_iscsi_constants.h
+++ b/drivers/scsi/bnx2i/57xx_iscsi_constants.h
@@ -1,12 +1,13 @@
1/* 57xx_iscsi_constants.h: Broadcom NetXtreme II iSCSI HSI 1/* 57xx_iscsi_constants.h: Broadcom NetXtreme II iSCSI HSI
2 * 2 *
3 * Copyright (c) 2006 - 2009 Broadcom Corporation 3 * Copyright (c) 2006 - 2010 Broadcom Corporation
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation. 7 * the Free Software Foundation.
8 * 8 *
9 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com) 9 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
10 * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
10 */ 11 */
11#ifndef __57XX_ISCSI_CONSTANTS_H_ 12#ifndef __57XX_ISCSI_CONSTANTS_H_
12#define __57XX_ISCSI_CONSTANTS_H_ 13#define __57XX_ISCSI_CONSTANTS_H_
diff --git a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
index 36af1afef9b6..dad6c8a34317 100644
--- a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
+++ b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
@@ -1,12 +1,13 @@
1/* 57xx_iscsi_hsi.h: Broadcom NetXtreme II iSCSI HSI. 1/* 57xx_iscsi_hsi.h: Broadcom NetXtreme II iSCSI HSI.
2 * 2 *
3 * Copyright (c) 2006 - 2009 Broadcom Corporation 3 * Copyright (c) 2006 - 2010 Broadcom Corporation
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation. 7 * the Free Software Foundation.
8 * 8 *
9 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com) 9 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
10 * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
10 */ 11 */
11#ifndef __57XX_ISCSI_HSI_LINUX_LE__ 12#ifndef __57XX_ISCSI_HSI_LINUX_LE__
12#define __57XX_ISCSI_HSI_LINUX_LE__ 13#define __57XX_ISCSI_HSI_LINUX_LE__
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index a44b1b33fa18..e1ca5fe7e6bb 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -1,6 +1,6 @@
1/* bnx2i.h: Broadcom NetXtreme II iSCSI driver. 1/* bnx2i.h: 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#ifndef _BNX2I_H_ 15#ifndef _BNX2I_H_
@@ -649,6 +650,7 @@ enum {
649 EP_STATE_OFLD_FAILED = 0x8000000, 650 EP_STATE_OFLD_FAILED = 0x8000000,
650 EP_STATE_CONNECT_FAILED = 0x10000000, 651 EP_STATE_CONNECT_FAILED = 0x10000000,
651 EP_STATE_DISCONN_TIMEDOUT = 0x20000000, 652 EP_STATE_DISCONN_TIMEDOUT = 0x20000000,
653 EP_STATE_OFLD_FAILED_CID_BUSY = 0x80000000,
652}; 654};
653 655
654/** 656/**
@@ -717,14 +719,11 @@ extern struct device_attribute *bnx2i_dev_attributes[];
717 * Function Prototypes 719 * Function Prototypes
718 */ 720 */
719extern void bnx2i_identify_device(struct bnx2i_hba *hba); 721extern void bnx2i_identify_device(struct bnx2i_hba *hba);
720extern void bnx2i_register_device(struct bnx2i_hba *hba);
721 722
722extern void bnx2i_ulp_init(struct cnic_dev *dev); 723extern void bnx2i_ulp_init(struct cnic_dev *dev);
723extern void bnx2i_ulp_exit(struct cnic_dev *dev); 724extern void bnx2i_ulp_exit(struct cnic_dev *dev);
724extern void bnx2i_start(void *handle); 725extern void bnx2i_start(void *handle);
725extern void bnx2i_stop(void *handle); 726extern void bnx2i_stop(void *handle);
726extern void bnx2i_reg_dev_all(void);
727extern void bnx2i_unreg_dev_all(void);
728extern struct bnx2i_hba *get_adapter_list_head(void); 727extern struct bnx2i_hba *get_adapter_list_head(void);
729 728
730struct bnx2i_conn *bnx2i_get_conn_from_id(struct bnx2i_hba *hba, 729struct bnx2i_conn *bnx2i_get_conn_from_id(struct bnx2i_hba *hba,
@@ -761,11 +760,11 @@ extern int bnx2i_send_iscsi_logout(struct bnx2i_conn *conn,
761 struct iscsi_task *mtask); 760 struct iscsi_task *mtask);
762extern void bnx2i_send_cmd_cleanup_req(struct bnx2i_hba *hba, 761extern void bnx2i_send_cmd_cleanup_req(struct bnx2i_hba *hba,
763 struct bnx2i_cmd *cmd); 762 struct bnx2i_cmd *cmd);
764extern void bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba, 763extern int bnx2i_send_conn_ofld_req(struct bnx2i_hba *hba,
765 struct bnx2i_endpoint *ep);
766extern void bnx2i_update_iscsi_conn(struct iscsi_conn *conn);
767extern void bnx2i_send_conn_destroy(struct bnx2i_hba *hba,
768 struct bnx2i_endpoint *ep); 764 struct bnx2i_endpoint *ep);
765extern void bnx2i_update_iscsi_conn(struct iscsi_conn *conn);
766extern int bnx2i_send_conn_destroy(struct bnx2i_hba *hba,
767 struct bnx2i_endpoint *ep);
769 768
770extern int bnx2i_alloc_qp_resc(struct bnx2i_hba *hba, 769extern int bnx2i_alloc_qp_resc(struct bnx2i_hba *hba,
771 struct bnx2i_endpoint *ep); 770 struct bnx2i_endpoint *ep);
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
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index 50c2aa3b8eb1..72a7b2d4a439 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -1,6 +1,6 @@
1/* bnx2i.c: Broadcom NetXtreme II iSCSI driver. 1/* bnx2i.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 "bnx2i.h" 15#include "bnx2i.h"
@@ -17,8 +18,8 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list);
17static u32 adapter_count; 18static u32 adapter_count;
18 19
19#define DRV_MODULE_NAME "bnx2i" 20#define DRV_MODULE_NAME "bnx2i"
20#define DRV_MODULE_VERSION "2.1.3" 21#define DRV_MODULE_VERSION "2.6.2.2"
21#define DRV_MODULE_RELDATE "Aug 10, 2010" 22#define DRV_MODULE_RELDATE "Nov 23, 2010"
22 23
23static char version[] __devinitdata = 24static char version[] __devinitdata =
24 "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \ 25 "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
@@ -65,8 +66,6 @@ MODULE_PARM_DESC(rq_size, "Configure RQ size");
65 66
66u64 iscsi_error_mask = 0x00; 67u64 iscsi_error_mask = 0x00;
67 68
68static void bnx2i_unreg_one_device(struct bnx2i_hba *hba) ;
69
70 69
71/** 70/**
72 * bnx2i_identify_device - identifies NetXtreme II device type 71 * bnx2i_identify_device - identifies NetXtreme II device type
@@ -211,13 +210,24 @@ void bnx2i_stop(void *handle)
211{ 210{
212 struct bnx2i_hba *hba = handle; 211 struct bnx2i_hba *hba = handle;
213 int conns_active; 212 int conns_active;
213 int wait_delay = 1 * HZ;
214 214
215 /* check if cleanup happened in GOING_DOWN context */ 215 /* check if cleanup happened in GOING_DOWN context */
216 if (!test_and_clear_bit(ADAPTER_STATE_GOING_DOWN, 216 if (!test_and_set_bit(ADAPTER_STATE_GOING_DOWN,
217 &hba->adapter_state)) 217 &hba->adapter_state)) {
218 iscsi_host_for_each_session(hba->shost, 218 iscsi_host_for_each_session(hba->shost,
219 bnx2i_drop_session); 219 bnx2i_drop_session);
220 220 wait_delay = hba->hba_shutdown_tmo;
221 }
222 /* Wait for inflight offload connection tasks to complete before
223 * proceeding. Forcefully terminate all connection recovery in
224 * progress at the earliest, either in bind(), send_pdu(LOGIN),
225 * or conn_start()
226 */
227 wait_event_interruptible_timeout(hba->eh_wait,
228 (list_empty(&hba->ep_ofld_list) &&
229 list_empty(&hba->ep_destroy_list)),
230 10 * HZ);
221 /* Wait for all endpoints to be torn down, Chip will be reset once 231 /* Wait for all endpoints to be torn down, Chip will be reset once
222 * control returns to network driver. So it is required to cleanup and 232 * control returns to network driver. So it is required to cleanup and
223 * release all connection resources before returning from this routine. 233 * release all connection resources before returning from this routine.
@@ -226,7 +236,7 @@ void bnx2i_stop(void *handle)
226 conns_active = hba->ofld_conns_active; 236 conns_active = hba->ofld_conns_active;
227 wait_event_interruptible_timeout(hba->eh_wait, 237 wait_event_interruptible_timeout(hba->eh_wait,
228 (hba->ofld_conns_active != conns_active), 238 (hba->ofld_conns_active != conns_active),
229 hba->hba_shutdown_tmo); 239 wait_delay);
230 if (hba->ofld_conns_active == conns_active) 240 if (hba->ofld_conns_active == conns_active)
231 break; 241 break;
232 } 242 }
@@ -235,88 +245,10 @@ void bnx2i_stop(void *handle)
235 /* This flag should be cleared last so that ep_disconnect() gracefully 245 /* This flag should be cleared last so that ep_disconnect() gracefully
236 * cleans up connection context 246 * cleans up connection context
237 */ 247 */
248 clear_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
238 clear_bit(ADAPTER_STATE_UP, &hba->adapter_state); 249 clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
239} 250}
240 251
241/**
242 * bnx2i_register_device - register bnx2i adapter instance with the cnic driver
243 * @hba: Adapter instance to register
244 *
245 * registers bnx2i adapter instance with the cnic driver while holding the
246 * adapter structure lock
247 */
248void bnx2i_register_device(struct bnx2i_hba *hba)
249{
250 int rc;
251
252 if (test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state) ||
253 test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
254 return;
255 }
256
257 rc = hba->cnic->register_device(hba->cnic, CNIC_ULP_ISCSI, hba);
258
259 if (!rc)
260 set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
261}
262
263
264/**
265 * bnx2i_reg_dev_all - registers all adapter instances with the cnic driver
266 *
267 * registers all bnx2i adapter instances with the cnic driver while holding
268 * the global resource lock
269 */
270void bnx2i_reg_dev_all(void)
271{
272 struct bnx2i_hba *hba, *temp;
273
274 mutex_lock(&bnx2i_dev_lock);
275 list_for_each_entry_safe(hba, temp, &adapter_list, link)
276 bnx2i_register_device(hba);
277 mutex_unlock(&bnx2i_dev_lock);
278}
279
280
281/**
282 * bnx2i_unreg_one_device - unregister adapter instance with the cnic driver
283 * @hba: Adapter instance to unregister
284 *
285 * registers bnx2i adapter instance with the cnic driver while holding
286 * the adapter structure lock
287 */
288static void bnx2i_unreg_one_device(struct bnx2i_hba *hba)
289{
290 if (hba->ofld_conns_active ||
291 !test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic) ||
292 test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state))
293 return;
294
295 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
296
297 /* ep_disconnect could come before NETDEV_DOWN, driver won't
298 * see NETDEV_DOWN as it already unregistered itself.
299 */
300 hba->adapter_state = 0;
301 clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
302}
303
304/**
305 * bnx2i_unreg_dev_all - unregisters all bnx2i instances with the cnic driver
306 *
307 * unregisters all bnx2i adapter instances with the cnic driver while holding
308 * the global resource lock
309 */
310void bnx2i_unreg_dev_all(void)
311{
312 struct bnx2i_hba *hba, *temp;
313
314 mutex_lock(&bnx2i_dev_lock);
315 list_for_each_entry_safe(hba, temp, &adapter_list, link)
316 bnx2i_unreg_one_device(hba);
317 mutex_unlock(&bnx2i_dev_lock);
318}
319
320 252
321/** 253/**
322 * bnx2i_init_one - initialize an adapter instance and allocate memory resources 254 * bnx2i_init_one - initialize an adapter instance and allocate memory resources
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index fb50efbce087..f0dce26593eb 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * bnx2i_iscsi.c: Broadcom NetXtreme II iSCSI driver. 2 * bnx2i_iscsi.c: Broadcom NetXtreme II iSCSI driver.
3 * 3 *
4 * Copyright (c) 2006 - 2009 Broadcom Corporation 4 * Copyright (c) 2006 - 2010 Broadcom Corporation
5 * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved. 5 * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
6 * Copyright (c) 2007, 2008 Mike Christie 6 * Copyright (c) 2007, 2008 Mike Christie
7 * 7 *
@@ -10,6 +10,7 @@
10 * the Free Software Foundation. 10 * the Free Software Foundation.
11 * 11 *
12 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com) 12 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
13 * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
13 */ 14 */
14 15
15#include <linux/slab.h> 16#include <linux/slab.h>
@@ -411,7 +412,9 @@ static void bnx2i_free_ep(struct iscsi_endpoint *ep)
411 bnx2i_ep->state = EP_STATE_IDLE; 412 bnx2i_ep->state = EP_STATE_IDLE;
412 bnx2i_ep->hba->ofld_conns_active--; 413 bnx2i_ep->hba->ofld_conns_active--;
413 414
414 bnx2i_free_iscsi_cid(bnx2i_ep->hba, bnx2i_ep->ep_iscsi_cid); 415 if (bnx2i_ep->ep_iscsi_cid != (u16) -1)
416 bnx2i_free_iscsi_cid(bnx2i_ep->hba, bnx2i_ep->ep_iscsi_cid);
417
415 if (bnx2i_ep->conn) { 418 if (bnx2i_ep->conn) {
416 bnx2i_ep->conn->ep = NULL; 419 bnx2i_ep->conn->ep = NULL;
417 bnx2i_ep->conn = NULL; 420 bnx2i_ep->conn = NULL;
@@ -1383,6 +1386,12 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
1383 ep = iscsi_lookup_endpoint(transport_fd); 1386 ep = iscsi_lookup_endpoint(transport_fd);
1384 if (!ep) 1387 if (!ep)
1385 return -EINVAL; 1388 return -EINVAL;
1389 /*
1390 * Forcefully terminate all in progress connection recovery at the
1391 * earliest, either in bind(), send_pdu(LOGIN), or conn_start()
1392 */
1393 if (bnx2i_adapter_ready(hba))
1394 return -EIO;
1386 1395
1387 bnx2i_ep = ep->dd_data; 1396 bnx2i_ep = ep->dd_data;
1388 if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) || 1397 if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) ||
@@ -1404,7 +1413,6 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
1404 hba->netdev->name); 1413 hba->netdev->name);
1405 return -EEXIST; 1414 return -EEXIST;
1406 } 1415 }
1407
1408 bnx2i_ep->conn = bnx2i_conn; 1416 bnx2i_ep->conn = bnx2i_conn;
1409 bnx2i_conn->ep = bnx2i_ep; 1417 bnx2i_conn->ep = bnx2i_ep;
1410 bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid; 1418 bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid;
@@ -1461,21 +1469,28 @@ static int bnx2i_conn_get_param(struct iscsi_cls_conn *cls_conn,
1461 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1469 struct bnx2i_conn *bnx2i_conn = conn->dd_data;
1462 int len = 0; 1470 int len = 0;
1463 1471
1472 if (!(bnx2i_conn && bnx2i_conn->ep && bnx2i_conn->ep->hba))
1473 goto out;
1474
1464 switch (param) { 1475 switch (param) {
1465 case ISCSI_PARAM_CONN_PORT: 1476 case ISCSI_PARAM_CONN_PORT:
1466 if (bnx2i_conn->ep) 1477 mutex_lock(&bnx2i_conn->ep->hba->net_dev_lock);
1478 if (bnx2i_conn->ep->cm_sk)
1467 len = sprintf(buf, "%hu\n", 1479 len = sprintf(buf, "%hu\n",
1468 bnx2i_conn->ep->cm_sk->dst_port); 1480 bnx2i_conn->ep->cm_sk->dst_port);
1481 mutex_unlock(&bnx2i_conn->ep->hba->net_dev_lock);
1469 break; 1482 break;
1470 case ISCSI_PARAM_CONN_ADDRESS: 1483 case ISCSI_PARAM_CONN_ADDRESS:
1471 if (bnx2i_conn->ep) 1484 mutex_lock(&bnx2i_conn->ep->hba->net_dev_lock);
1485 if (bnx2i_conn->ep->cm_sk)
1472 len = sprintf(buf, "%pI4\n", 1486 len = sprintf(buf, "%pI4\n",
1473 &bnx2i_conn->ep->cm_sk->dst_ip); 1487 &bnx2i_conn->ep->cm_sk->dst_ip);
1488 mutex_unlock(&bnx2i_conn->ep->hba->net_dev_lock);
1474 break; 1489 break;
1475 default: 1490 default:
1476 return iscsi_conn_get_param(cls_conn, param, buf); 1491 return iscsi_conn_get_param(cls_conn, param, buf);
1477 } 1492 }
1478 1493out:
1479 return len; 1494 return len;
1480} 1495}
1481 1496
@@ -1599,8 +1614,6 @@ static struct bnx2i_hba *bnx2i_check_route(struct sockaddr *dst_addr)
1599 struct bnx2i_hba *hba; 1614 struct bnx2i_hba *hba;
1600 struct cnic_dev *cnic = NULL; 1615 struct cnic_dev *cnic = NULL;
1601 1616
1602 bnx2i_reg_dev_all();
1603
1604 hba = get_adapter_list_head(); 1617 hba = get_adapter_list_head();
1605 if (hba && hba->cnic) 1618 if (hba && hba->cnic)
1606 cnic = hba->cnic->cm_select_dev(desti, CNIC_ULP_ISCSI); 1619 cnic = hba->cnic->cm_select_dev(desti, CNIC_ULP_ISCSI);
@@ -1640,18 +1653,26 @@ no_nx2_route:
1640static int bnx2i_tear_down_conn(struct bnx2i_hba *hba, 1653static int bnx2i_tear_down_conn(struct bnx2i_hba *hba,
1641 struct bnx2i_endpoint *ep) 1654 struct bnx2i_endpoint *ep)
1642{ 1655{
1643 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) 1656 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic) && ep->cm_sk)
1644 hba->cnic->cm_destroy(ep->cm_sk); 1657 hba->cnic->cm_destroy(ep->cm_sk);
1645 1658
1646 if (test_bit(ADAPTER_STATE_GOING_DOWN, &ep->hba->adapter_state))
1647 ep->state = EP_STATE_DISCONN_COMPL;
1648
1649 if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type) && 1659 if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type) &&
1650 ep->state == EP_STATE_DISCONN_TIMEDOUT) { 1660 ep->state == EP_STATE_DISCONN_TIMEDOUT) {
1651 printk(KERN_ALERT "bnx2i - ERROR - please submit GRC Dump," 1661 if (ep->conn && ep->conn->cls_conn &&
1652 " NW/PCIe trace, driver msgs to developers" 1662 ep->conn->cls_conn->dd_data) {
1653 " for analysis\n"); 1663 struct iscsi_conn *conn = ep->conn->cls_conn->dd_data;
1654 return 1; 1664
1665 /* Must suspend all rx queue activity for this ep */
1666 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
1667 }
1668 /* CONN_DISCONNECT timeout may or may not be an issue depending
1669 * on what transcribed in TCP layer, different targets behave
1670 * differently
1671 */
1672 printk(KERN_ALERT "bnx2i (%s): - WARN - CONN_DISCON timed out, "
1673 "please submit GRC Dump, NW/PCIe trace, "
1674 "driver msgs to developers for analysis\n",
1675 hba->netdev->name);
1655 } 1676 }
1656 1677
1657 ep->state = EP_STATE_CLEANUP_START; 1678 ep->state = EP_STATE_CLEANUP_START;
@@ -1664,7 +1685,9 @@ static int bnx2i_tear_down_conn(struct bnx2i_hba *hba,
1664 bnx2i_ep_destroy_list_add(hba, ep); 1685 bnx2i_ep_destroy_list_add(hba, ep);
1665 1686
1666 /* destroy iSCSI context, wait for it to complete */ 1687 /* destroy iSCSI context, wait for it to complete */
1667 bnx2i_send_conn_destroy(hba, ep); 1688 if (bnx2i_send_conn_destroy(hba, ep))
1689 ep->state = EP_STATE_CLEANUP_CMPL;
1690
1668 wait_event_interruptible(ep->ofld_wait, 1691 wait_event_interruptible(ep->ofld_wait,
1669 (ep->state != EP_STATE_CLEANUP_START)); 1692 (ep->state != EP_STATE_CLEANUP_START));
1670 1693
@@ -1711,8 +1734,6 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1711 if (shost) { 1734 if (shost) {
1712 /* driver is given scsi host to work with */ 1735 /* driver is given scsi host to work with */
1713 hba = iscsi_host_priv(shost); 1736 hba = iscsi_host_priv(shost);
1714 /* Register the device with cnic if not already done so */
1715 bnx2i_register_device(hba);
1716 } else 1737 } else
1717 /* 1738 /*
1718 * check if the given destination can be reached through 1739 * check if the given destination can be reached through
@@ -1720,13 +1741,17 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1720 */ 1741 */
1721 hba = bnx2i_check_route(dst_addr); 1742 hba = bnx2i_check_route(dst_addr);
1722 1743
1723 if (!hba || test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state)) { 1744 if (!hba) {
1724 rc = -EINVAL; 1745 rc = -EINVAL;
1725 goto nohba; 1746 goto nohba;
1726 } 1747 }
1748 mutex_lock(&hba->net_dev_lock);
1727 1749
1750 if (bnx2i_adapter_ready(hba) || !hba->cid_que.cid_free_cnt) {
1751 rc = -EPERM;
1752 goto check_busy;
1753 }
1728 cnic = hba->cnic; 1754 cnic = hba->cnic;
1729 mutex_lock(&hba->net_dev_lock);
1730 ep = bnx2i_alloc_ep(hba); 1755 ep = bnx2i_alloc_ep(hba);
1731 if (!ep) { 1756 if (!ep) {
1732 rc = -ENOMEM; 1757 rc = -ENOMEM;
@@ -1734,23 +1759,21 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1734 } 1759 }
1735 bnx2i_ep = ep->dd_data; 1760 bnx2i_ep = ep->dd_data;
1736 1761
1737 if (bnx2i_adapter_ready(hba)) {
1738 rc = -EPERM;
1739 goto net_if_down;
1740 }
1741
1742 bnx2i_ep->num_active_cmds = 0; 1762 bnx2i_ep->num_active_cmds = 0;
1743 iscsi_cid = bnx2i_alloc_iscsi_cid(hba); 1763 iscsi_cid = bnx2i_alloc_iscsi_cid(hba);
1744 if (iscsi_cid == -1) { 1764 if (iscsi_cid == -1) {
1745 printk(KERN_ALERT "alloc_ep: unable to allocate iscsi cid\n"); 1765 printk(KERN_ALERT "bnx2i (%s): alloc_ep - unable to allocate "
1766 "iscsi cid\n", hba->netdev->name);
1746 rc = -ENOMEM; 1767 rc = -ENOMEM;
1747 goto iscsi_cid_err; 1768 bnx2i_free_ep(ep);
1769 goto check_busy;
1748 } 1770 }
1749 bnx2i_ep->hba_age = hba->age; 1771 bnx2i_ep->hba_age = hba->age;
1750 1772
1751 rc = bnx2i_alloc_qp_resc(hba, bnx2i_ep); 1773 rc = bnx2i_alloc_qp_resc(hba, bnx2i_ep);
1752 if (rc != 0) { 1774 if (rc != 0) {
1753 printk(KERN_ALERT "bnx2i: ep_conn, alloc QP resc error\n"); 1775 printk(KERN_ALERT "bnx2i (%s): ep_conn - alloc QP resc error"
1776 "\n", hba->netdev->name);
1754 rc = -ENOMEM; 1777 rc = -ENOMEM;
1755 goto qp_resc_err; 1778 goto qp_resc_err;
1756 } 1779 }
@@ -1765,7 +1788,18 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1765 bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep; 1788 bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep;
1766 add_timer(&bnx2i_ep->ofld_timer); 1789 add_timer(&bnx2i_ep->ofld_timer);
1767 1790
1768 bnx2i_send_conn_ofld_req(hba, bnx2i_ep); 1791 if (bnx2i_send_conn_ofld_req(hba, bnx2i_ep)) {
1792 if (bnx2i_ep->state == EP_STATE_OFLD_FAILED_CID_BUSY) {
1793 printk(KERN_ALERT "bnx2i (%s): iscsi cid %d is busy\n",
1794 hba->netdev->name, bnx2i_ep->ep_iscsi_cid);
1795 rc = -EBUSY;
1796 } else
1797 rc = -ENOSPC;
1798 printk(KERN_ALERT "bnx2i (%s): unable to send conn offld kwqe"
1799 "\n", hba->netdev->name);
1800 bnx2i_ep_ofld_list_del(hba, bnx2i_ep);
1801 goto conn_failed;
1802 }
1769 1803
1770 /* Wait for CNIC hardware to setup conn context and return 'cid' */ 1804 /* Wait for CNIC hardware to setup conn context and return 'cid' */
1771 wait_event_interruptible(bnx2i_ep->ofld_wait, 1805 wait_event_interruptible(bnx2i_ep->ofld_wait,
@@ -1778,7 +1812,12 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1778 bnx2i_ep_ofld_list_del(hba, bnx2i_ep); 1812 bnx2i_ep_ofld_list_del(hba, bnx2i_ep);
1779 1813
1780 if (bnx2i_ep->state != EP_STATE_OFLD_COMPL) { 1814 if (bnx2i_ep->state != EP_STATE_OFLD_COMPL) {
1781 rc = -ENOSPC; 1815 if (bnx2i_ep->state == EP_STATE_OFLD_FAILED_CID_BUSY) {
1816 printk(KERN_ALERT "bnx2i (%s): iscsi cid %d is busy\n",
1817 hba->netdev->name, bnx2i_ep->ep_iscsi_cid);
1818 rc = -EBUSY;
1819 } else
1820 rc = -ENOSPC;
1782 goto conn_failed; 1821 goto conn_failed;
1783 } 1822 }
1784 1823
@@ -1786,7 +1825,8 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1786 iscsi_cid, &bnx2i_ep->cm_sk, bnx2i_ep); 1825 iscsi_cid, &bnx2i_ep->cm_sk, bnx2i_ep);
1787 if (rc) { 1826 if (rc) {
1788 rc = -EINVAL; 1827 rc = -EINVAL;
1789 goto conn_failed; 1828 /* Need to terminate and cleanup the connection */
1829 goto release_ep;
1790 } 1830 }
1791 1831
1792 bnx2i_ep->cm_sk->rcv_buf = 256 * 1024; 1832 bnx2i_ep->cm_sk->rcv_buf = 256 * 1024;
@@ -1830,15 +1870,12 @@ release_ep:
1830 return ERR_PTR(rc); 1870 return ERR_PTR(rc);
1831 } 1871 }
1832conn_failed: 1872conn_failed:
1833net_if_down:
1834iscsi_cid_err:
1835 bnx2i_free_qp_resc(hba, bnx2i_ep); 1873 bnx2i_free_qp_resc(hba, bnx2i_ep);
1836qp_resc_err: 1874qp_resc_err:
1837 bnx2i_free_ep(ep); 1875 bnx2i_free_ep(ep);
1838check_busy: 1876check_busy:
1839 mutex_unlock(&hba->net_dev_lock); 1877 mutex_unlock(&hba->net_dev_lock);
1840nohba: 1878nohba:
1841 bnx2i_unreg_dev_all();
1842 return ERR_PTR(rc); 1879 return ERR_PTR(rc);
1843} 1880}
1844 1881
@@ -1898,12 +1935,13 @@ static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep)
1898 cnic_dev_10g = 1; 1935 cnic_dev_10g = 1;
1899 1936
1900 switch (bnx2i_ep->state) { 1937 switch (bnx2i_ep->state) {
1901 case EP_STATE_CONNECT_START: 1938 case EP_STATE_CONNECT_FAILED:
1902 case EP_STATE_CLEANUP_FAILED: 1939 case EP_STATE_CLEANUP_FAILED:
1903 case EP_STATE_OFLD_FAILED: 1940 case EP_STATE_OFLD_FAILED:
1904 case EP_STATE_DISCONN_TIMEDOUT: 1941 case EP_STATE_DISCONN_TIMEDOUT:
1905 ret = 0; 1942 ret = 0;
1906 break; 1943 break;
1944 case EP_STATE_CONNECT_START:
1907 case EP_STATE_CONNECT_COMPL: 1945 case EP_STATE_CONNECT_COMPL:
1908 case EP_STATE_ULP_UPDATE_START: 1946 case EP_STATE_ULP_UPDATE_START:
1909 case EP_STATE_ULP_UPDATE_COMPL: 1947 case EP_STATE_ULP_UPDATE_COMPL:
@@ -1914,13 +1952,10 @@ static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep)
1914 ret = 1; 1952 ret = 1;
1915 break; 1953 break;
1916 case EP_STATE_TCP_RST_RCVD: 1954 case EP_STATE_TCP_RST_RCVD:
1917 ret = 0;
1918 break;
1919 case EP_STATE_CONNECT_FAILED:
1920 if (cnic_dev_10g) 1955 if (cnic_dev_10g)
1921 ret = 1;
1922 else
1923 ret = 0; 1956 ret = 0;
1957 else
1958 ret = 1;
1924 break; 1959 break;
1925 default: 1960 default:
1926 ret = 0; 1961 ret = 0;
@@ -1953,7 +1988,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
1953 if (!cnic) 1988 if (!cnic)
1954 return 0; 1989 return 0;
1955 1990
1956 if (bnx2i_ep->state == EP_STATE_IDLE) 1991 if (bnx2i_ep->state == EP_STATE_IDLE ||
1992 bnx2i_ep->state == EP_STATE_DISCONN_TIMEDOUT)
1957 return 0; 1993 return 0;
1958 1994
1959 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep)) 1995 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep))
@@ -1979,9 +2015,10 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
1979 if (session->state == ISCSI_STATE_LOGGING_OUT) { 2015 if (session->state == ISCSI_STATE_LOGGING_OUT) {
1980 if (bnx2i_ep->state == EP_STATE_LOGOUT_SENT) { 2016 if (bnx2i_ep->state == EP_STATE_LOGOUT_SENT) {
1981 /* Logout sent, but no resp */ 2017 /* Logout sent, but no resp */
1982 printk(KERN_ALERT "bnx2i - WARNING " 2018 printk(KERN_ALERT "bnx2i (%s): WARNING"
1983 "logout response was not " 2019 " logout response was not "
1984 "received!\n"); 2020 "received!\n",
2021 bnx2i_ep->hba->netdev->name);
1985 } else if (bnx2i_ep->state == 2022 } else if (bnx2i_ep->state ==
1986 EP_STATE_LOGOUT_RESP_RCVD) 2023 EP_STATE_LOGOUT_RESP_RCVD)
1987 close = 1; 2024 close = 1;
@@ -1999,9 +2036,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
1999 else 2036 else
2000 close_ret = cnic->cm_abort(bnx2i_ep->cm_sk); 2037 close_ret = cnic->cm_abort(bnx2i_ep->cm_sk);
2001 2038
2002 /* No longer allow CFC delete if cm_close/abort fails the request */
2003 if (close_ret) 2039 if (close_ret)
2004 printk(KERN_ALERT "bnx2i: %s close/abort(%d) returned %d\n", 2040 printk(KERN_ALERT "bnx2i (%s): close/abort(%d) returned %d\n",
2005 bnx2i_ep->hba->netdev->name, close, close_ret); 2041 bnx2i_ep->hba->netdev->name, close, close_ret);
2006 else 2042 else
2007 /* wait for option-2 conn teardown */ 2043 /* wait for option-2 conn teardown */
@@ -2015,7 +2051,7 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
2015destroy_conn: 2051destroy_conn:
2016 bnx2i_ep_active_list_del(hba, bnx2i_ep); 2052 bnx2i_ep_active_list_del(hba, bnx2i_ep);
2017 if (bnx2i_tear_down_conn(hba, bnx2i_ep)) 2053 if (bnx2i_tear_down_conn(hba, bnx2i_ep))
2018 ret = -EINVAL; 2054 return -EINVAL;
2019out: 2055out:
2020 bnx2i_ep->state = EP_STATE_IDLE; 2056 bnx2i_ep->state = EP_STATE_IDLE;
2021 return ret; 2057 return ret;
@@ -2054,14 +2090,17 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
2054 2090
2055 mutex_lock(&hba->net_dev_lock); 2091 mutex_lock(&hba->net_dev_lock);
2056 2092
2057 if (bnx2i_ep->state == EP_STATE_IDLE) 2093 if (bnx2i_ep->state == EP_STATE_DISCONN_TIMEDOUT)
2058 goto return_bnx2i_ep; 2094 goto out;
2059 2095
2060 if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state)) 2096 if (bnx2i_ep->state == EP_STATE_IDLE)
2061 goto free_resc; 2097 goto free_resc;
2062 2098
2063 if (bnx2i_ep->hba_age != hba->age) 2099 if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state) ||
2100 (bnx2i_ep->hba_age != hba->age)) {
2101 bnx2i_ep_active_list_del(hba, bnx2i_ep);
2064 goto free_resc; 2102 goto free_resc;
2103 }
2065 2104
2066 /* Do all chip cleanup here */ 2105 /* Do all chip cleanup here */
2067 if (bnx2i_hw_ep_disconnect(bnx2i_ep)) { 2106 if (bnx2i_hw_ep_disconnect(bnx2i_ep)) {
@@ -2070,14 +2109,13 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
2070 } 2109 }
2071free_resc: 2110free_resc:
2072 bnx2i_free_qp_resc(hba, bnx2i_ep); 2111 bnx2i_free_qp_resc(hba, bnx2i_ep);
2073return_bnx2i_ep: 2112
2074 if (bnx2i_conn) 2113 if (bnx2i_conn)
2075 bnx2i_conn->ep = NULL; 2114 bnx2i_conn->ep = NULL;
2076 2115
2077 bnx2i_free_ep(ep); 2116 bnx2i_free_ep(ep);
2117out:
2078 mutex_unlock(&hba->net_dev_lock); 2118 mutex_unlock(&hba->net_dev_lock);
2079 if (!hba->ofld_conns_active)
2080 bnx2i_unreg_dev_all();
2081 2119
2082 wake_up_interruptible(&hba->eh_wait); 2120 wake_up_interruptible(&hba->eh_wait);
2083} 2121}
diff --git a/drivers/scsi/bnx2i/bnx2i_sysfs.c b/drivers/scsi/bnx2i/bnx2i_sysfs.c
index 96426b751eb2..9174196d9033 100644
--- a/drivers/scsi/bnx2i/bnx2i_sysfs.c
+++ b/drivers/scsi/bnx2i/bnx2i_sysfs.c
@@ -1,12 +1,13 @@
1/* bnx2i_sysfs.c: Broadcom NetXtreme II iSCSI driver. 1/* bnx2i_sysfs.c: Broadcom NetXtreme II iSCSI driver.
2 * 2 *
3 * Copyright (c) 2004 - 2009 Broadcom Corporation 3 * Copyright (c) 2004 - 2010 Broadcom Corporation
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation. 7 * the Free Software Foundation.
8 * 8 *
9 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com) 9 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
10 * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
10 */ 11 */
11 12
12#include "bnx2i.h" 13#include "bnx2i.h"