[PATCH 2/2] RFC: The be2iscsi driver support for bsg

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



  This patch contains the necessary changes to support
the bsg interface

Signed-off-by: Jayamohan Kallickal <jayamohank@xxxxxxxxxxxxxxxxx>
---
 drivers/scsi/be2iscsi/be_cmds.h  |  137 ++++++++++++++++++++---
 drivers/scsi/be2iscsi/be_iscsi.c |    3 +-
 drivers/scsi/be2iscsi/be_main.c  |   99 ++++++++++++++--
 drivers/scsi/be2iscsi/be_main.h  |    6 +-
 drivers/scsi/be2iscsi/be_mgmt.c  |  230 +++++++++++++++++++++++++++++++++++++-
 drivers/scsi/be2iscsi/be_mgmt.h  |  107 ++++++++++++++++++
 include/scsi/scsi_bsg_iscsi.h    |    1 +
 7 files changed, 547 insertions(+), 36 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 49fcc78..d5c14cf 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -18,6 +18,7 @@
 #ifndef BEISCSI_CMDS_H
 #define BEISCSI_CMDS_H
 
+#include <scsi/scsi_bsg_iscsi.h>
 /**
  * The driver sends configuration and managements command requests to the
  * firmware in the BE. These requests are communicated to the processor
@@ -162,6 +163,13 @@ struct be_mcc_mailbox {
 #define OPCODE_COMMON_ISCSI_CFG_POST_SGL_PAGES		2
 #define OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES        3
 #define OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG		7
+#define OPCODE_COMMON_ISCSI_NTWK_SET_VLAN		14
+#define OPCODE_COMMON_ISCSI_NTWK_CONFIGURE_STATELESS_IP_ADDR	17
+#define OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR		21
+#define OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY	22
+#define OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY 23
+#define OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID		24
+#define OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO		25
 #define OPCODE_COMMON_ISCSI_SET_FRAGNUM_BITS_FOR_SGL_CRA 61
 #define OPCODE_COMMON_ISCSI_DEFQ_CREATE                 64
 #define OPCODE_COMMON_ISCSI_DEFQ_DESTROY 		65
@@ -237,6 +245,86 @@ struct be_cmd_resp_eq_create {
 	u16 rsvd0;		/* sword */
 } __packed;
 
+struct mgmt_chap_format {
+	u32 flags;
+	u8  intr_chap_name[256];
+	u8  intr_secret[16];
+	u8  target_chap_name[256];
+	u8  target_secret[16];
+	u16 intr_chap_name_length;
+	u16 intr_secret_length;
+	u16 target_chap_name_length;
+	u16 target_secret_length;
+} __packed;
+
+struct mgmt_auth_method_format {
+	u8	auth_method_type;
+	u8	padding[3];
+	struct	mgmt_chap_format chap;
+} __packed;
+
+struct mgmt_conn_login_options {
+	u8 flags;
+	u8 header_digest;
+	u8 data_digest;
+	u8 rsvd0;
+	u32 max_recv_datasegment_len_ini;
+	u32 max_recv_datasegment_len_tgt;
+	u32 tcp_mss;
+	u32 tcp_window_size;
+	struct	mgmt_auth_method_format auth_data;
+} __packed;
+
+struct	mgmt_conn_info {
+	u32	connection_handle;
+	u32	connection_status;
+	u16	src_port;
+	u16	dest_port;
+	u16	dest_port_redirected;
+	u16	cid;
+	u32	estimated_throughput;
+	struct	ip_address_format	src_ipaddr;
+	struct	ip_address_format	dest_ipaddr;
+	struct	ip_address_format	dest_ipaddr_redirected;
+	struct	mgmt_conn_login_options	negotiated_login_options;
+} __packed;
+
+struct mgmt_session_login_options {
+	u8	flags;
+	u8	error_recovery_level;
+	u16	rsvd0;
+	u32	first_burst_length;
+	u32	max_burst_length;
+	u16	max_connections;
+	u16	max_outstanding_r2t;
+	u16	default_time2wait;
+	u16	default_time2retain;
+} __packed;
+
+struct mgmt_session_info {
+	u32	session_handle;
+	u32	status;
+	u8	isid[6];
+	u16	tsih;
+	u32	session_flags;
+	u16	conn_count;
+	u16	pad;
+	u8	target_name[224];
+	u8	initiator_iscsiname[224];
+	struct	mgmt_session_login_options	negotiated_login_options;
+	struct	mgmt_conn_info	conn_list[1];
+} __packed;
+
+struct  be_cmd_req_geta_session {
+	struct be_cmd_resp_hdr resp_hdr;
+	u32 session_handle;
+} __packed;
+
+struct  be_cmd_resp_geta_session {
+	struct be_cmd_resp_hdr resp_hdr;
+	struct mgmt_session_info session_info;
+} __packed;
+
 struct mac_addr {
 	u16 size_of_struct;
 	u8 addr[ETH_ALEN];
@@ -254,6 +342,16 @@ struct be_cmd_resp_mac_query {
 	struct mac_addr mac;
 };
 
+struct be_cmd_req_get_boot_target {
+	struct be_cmd_req_hdr hdr;
+} __packed;
+
+struct be_cmd_resp_get_boot_target {
+	struct be_cmd_resp_hdr hdr;
+	u32  boot_session_count;
+	u32  boot_session_handle;
+};
+
 /******************** Create CQ ***************************/
 /**
  * Pseudo amap definition in which each bit of the actual structure is defined
@@ -601,14 +699,6 @@ struct be_eq_delay_params_in {
 	struct eq_delay delay[8];
 } __packed;
 
-struct ip_address_format {
-	u16 size_of_structure;
-	u8 reserved;
-	u8 ip_type;
-	u8 ip_address[16];
-	u32 rsvd0;
-} __packed;
-
 struct tcp_connect_and_offload_in {
 	struct be_cmd_req_hdr hdr;
 	struct ip_address_format ip_address;
@@ -688,18 +778,31 @@ struct be_fw_cfg {
 	u32 function_caps;
 } __packed;
 
-#define CMD_ISCSI_COMMAND_INVALIDATE  1
-#define ISCSI_OPCODE_SCSI_DATA_OUT      5
+struct be_all_if_id {
+	struct be_cmd_req_hdr hdr;
+	u32 if_count;
+	u32 if_hndl_list[1];
+} __packed;
+
+
+#define ISCSI_OPCODE_SCSI_DATA_OUT		5
 #define OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD 70
-#define OPCODE_ISCSI_INI_DRIVER_OFFLOAD_SESSION 41
-#define OPCODE_COMMON_MODIFY_EQ_DELAY	41
-#define OPCODE_COMMON_ISCSI_CLEANUP	59
-#define	OPCODE_COMMON_TCP_UPLOAD	56
+#define OPCODE_COMMON_MODIFY_EQ_DELAY		41
+#define OPCODE_COMMON_ISCSI_CLEANUP		59
+#define	OPCODE_COMMON_TCP_UPLOAD		56
 #define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1
-/* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */
-#define CMD_ISCSI_CONNECTION_INVALIDATE 0x8001
-#define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 0x8002
+#define OPCODE_ISCSI_INI_CFG_GET_HBA_NAME	6
+#define OPCODE_ISCSI_INI_CFG_SET_HBA_NAME	7
+#define OPCODE_ISCSI_INI_SESSION_GET_A_SESSION  14
+#define OPCODE_ISCSI_INI_DRIVER_OFFLOAD_SESSION 41
 #define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42
+#define OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET	52
+
+/* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */
+#define CMD_ISCSI_COMMAND_INVALIDATE		1
+#define CMD_ISCSI_CONNECTION_INVALIDATE		0x8001
+#define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST	0x8002
+
 
 #define INI_WR_CMD			1	/* Initiator write command */
 #define INI_TMF_CMD			2	/* Initiator TMF command */
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index c3928cb..eae98de 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -696,8 +696,7 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
 	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop  ep_cid = %d\n",
 			     beiscsi_ep->ep_cid);
 	tag = mgmt_invalidate_connection(phba, beiscsi_ep,
-					    beiscsi_ep->ep_cid, 1,
-					    savecfg_flag);
+					 beiscsi_ep->ep_cid, 0, savecfg_flag);
 	if (!tag) {
 		SE_DEBUG(DBG_LVL_1,
 			 "mgmt_invalidate_connection Failed for cid=%d \n",
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index fcfb29e..82ec2cc 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -28,6 +28,7 @@
 
 #include <scsi/libiscsi.h>
 #include <scsi/scsi_transport_iscsi.h>
+#include <scsi/scsi_bsg_iscsi.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -73,6 +74,7 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
 	cls_session = starget_to_session(scsi_target(sc->device));
 	session = cls_session->dd_data;
 
+
 	spin_lock_bh(&session->lock);
 	if (!aborted_task || !aborted_task->sc) {
 		/* we raced */
@@ -229,6 +231,7 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
 	phba->shost = shost;
 	phba->pcidev = pci_dev_get(pcidev);
 	pci_set_drvdata(pcidev, phba);
+	phba->interface_handle = 0xFFFFFFFF;
 
 	if (iscsi_host_add(shost, &phba->pcidev->dev))
 		goto free_devices;
@@ -1074,7 +1077,6 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
 			be_complete_logout(beiscsi_conn, task, psol);
 		else
 			be_complete_tmf(beiscsi_conn, task, psol);
-
 		break;
 
 	case HWH_TYPE_LOGIN:
@@ -1763,7 +1765,7 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
 	      unsigned int num_sg, struct beiscsi_io_task *io_task)
 {
 	struct iscsi_sge *psgl;
-	unsigned short sg_len, index;
+	unsigned int sg_len, index;
 	unsigned int sge_len = 0;
 	unsigned long long addr;
 	struct scatterlist *l_sg;
@@ -3201,7 +3203,9 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
 				hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
 			}
 		}
-	}
+	} else
+		shost_printk(KERN_WARNING, phba->shost,
+			     "In hwi_enable_intr, Not Enabled \n");
 	return true;
 }
 
@@ -3427,21 +3431,23 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
 		return -ENOMEM;
 	io_task->bhs_pa.u.a64.address = paddr;
 	io_task->libiscsi_itt = (itt_t)task->itt;
-	io_task->pwrb_handle = alloc_wrb_handle(phba,
-						beiscsi_conn->beiscsi_conn_cid -
-						phba->fw_config.iscsi_cid_start
-						);
 	io_task->conn = beiscsi_conn;
 
 	task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr;
 	task->hdr_max = sizeof(struct be_cmd_bhs);
-
+	io_task->psgl_handle = NULL;
+	io_task->psgl_handle = NULL;
 	if (task->sc) {
 		spin_lock(&phba->io_sgl_lock);
 		io_task->psgl_handle = alloc_io_sgl_handle(phba);
 		spin_unlock(&phba->io_sgl_lock);
 		if (!io_task->psgl_handle)
 			goto free_hndls;
+		io_task->pwrb_handle = alloc_wrb_handle(phba,
+					beiscsi_conn->beiscsi_conn_cid -
+					phba->fw_config.iscsi_cid_start);
+		if (!io_task->pwrb_handle)
+			goto free_io_hndls;
 	} else {
 		io_task->scsi_cmnd = NULL;
 		if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) {
@@ -3456,9 +3462,19 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
 				beiscsi_conn->login_in_progress = 1;
 				beiscsi_conn->plogin_sgl_handle =
 							io_task->psgl_handle;
+				io_task->pwrb_handle =
+					alloc_wrb_handle(phba,
+					beiscsi_conn->beiscsi_conn_cid -
+					phba->fw_config.iscsi_cid_start);
+				if (!io_task->pwrb_handle)
+					goto free_io_hndls;
+				beiscsi_conn->plogin_wrb_handle =
+							io_task->pwrb_handle;
 			} else {
 				io_task->psgl_handle =
 						beiscsi_conn->plogin_sgl_handle;
+				io_task->pwrb_handle =
+						beiscsi_conn->plogin_wrb_handle;
 			}
 		} else {
 			spin_lock(&phba->mgmt_sgl_lock);
@@ -3466,6 +3482,12 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
 			spin_unlock(&phba->mgmt_sgl_lock);
 			if (!io_task->psgl_handle)
 				goto free_hndls;
+			io_task->pwrb_handle =
+					alloc_wrb_handle(phba,
+					beiscsi_conn->beiscsi_conn_cid -
+					phba->fw_config.iscsi_cid_start);
+			if (!io_task->pwrb_handle)
+				goto free_mgmt_hndls;
 		}
 	}
 	itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle->
@@ -3475,13 +3497,22 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
 
 	io_task->cmd_bhs->iscsi_hdr.itt = itt;
 	return 0;
-
+free_io_hndls:
+	spin_lock(&phba->io_sgl_lock);
+	free_io_sgl_handle(phba, io_task->psgl_handle);
+	spin_unlock(&phba->io_sgl_lock);
+	goto free_hndls;
+free_mgmt_hndls:
+	spin_lock(&phba->mgmt_sgl_lock);
+	free_mgmt_sgl_handle(phba, io_task->psgl_handle);
+	spin_unlock(&phba->mgmt_sgl_lock);
 free_hndls:
 	phwi_ctrlr = phba->phwi_ctrlr;
 	pwrb_context = &phwi_ctrlr->wrb_context[
 			beiscsi_conn->beiscsi_conn_cid -
 			phba->fw_config.iscsi_cid_start];
-	free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
+	if (io_task->pwrb_handle)
+		free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
 	io_task->pwrb_handle = NULL;
 	pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
 		      io_task->bhs_pa.u.a64.address);
@@ -3688,8 +3719,6 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
 		SE_DEBUG(DBG_LVL_1, " scsi_dma_map Failed\n")
 		return num_sg;
 	}
-	SE_DEBUG(DBG_LVL_4, "xferlen=0x%08x scmd=%p num_sg=%d sernum=%lu\n",
-		  (scsi_bufflen(sc)), sc, num_sg, sc->serial_number);
 	xferlen = scsi_bufflen(sc);
 	sg = scsi_sglist(sc);
 	if (sc->sc_data_direction == DMA_TO_DEVICE) {
@@ -3701,6 +3730,50 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
 	return beiscsi_iotask(task, sg, num_sg, xferlen, writedir);
 }
 
+/**
+* beiscsi_bsg_request - handle bsg request from ISCSI transport
+ * @job: iscsi_bsg_job to handle
+ */
+static int beiscsi_bsg_request(struct iscsi_bsg_job *job)
+{
+	uint32_t msgcode;
+	int rc = -EINVAL;
+	unsigned int tag;
+	unsigned short status, extd_status;
+	struct beiscsi_hba *phba;
+
+	msgcode = job->request->msgcode;
+	phba = iscsi_host_priv(job->shost);
+	switch (msgcode) {
+	case ISCSI_BSG_HST_VENDOR:
+		shost_printk(KERN_ERR, phba->shost,
+			"No Vendor Specific Commands Supported \n");
+		break;
+	case ISCSI_BSG_HST_NET_CONFIG:
+		tag = mgmt_netcfg_fw_cmd(&phba->ctrl, phba, job);
+		if (!tag) {
+			SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed \n");
+			return -EAGAIN;
+		} else
+			wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+						 phba->ctrl.mcc_numtag[tag]);
+
+		extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+		status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+		free_mcc_tag(&phba->ctrl, tag);
+		if (status || extd_status) {
+			SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
+					    " status = %d extd_status = %d \n",
+					    status, extd_status);
+			return -EIO;
+		}
+
+	default:
+		break;
+	}
+	return rc;
+}
+
 static void beiscsi_remove(struct pci_dev *pcidev)
 {
 	struct beiscsi_hba *phba = NULL;
@@ -3736,6 +3809,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
 
 	beiscsi_clean_port(phba);
 	beiscsi_free_mem(phba);
+
 	beiscsi_unmap_pci_function(phba);
 	pci_free_consistent(phba->pcidev,
 			    phba->ctrl.mbox_mem_alloced.size,
@@ -3965,6 +4039,7 @@ struct iscsi_transport beiscsi_iscsi_transport = {
 	.ep_poll = beiscsi_ep_poll,
 	.ep_disconnect = beiscsi_ep_disconnect,
 	.session_recovery_timedout = iscsi_session_recovery_timedout,
+	.bsg_request = beiscsi_bsg_request,
 };
 
 static struct pci_driver beiscsi_pci_driver = {
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 87ec212..18a02a7 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -62,7 +62,7 @@
 #define BEISCSI_SGLIST_ELEMENTS	30
 
 #define BEISCSI_CMD_PER_LUN	128	/* scsi_host->cmd_per_lun */
-#define BEISCSI_MAX_SECTORS	256	/* scsi_host->max_sectors */
+#define BEISCSI_MAX_SECTORS	2048	/* scsi_host->max_sectors */
 
 #define BEISCSI_MAX_CMD_LEN	16	/* scsi_host->max_cmd_len */
 #define BEISCSI_NUM_MAX_LUN	256	/* scsi_host->max_lun */
@@ -77,7 +77,7 @@
 #define MAX_CMD_SZ			65536
 #define IIOC_SCSI_DATA                  0x05	/* Write Operation */
 
-#define DBG_LVL				0x00000001
+#define DBG_LVL				0x000000FF
 #define DBG_LVL_1			0x00000001
 #define DBG_LVL_2			0x00000002
 #define DBG_LVL_3			0x00000004
@@ -334,6 +334,7 @@ struct beiscsi_hba {
 	struct work_struct work_cqs;	/* The work being queued */
 	struct be_ctrl_info ctrl;
 	unsigned int generation;
+	unsigned int interface_handle;
 	struct invalidate_command_table inv_tbl[128];
 
 };
@@ -353,6 +354,7 @@ struct beiscsi_conn {
 	struct beiscsi_endpoint *ep;
 	unsigned short login_in_progress;
 	struct sgl_handle *plogin_sgl_handle;
+	struct wrb_handle *plogin_wrb_handle;
 	struct beiscsi_session *beiscsi_sess;
 	struct iscsi_task *task;
 };
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 72617b6..15f8203 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -20,6 +20,8 @@
 
 #include "be_mgmt.h"
 #include "be_iscsi.h"
+#include <scsi/scsi_transport_iscsi.h>
+#include <scsi/scsi_bsg_iscsi.h>
 
 unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
 				struct beiscsi_hba *phba)
@@ -112,11 +114,210 @@ unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
 	spin_unlock(&ctrl->mbox_lock);
 	if (nonemb_cmd.va)
 		pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
-				    nonemb_cmd.va, nonemb_cmd.dma);
+			    nonemb_cmd.va, nonemb_cmd.dma);
+
+	return status;
+}
+
+unsigned char mgmt_get_all_if_id(struct be_ctrl_info *ctrl,
+				struct beiscsi_hba *phba)
+{
+	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_all_if_id *req = embedded_payload(wrb);
+	struct be_all_if_id *pbe_allid = req;
+	int status = 0;
+
+	spin_lock(&ctrl->mbox_lock);
+	memset(wrb, 0, sizeof(*wrb));
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
+			   OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
+			   sizeof(*req));
+	status = be_mbox_notify(ctrl);
+	if (!status) {
+
+		phba->interface_handle = pbe_allid->if_hndl_list[0];
+	} else {
+		shost_printk(KERN_WARNING, phba->shost,
+			     "Failed in mgmt_get_all_if_id\n");
+	}
+	spin_unlock(&ctrl->mbox_lock);
 	return status;
 }
 
+int  mgmt_netcfg_fw_cmd(struct be_ctrl_info *ctrl,
+		 struct beiscsi_hba *phba,
+		 struct iscsi_bsg_job *job)
+{
+	struct be_dma_mem nonemb_cmd;
+	unsigned char *pdata;
+	int num, i, status = -EIO;
+	struct scatterlist *sge = NULL;
+	struct be_cmd_resp_hdr *resp;
+	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
+	struct be_cmd_req_hdr *phdr;
+	struct be_sge *mcc_sge = nonembedded_sgl(wrb);
+	struct iscsi_bsg_common_format *bsgdata;
+	struct be_modify_ip_addr *setip;
+	struct be_modify_default_gateway *setdefgw;
+	struct be_set_vlan *setvlan;
+	struct be_set_get_hba_name *sethbaname;
+	struct be_stateless_ip_addr *dhcp;
+	struct be_get_default_gateway_request *getdefgw;
+	struct be_get_if_info_request *getifinfo;
+	unsigned int tag = 0;
+
+	if (phba->interface_handle == 0xFFFFFFFF) {
+		if (mgmt_get_all_if_id(ctrl, phba)) {
+			shost_printk(KERN_WARNING, phba->shost,
+				"Did not get Interface ID \n");
+			return -EAGAIN;
+		}
+	}
+
+
+	nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
+					     job->request_payload.size,
+					     &nonemb_cmd.dma);
+	if (nonemb_cmd.va == NULL) {
+		SE_DEBUG(DBG_LVL_1,
+			 "Failed to allocate memory for mgmt_netcfg_fw_cmd\n");
+		return -EIO;
+	}
+
+	phdr = nonemb_cmd.va;
+	nonemb_cmd.size = job->request_payload.size;
+	memset(nonemb_cmd.va, 0, nonemb_cmd.size);
+	resp = nonemb_cmd.va;
+
+	bsgdata = (struct iscsi_bsg_common_format *)job->request_payload.va;
+	switch (job->request->rqst_data.h_netconfig.set_op) {
+	case ISCSI_SET_IP_ADDR:
+		be_cmd_hdr_prepare(phdr, CMD_SUBSYSTEM_ISCSI,
+			OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
+			sizeof(struct be_modify_ip_addr));
+		setip = nonemb_cmd.va;
+		setip->ip_params.record_entry_count = bsgdata->ip_params.
+						      record_entry_count;
+		for (i = 0; i < setip->ip_params.record_entry_count; i++) {
+			memcpy(&setip->ip_params.ip_record[i],
+				&bsgdata->ip_params.ip_record[i],
+				sizeof(struct iscsi_ip_addr_record));
+		}
+		break;
+
+	case ISCSI_SET_DEFAULT_GATEWAY:
+		be_cmd_hdr_prepare(phdr, CMD_SUBSYSTEM_ISCSI,
+			OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
+			sizeof(struct be_modify_default_gateway));
+		setdefgw = nonemb_cmd.va;
+		setdefgw->action =  bsgdata->action;
+		memcpy(&setdefgw->gateway, &bsgdata->gateway,
+			sizeof(struct ip_address_format));
+
+		break;
+
+	case ISCSI_SET_VLAN:
+		be_cmd_hdr_prepare(phdr, CMD_SUBSYSTEM_ISCSI,
+			OPCODE_COMMON_ISCSI_NTWK_SET_VLAN,
+			sizeof(struct be_set_vlan));
+		setvlan = nonemb_cmd.va;
+		setvlan->interface_hndl = bsgdata->interface_hndl;
+		setvlan->vlan_priority = bsgdata->vlan_priority;
+
+		break;
+
+	case ISCSI_SET_HBA_NAME:
+		be_cmd_hdr_prepare(phdr, CMD_SUBSYSTEM_ISCSI_INI,
+			OPCODE_ISCSI_INI_CFG_SET_HBA_NAME,
+			sizeof(struct be_set_get_hba_name));
+		sethbaname = nonemb_cmd.va;
+		sethbaname->flags = bsgdata->flags;
+		memcpy(&sethbaname->iscsiname, &bsgdata->iscsiname, 224);
+		memcpy(&sethbaname->iscsialias, &bsgdata->iscsialias, 32);
+		break;
+
+	case ISCSI_CONFIGURE_STATELESS_IP:
+		be_cmd_hdr_prepare(phdr, CMD_SUBSYSTEM_ISCSI,
+			OPCODE_COMMON_ISCSI_NTWK_CONFIGURE_STATELESS_IP_ADDR,
+			sizeof(struct be_stateless_ip_addr));
+		dhcp = nonemb_cmd.va;
+		dhcp->interface_hndl = bsgdata->interface_hndl;
+		dhcp->ip_type = bsgdata->ip_type;
+		dhcp->flags = bsgdata->flags;
+		dhcp->retry_count = bsgdata->retry_count;
+		break;
+
+	case ISCSI_GET_HBA_NAME:
+		be_cmd_hdr_prepare(phdr, CMD_SUBSYSTEM_ISCSI_INI,
+			OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
+			sizeof(struct be_set_get_hba_name));
+		sethbaname = nonemb_cmd.va;
+		sethbaname->flags = bsgdata->flags;
+		break;
+	case ISCSI_GET_IF_INFO:
+		be_cmd_hdr_prepare(phdr, CMD_SUBSYSTEM_ISCSI,
+			OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
+			sizeof(struct be_get_if_info_request));
+		getifinfo = nonemb_cmd.va;
+		getifinfo->interface_hndl = phba->interface_handle;
+		getifinfo->ip_type = bsgdata->ip_type;
+		break;
+	case ISCSI_GET_DEFAULT_GATEWAY:
+		be_cmd_hdr_prepare(phdr, CMD_SUBSYSTEM_ISCSI,
+			OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
+			sizeof(struct be_get_default_gateway_request));
+		getdefgw = nonemb_cmd.va;
+		getdefgw->ip_type = bsgdata->ip_type;
+		break;
+	case ISCSI_GET_MAC_ADDRESS:
+	be_cmd_hdr_prepare(phdr, CMD_SUBSYSTEM_ISCSI,
+			   OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
+			   sizeof(struct be_cmd_req_get_mac_addr));
+
+	default:
+		pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
+				    nonemb_cmd.va, nonemb_cmd.dma);
+		return -EIO;
+	}
+
+	spin_lock(&ctrl->mbox_lock);
+	tag = alloc_mcc_tag(phba);
+	if (!tag) {
+		spin_unlock(&ctrl->mbox_lock);
+		return tag;
+	}
+
+	memset(wrb, 0, sizeof(*wrb));
+	be_wrb_hdr_prepare(wrb, nonemb_cmd.size, false,
+			   job->request_payload.sg_cnt);
+	mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
+	mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
+	mcc_sge->len = cpu_to_le32(nonemb_cmd.size);
+	wrb->tag0 |= tag;
+
+	be_mcc_notify(phba);
+
+	pdata = nonemb_cmd.va;
+	for_each_sg(job->reply_payload.sg_list, sge,
+		    job->reply_payload.sg_cnt, num) {
+		if (sge->length) {
+			memcpy(sg_virt(sge), pdata, sge->length);
+			pdata += sge->length;
+		}
+	}
+
+	pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
+				    nonemb_cmd.va, nonemb_cmd.dma);
+
+	spin_unlock(&ctrl->mbox_lock);
+	job->reply->reply_payload_rcv_len = resp->response_length;
+	job->reply->result = status;
+	job->job_done(job);
+	return tag;
+ }
 
 unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
 {
@@ -169,6 +370,7 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
 		SE_DEBUG(DBG_LVL_1,
 			 "Failed to allocate memory for"
 			 "mgmt_invalidate_icds \n");
+		spin_unlock(&ctrl->mbox_lock);
 		return -1;
 	}
 	nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
@@ -277,6 +479,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
 	struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
 	struct be_ctrl_info *ctrl = &phba->ctrl;
 	struct be_mcc_wrb *wrb;
+	struct be_dma_mem nonemb_cmd;
 	struct tcp_connect_and_offload_in *req;
 	unsigned short def_hdr_id;
 	unsigned short def_data_id;
@@ -285,6 +488,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
 	unsigned int tag = 0;
 	unsigned int i;
 	unsigned short cid = beiscsi_ep->ep_cid;
+	struct be_sge *sge;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -293,17 +497,34 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
 
 	ptemplate_address = &template_address;
 	ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
+
 	spin_lock(&ctrl->mbox_lock);
 	tag = alloc_mcc_tag(phba);
 	if (!tag) {
 		spin_unlock(&ctrl->mbox_lock);
 		return tag;
 	}
+
+	nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
+				sizeof(struct tcp_connect_and_offload_in),
+				&nonemb_cmd.dma);
+	if (nonemb_cmd.va == NULL) {
+		SE_DEBUG(DBG_LVL_1,
+			 "Failed to allocate memory for mgmt_open_connection"
+			 "\n");
+		return -1;
+	}
+	nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in);
+
 	wrb = wrb_from_mccq(phba);
-	req = embedded_payload(wrb);
+	memset(wrb, 0, sizeof(*wrb));
+	sge = nonembedded_sgl(wrb);
+
+	req = nonemb_cmd.va;
+	memset(req, 0, sizeof(*req));
 	wrb->tag0 |= tag;
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
 			   OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
 			   sizeof(*req));
@@ -346,6 +567,9 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
 	req->do_offload = 1;
 	req->dataout_template_pa.lo = ptemplate_address->lo;
 	req->dataout_template_pa.hi = ptemplate_address->hi;
+	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
+	sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
+	sge->len = cpu_to_le32(nonemb_cmd.size);
 	be_mcc_notify(phba);
 	spin_unlock(&ctrl->mbox_lock);
 	return tag;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 3d316b8..ed878d1 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -25,6 +25,7 @@
 #include <linux/list.h>
 #include "be_iscsi.h"
 #include "be_main.h"
+#include <scsi/scsi_bsg_iscsi.h>
 
 /**
  * Pseudo amap definition in which each bit of the actual structure is defined
@@ -202,6 +203,106 @@ struct be_mgmt_controller_attributes_resp {
 	struct mgmt_controller_attributes params;
 } __packed;
 
+/*
+struct ip_address_subnet_format {
+	u16 sizeofstructure;
+	u8  iptype;
+	u8  ipv6_prefix_length;
+	u8  ipaddress[16];
+	u8  subnetmask[16];
+	u32 rsvd0;
+} __packed;
+
+struct iscsi_ip_addr_record {
+	u32  action;
+	u32  interface_hndl;
+	struct ip_address_subnet_format ip_address;
+	u32  status;
+} __packed;
+
+struct iscsi_ip_addr_record_params {
+	u32 record_entry_count;
+	struct iscsi_ip_addr_record ip_record[1];
+} __packed;
+*/
+struct be_modify_ip_addr {
+	struct be_cmd_req_hdr hdr;
+	struct iscsi_ip_addr_record_params ip_params;
+} __packed;
+
+struct be_modify_default_gateway {
+	struct be_cmd_req_hdr hdr;
+	u32    action;
+	struct ip_address_format gateway;
+} __packed;
+
+struct be_set_vlan {
+	struct be_cmd_req_hdr hdr;
+	u32  interface_hndl;
+	u32  vlan_priority;
+} __packed;
+
+struct be_set_get_hba_name {
+	struct be_cmd_req_hdr hdr;
+	u16 flags;
+	u16 rsvd0;
+	u8  iscsiname[224];
+	u8  iscsialias[32];
+} __packed;
+
+struct be_stateless_ip_addr {
+	struct be_cmd_req_hdr hdr;
+	u32  interface_hndl;
+	u32  ip_type;
+	u32  flags;
+	u32  retry_count;
+} __packed;
+
+struct be_get_if_info_request {
+	struct be_cmd_req_hdr hdr;
+	u32 interface_hndl;
+	u32 ip_type;
+} __packed;
+
+struct be_get_if_info_response {
+	struct be_cmd_req_hdr hdr;
+	u32    interface_hndl;
+	u32    vlan_priority;
+	u32    ip_address_count;
+	u32    dhcp_state;
+	struct ip_address_subnet_format ip_address[1];
+} __packed;
+
+struct be_get_default_gateway_request {
+	struct be_cmd_req_hdr hdr;
+	u32    ip_type;
+} __packed;
+
+struct be_get_default_gateway_response {
+	struct be_cmd_req_hdr hdr;
+	struct ip_address_format gateway;
+} __packed;
+
+struct be_bsg_common_format {
+	u8 opcode;		/* dword 0 */
+	u8 subsystem;		/* dword 0 */
+	u8 port_number;		/* dword 0 */
+	u8 domain;		/* dword 0 */
+	u32 timeout;		/* dword 1 */
+	u32 request_length;	/* dword 2 */
+	u32 rsvd0;		/* dword 3 */
+	u32    action;
+	struct ip_address_format gateway;
+	u32  interface_hndl;
+	u32  vlan_priority;
+	u32  flags;
+	u8   iscsiname[224];
+	u8   iscsialias[32];
+	u32  ip_type;
+	u32  retry_count;
+	struct iscsi_ip_addr_record_params ip_params;
+} __packed;
+
 /* configuration management */
 
 #define GET_MGMT_CONTROLLER_WS(phba)    (phba->pmgmt_ws)
@@ -246,4 +347,10 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
 					 unsigned short issue_reset,
 					 unsigned short savecfg_flag);
 
+unsigned char mgmt_get_all_if_id(struct be_ctrl_info *ctrl,
+				struct beiscsi_hba *phba);
+
+int  mgmt_netcfg_fw_cmd(struct be_ctrl_info *ctrl,
+		 struct beiscsi_hba *phba,
+		 struct iscsi_bsg_job *job);
 #endif
diff --git a/include/scsi/scsi_bsg_iscsi.h b/include/scsi/scsi_bsg_iscsi.h
index 10c91c3..2c85dd0 100644
--- a/include/scsi/scsi_bsg_iscsi.h
+++ b/include/scsi/scsi_bsg_iscsi.h
@@ -56,6 +56,7 @@
 #define ISCSI_GET_HBA_NAME		6
 #define ISCSI_GET_IF_INFO		7
 #define ISCSI_GET_DEFAULT_GATEWAY	8
+#define ISCSI_GET_MAC_ADDRESS           9
 
 /*
  * iSCSI Host Messages
-- 
1.6.4

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux