Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2eefb20d authored by Eddie Wai's avatar Eddie Wai Committed by James Bottomley
Browse files

[SCSI] bnx2i: Fixed the TCP graceful termination initiation



In compliance to RFC793, a TCP graceful termination will be used
instead of an abortive termination for the case where the remote
has initiated the close of the connection.
Additionally, a TCP abortive termination will be used to close the
connection when a logout response is not received in time after a
logout request has been initiated.

Signed-off-by: default avatarEddie Wai <eddie.wai@broadcom.com>
Reviewed-by: default avatarMichael Chan <mchan@broadcom.com>
Reviewed-by: default avatarBenjamin Li <benli@broadcom.com>
Acked-by: default avatarAnil Veerabhadrappa <anilgv@broadcom.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent e37d2c47
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -639,6 +639,8 @@ enum {
	EP_STATE_CLEANUP_CMPL           = 0x800,
	EP_STATE_TCP_FIN_RCVD           = 0x1000,
	EP_STATE_TCP_RST_RCVD           = 0x2000,
	EP_STATE_LOGOUT_SENT            = 0x4000,
	EP_STATE_LOGOUT_RESP_RCVD       = 0x8000,
	EP_STATE_PG_OFLD_FAILED         = 0x1000000,
	EP_STATE_ULP_UPDATE_FAILED      = 0x2000000,
	EP_STATE_CLEANUP_FAILED         = 0x4000000,
+4 −0
Original line number Diff line number Diff line
@@ -562,6 +562,8 @@ int bnx2i_send_iscsi_logout(struct bnx2i_conn *bnx2i_conn,
	logout_wqe->num_bds = 1;
	logout_wqe->cq_index = 0; /* CQ# used for completion, 5771x only */

	bnx2i_conn->ep->state = EP_STATE_LOGOUT_SENT;

	bnx2i_ring_dbell_update_sq_params(bnx2i_conn, 1);
	return 0;
}
@@ -1482,6 +1484,8 @@ static int bnx2i_process_logout_resp(struct iscsi_session *session,
	resp_hdr->t2retain = cpu_to_be32(logout->time_to_retain);

	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);

	bnx2i_conn->ep->state = EP_STATE_LOGOUT_RESP_RCVD;
done:
	spin_unlock(&session->lock);
	return 0;
+34 −19
Original line number Diff line number Diff line
@@ -1890,6 +1890,8 @@ static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep)
	case EP_STATE_ULP_UPDATE_START:
	case EP_STATE_ULP_UPDATE_COMPL:
	case EP_STATE_TCP_FIN_RCVD:
	case EP_STATE_LOGOUT_SENT:
	case EP_STATE_LOGOUT_RESP_RCVD:
	case EP_STATE_ULP_UPDATE_FAILED:
		ret = 1;
		break;
@@ -1923,6 +1925,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
	struct iscsi_session *session = NULL;
	struct iscsi_conn *conn = NULL;
	int ret = 0;
	int close = 0;
	int close_ret = 0;

	if (!hba)
		return 0;
@@ -1939,32 +1943,43 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
		session = conn->session;
	}

	bnx2i_ep->state = EP_STATE_DISCONN_START;

	init_timer(&bnx2i_ep->ofld_timer);
	bnx2i_ep->ofld_timer.expires = hba->conn_teardown_tmo + jiffies;
	bnx2i_ep->ofld_timer.function = bnx2i_ep_ofld_timer;
	bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep;
	add_timer(&bnx2i_ep->ofld_timer);

	if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
		int close = 0;
		int close_ret = 0;
	if (!test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic))
		goto out;

	if (session) {
		spin_lock_bh(&session->lock);
			if (session->state == ISCSI_STATE_LOGGING_OUT)
		if (bnx2i_ep->state != EP_STATE_TCP_FIN_RCVD) {
			if (session->state == ISCSI_STATE_LOGGING_OUT) {
				if (bnx2i_ep->state == EP_STATE_LOGOUT_SENT) {
					/* Logout sent, but no resp */
					printk(KERN_ALERT "bnx2i - WARNING "
						"logout response was not "
						"received!\n");
				} else if (bnx2i_ep->state ==
					   EP_STATE_LOGOUT_RESP_RCVD)
					close = 1;
			}
		} else
			close = 1;

		spin_unlock_bh(&session->lock);
	}

	bnx2i_ep->state = EP_STATE_DISCONN_START;

	if (close)
		close_ret = cnic->cm_close(bnx2i_ep->cm_sk);
	else
		close_ret = cnic->cm_abort(bnx2i_ep->cm_sk);

	if (close_ret)
		bnx2i_ep->state = EP_STATE_DISCONN_COMPL;
	} else
		goto out;

	/* wait for option-2 conn teardown */
	wait_event_interruptible(bnx2i_ep->ofld_wait,