* [PATCH 09/12] be2iscsi: Add support for iscsi boot
@ 2010-06-30 0:02 Jayamohan Kallickal
2010-07-04 20:16 ` Mike Christie
0 siblings, 1 reply; 4+ messages in thread
From: Jayamohan Kallickal @ 2010-06-30 0:02 UTC (permalink / raw)
To: linux-scsi; +Cc: James.Bottomley, michaelc
This patch contains changes for adding support for iscsi_boot
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com>
---
drivers/scsi/be2iscsi/be_cmds.h | 147 ++++++++++++++--
drivers/scsi/be2iscsi/be_main.c | 353 +++++++++++++++++++++++++++++++++++++++
drivers/scsi/be2iscsi/be_main.h | 2 +
drivers/scsi/be2iscsi/be_mgmt.c | 71 ++++++++
4 files changed, 556 insertions(+), 17 deletions(-)
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 0176422..02b0ee6 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -162,6 +162,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,11 +244,109 @@ 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 ip_address_format {
+ u16 size_of_structure;
+ u8 reserved;
+ u8 ip_type;
+ u8 ip_address[16];
+ u32 rsvd0;
+} __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_req_hdr hdr;
+ u32 session_handle;
+} __packed;
+
+struct be_cmd_resp_geta_session {
+ struct be_cmd_resp_hdr hdr;
+ struct mgmt_session_info session_info;
+} __packed;
+
struct mac_addr {
u16 size_of_struct;
u8 addr[ETH_ALEN];
} __packed;
+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;
+ int boot_session_handle;
+};
+
struct be_cmd_req_mac_query {
struct be_cmd_req_hdr hdr;
u8 type;
@@ -426,6 +531,11 @@ int be_poll_mcc(struct be_ctrl_info *ctrl);
unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba);
unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba);
+unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba);
+unsigned int beiscsi_geta_session_info(struct beiscsi_hba *phba,
+ u32 boot_session_handle,
+ struct be_dma_mem *nonemb_cmd);
+
void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
/*ISCSI Functuions */
int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
@@ -601,14 +711,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 +790,29 @@ 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_MODIFY_EQ_DELAY 41
+#define OPCODE_COMMON_ISCSI_CLEANUP 59
+#define OPCODE_COMMON_TCP_UPLOAD 56
#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_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_main.c b/drivers/scsi/be2iscsi/be_main.c
index b17897b..01977a6 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -26,6 +26,7 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/semaphore.h>
+#include <linux/iscsi_boot_sysfs.h>
#include <scsi/libiscsi.h>
#include <scsi/scsi_transport_iscsi.h>
@@ -213,6 +214,258 @@ unlock:
return rc;
}
+static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf)
+{
+ struct beiscsi_hba *phba = data;
+ char *str = buf;
+ int rc;
+
+ printk(KERN_ERR " In beiscsi_show_boot_tgt_info type=%d\n", type);
+ switch (type) {
+ case ISCSI_BOOT_TGT_NAME:
+ rc = sprintf(buf, "%.*s\n",
+ (int)strlen(phba->boot_sess.target_name),
+ (char *)&phba->boot_sess.target_name);
+ break;
+ case ISCSI_BOOT_TGT_IP_ADDR:
+ if (phba->boot_sess.conn_list[0].dest_ipaddr.ip_type == 0x1)
+ rc = sprintf(buf, "%pI4\n",
+ (char *)&phba->boot_sess.conn_list[0].
+ dest_ipaddr.ip_address);
+ else
+ rc = sprintf(str, "%pI6\n",
+ (char *)&phba->boot_sess.conn_list[0].
+ dest_ipaddr.ip_address);
+ break;
+ case ISCSI_BOOT_TGT_PORT:
+ rc = sprintf(str, "%d\n", phba->boot_sess.conn_list[0].
+ dest_port);
+ break;
+
+ case ISCSI_BOOT_TGT_CHAP_NAME:
+ rc = sprintf(str, "%.*s\n",
+ phba->boot_sess.conn_list[0].
+ negotiated_login_options.auth_data.chap.
+ target_chap_name_length,
+ (char *)&phba->boot_sess.conn_list[0].
+ negotiated_login_options.auth_data.chap.
+ target_chap_name);
+ break;
+ case ISCSI_BOOT_TGT_CHAP_SECRET:
+ rc = sprintf(str, "%.*s\n",
+ phba->boot_sess.conn_list[0].
+ negotiated_login_options.auth_data.chap.
+ target_secret_length,
+ (char *)&phba->boot_sess.conn_list[0].
+ negotiated_login_options.auth_data.chap.
+ target_secret);
+
+ break;
+ case ISCSI_BOOT_TGT_REV_CHAP_NAME:
+ rc = sprintf(str, "%.*s\n",
+ phba->boot_sess.conn_list[0].
+ negotiated_login_options.auth_data.chap.
+ intr_chap_name_length,
+ (char *)&phba->boot_sess.conn_list[0].
+ negotiated_login_options.auth_data.chap.
+ intr_chap_name);
+
+ break;
+ case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
+ rc = sprintf(str, "%.*s\n",
+ phba->boot_sess.conn_list[0].
+ negotiated_login_options.auth_data.chap.
+ intr_secret_length,
+ (char *)&phba->boot_sess.conn_list[0].
+ negotiated_login_options.auth_data.chap.
+ intr_secret);
+ break;
+ case ISCSI_BOOT_TGT_FLAGS:
+ rc = sprintf(str, "2\n");
+ break;
+ case ISCSI_BOOT_TGT_NIC_ASSOC:
+ rc = sprintf(str, "0\n");
+ break;
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+ return rc;
+}
+
+static ssize_t beiscsi_show_boot_ini_info(void *data, int type, char *buf)
+{
+ struct beiscsi_hba *phba = data;
+ char *str = buf;
+ int rc;
+
+ printk(KERN_ERR " In beiscsi_show_boot_ini_info type=%d\n", type);
+ switch (type) {
+ case ISCSI_BOOT_INI_INITIATOR_NAME:
+ rc = sprintf(str, "%s\n", phba->boot_sess.initiator_iscsiname);
+ break;
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+ return rc;
+}
+
+static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf)
+{
+ struct beiscsi_hba *phba = data;
+ char *str = buf;
+ int rc;
+
+ printk(KERN_ERR " In beiscsi_show_boot_eth_info type = %d\n", type);
+ switch (type) {
+ case ISCSI_BOOT_ETH_FLAGS:
+ rc = sprintf(str, "2\n");
+ break;
+ case ISCSI_BOOT_ETH_INDEX:
+ rc = sprintf(str, "0\n");
+ break;
+ case ISCSI_BOOT_ETH_MAC:
+ {
+ struct be_cmd_resp_get_mac_addr *resp;
+ struct be_mcc_wrb *wrb;
+ unsigned int tag, wrb_num;
+ unsigned short status, extd_status;
+ struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+
+ tag = be_cmd_get_mac_addr(phba);
+ if (!tag) {
+ SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
+ return -1;
+ } else
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+
+ wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+ extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+ status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+ if (status || extd_status) {
+ SE_DEBUG(DBG_LVL_1, "Failed to get be_cmd_get_mac_addr"
+ " status = %d extd_status = %d\n",
+ status, extd_status);
+ free_mcc_tag(&phba->ctrl, tag);
+ return -1;
+ } else {
+ wrb = queue_get_wrb(mccq, wrb_num);
+ free_mcc_tag(&phba->ctrl, tag);
+ resp = embedded_payload(wrb);
+ memcpy(phba->mac_address, resp->mac_address, ETH_ALEN);
+ rc = sysfs_format_mac(buf, phba->mac_address,
+ ETH_ALEN);
+ }
+ }
+
+ break;
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+ return rc;
+}
+
+
+static mode_t beiscsi_tgt_get_attr_visibility(void *data, int type)
+{
+ int rc;
+
+ switch (type) {
+ case ISCSI_BOOT_TGT_NAME:
+ case ISCSI_BOOT_TGT_IP_ADDR:
+ case ISCSI_BOOT_TGT_PORT:
+ case ISCSI_BOOT_TGT_CHAP_NAME:
+ case ISCSI_BOOT_TGT_CHAP_SECRET:
+ case ISCSI_BOOT_TGT_REV_CHAP_NAME:
+ case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
+ case ISCSI_BOOT_TGT_NIC_ASSOC:
+ case ISCSI_BOOT_TGT_FLAGS:
+ rc = S_IRUGO;
+ break;
+ default:
+ rc = 0;
+ break;
+ }
+ return rc;
+}
+
+static mode_t beiscsi_ini_get_attr_visibility(void *data, int type)
+{
+ int rc;
+
+ switch (type) {
+ case ISCSI_BOOT_INI_INITIATOR_NAME:
+ rc = S_IRUGO;
+ break;
+ default:
+ rc = 0;
+ break;
+ }
+ return rc;
+}
+
+
+static mode_t beiscsi_eth_get_attr_visibility(void *data, int type)
+{
+ int rc;
+
+ switch (type) {
+ case ISCSI_BOOT_ETH_FLAGS:
+ case ISCSI_BOOT_ETH_MAC:
+ case ISCSI_BOOT_ETH_INDEX:
+ rc = S_IRUGO;
+ break;
+ default:
+ rc = 0;
+ break;
+ }
+ return rc;
+}
+
+static int beiscsi_setup_boot_info(struct beiscsi_hba *phba)
+{
+ struct iscsi_boot_kobj *boot_kobj;
+ char *set_name;
+
+ set_name = kasprintf(GFP_KERNEL, "iscsi_boot%u", phba->shost->host_no);
+ if (!set_name)
+ return -ENOMEM;
+
+ phba->boot_kset = iscsi_boot_create_kset(set_name);
+ if (!phba->boot_kset) {
+ kfree(set_name);
+ return -ENOMEM;
+ }
+
+ /* get boot info using mgmt cmd */
+ boot_kobj = iscsi_boot_create_target(phba->boot_kset, 0, phba,
+ beiscsi_show_boot_tgt_info,
+ beiscsi_tgt_get_attr_visibility);
+ if (!boot_kobj)
+ goto free_kset;
+
+ boot_kobj = iscsi_boot_create_initiator(phba->boot_kset, 0, phba,
+ beiscsi_show_boot_ini_info,
+ beiscsi_ini_get_attr_visibility);
+ if (!boot_kobj)
+ goto free_kset;
+
+ boot_kobj = iscsi_boot_create_ethernet(phba->boot_kset, 0, phba,
+ beiscsi_show_boot_eth_info,
+ beiscsi_eth_get_attr_visibility);
+ if (!boot_kobj)
+ goto free_kset;
+ return 0;
+
+free_kset:
+ kfree(set_name);
+ iscsi_boot_destroy_kset(phba->boot_kset);
+ return -ENOMEM;
+}
+
/*------------------- PCI Driver operations and data ----------------- */
static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
@@ -270,6 +523,15 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
if (iscsi_host_add(shost, &phba->pcidev->dev))
goto free_devices;
+
+ if (beiscsi_setup_boot_info(phba))
+ /*
+ * log error but continue, because we may not be using
+ * iscsi boot.
+ */
+ shost_printk(KERN_ERR, phba->shost, "Could not set up "
+ "iSCSI boot info.");
+
return phba;
free_devices:
@@ -3263,6 +3525,89 @@ static void hwi_disable_intr(struct beiscsi_hba *phba)
"In hwi_disable_intr, Already Disabled\n");
}
+static char beiscsi_get_boot_info(struct beiscsi_hba *phba)
+{
+ struct be_cmd_resp_get_boot_target *boot_resp;
+ struct be_cmd_resp_geta_session *session_resp;
+ struct be_mcc_wrb *wrb;
+ struct be_dma_mem nonemb_cmd;
+ unsigned int tag, wrb_num;
+ unsigned short status, extd_status;
+ struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+
+ tag = beiscsi_get_boot_target(phba);
+ if (!tag) {
+ SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
+ return -1;
+ } else
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+
+ wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+ extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+ status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+ if (status || extd_status) {
+ SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
+ " status = %d extd_status = %d\n",
+ status, extd_status);
+ free_mcc_tag(&phba->ctrl, tag);
+ return -1;
+ }
+ wrb = queue_get_wrb(mccq, wrb_num);
+ free_mcc_tag(&phba->ctrl, tag);
+ boot_resp = embedded_payload(wrb);
+
+ if (boot_resp->boot_session_handle >= 0) {
+
+ nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
+ sizeof(*session_resp),
+ &nonemb_cmd.dma);
+ if (nonemb_cmd.va == NULL) {
+ SE_DEBUG(DBG_LVL_1,
+ "Failed to allocate memory for"
+ "beiscsi_geta_session_info\n");
+ return -1;
+ }
+
+ memset(nonemb_cmd.va, 0, sizeof(*session_resp));
+ tag = beiscsi_geta_session_info(phba,
+ boot_resp->boot_session_handle, &nonemb_cmd);
+ if (!tag) {
+ SE_DEBUG(DBG_LVL_1, "beiscsi_geta_session_info"
+ " Failed\n");
+ pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+ nonemb_cmd.va, nonemb_cmd.dma);
+ return -1;
+ } else
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+
+ wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+ extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+ status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+ if (status || extd_status) {
+ SE_DEBUG(DBG_LVL_1, "beiscsi_geta_session_info Failed"
+ " status = %d extd_status = %d\n",
+ status, extd_status);
+ free_mcc_tag(&phba->ctrl, tag);
+ pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+ nonemb_cmd.va, nonemb_cmd.dma);
+ return -1;
+ }
+ wrb = queue_get_wrb(mccq, wrb_num);
+ free_mcc_tag(&phba->ctrl, tag);
+ session_resp = nonemb_cmd.va ;
+ memcpy(&phba->boot_sess, &session_resp->session_info,
+ sizeof(struct mgmt_session_info));
+ pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+ nonemb_cmd.va, nonemb_cmd.dma);
+ } else {
+ printk(KERN_ERR "No Boot Session for this pci_func,"
+ "session Hndl = %d\n", boot_resp->boot_session_handle);
+ }
+ return 0;
+}
+
static int beiscsi_init_port(struct beiscsi_hba *phba)
{
int ret;
@@ -3825,6 +4170,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
iscsi_host_remove(phba->shost);
pci_dev_put(phba->pcidev);
iscsi_host_free(phba->shost);
+ iscsi_boot_destroy_kset(phba->boot_kset);
}
static void beiscsi_msix_enable(struct beiscsi_hba *phba)
@@ -3985,6 +4331,13 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
"Failed to hwi_enable_intr\n");
goto free_intr;
}
+ ret = beiscsi_get_boot_info(phba);
+ if (ret < 0) {
+ shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
+ "Failed to hwi_enable_intr\n");
+ goto free_intr;
+ }
+
SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n");
return 0;
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 08996d0..978a57d 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -311,6 +311,7 @@ struct beiscsi_hba {
struct list_head hba_queue;
unsigned short *cid_array;
struct iscsi_endpoint **ep_array;
+ struct iscsi_boot_kset *boot_kset;
struct Scsi_Host *shost;
struct {
/**
@@ -341,6 +342,7 @@ struct beiscsi_hba {
struct work_struct work_cqs; /* The work being queued */
struct be_ctrl_info ctrl;
unsigned int generation;
+ struct mgmt_session_info boot_sess;
struct invalidate_command_table inv_tbl[128];
};
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index c33aa3c..ee85898 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -20,6 +20,77 @@
#include "be_mgmt.h"
#include "be_iscsi.h"
+#include <scsi/scsi_transport_iscsi.h>
+
+unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba)
+{
+ struct be_ctrl_info *ctrl = &phba->ctrl;
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_mac_addr *req;
+ unsigned int tag = 0;
+
+ SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n");
+ spin_lock(&ctrl->mbox_lock);
+ tag = alloc_mcc_tag(phba);
+ if (!tag) {
+ spin_unlock(&ctrl->mbox_lock);
+ return tag;
+ }
+
+ wrb = wrb_from_mccq(phba);
+ req = embedded_payload(wrb);
+ wrb->tag0 |= tag;
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
+ OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
+ sizeof(*req));
+
+ be_mcc_notify(phba);
+ spin_unlock(&ctrl->mbox_lock);
+ return tag;
+}
+
+unsigned int beiscsi_geta_session_info(struct beiscsi_hba *phba,
+ u32 boot_session_handle,
+ struct be_dma_mem *nonemb_cmd)
+{
+ struct be_ctrl_info *ctrl = &phba->ctrl;
+ struct be_mcc_wrb *wrb;
+ unsigned int tag = 0;
+ struct be_cmd_req_geta_session *req;
+ struct be_cmd_resp_geta_session *resp;
+ struct be_sge *sge;
+
+ SE_DEBUG(DBG_LVL_8, "In beiscsi_geta_session_info\n");
+ spin_lock(&ctrl->mbox_lock);
+ tag = alloc_mcc_tag(phba);
+ if (!tag) {
+ spin_unlock(&ctrl->mbox_lock);
+ return tag;
+ }
+
+ nonemb_cmd->size = sizeof(*resp);
+ req = nonemb_cmd->va;
+ memset(req, 0, sizeof(*req));
+ wrb = wrb_from_mccq(phba);
+ sge = nonembedded_sgl(wrb);
+ wrb->tag0 |= tag;
+
+
+ wrb->tag0 |= tag;
+ be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
+ OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
+ sizeof(*resp));
+ req->session_handle = boot_session_handle;
+ 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;
+}
unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba)
--
1.6.5.2
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH 09/12] be2iscsi: Add support for iscsi boot
2010-06-30 0:02 [PATCH 09/12] be2iscsi: Add support for iscsi boot Jayamohan Kallickal
@ 2010-07-04 20:16 ` Mike Christie
2010-07-05 20:40 ` Konrad Rzeszutek Wilk
0 siblings, 1 reply; 4+ messages in thread
From: Mike Christie @ 2010-07-04 20:16 UTC (permalink / raw)
To: Jayamohan Kalickal; +Cc: linux-scsi, James.Bottomley, Konrad Rzeszutek
ccing Konrad to give him some heads up that there is going to be another
user of the boot lib.
On 06/29/2010 07:02 PM, Jayamohan Kallickal wrote:
> +static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf)
> +{
> + struct beiscsi_hba *phba = data;
> + char *str = buf;
> + int rc;
> +
> + printk(KERN_ERR " In beiscsi_show_boot_tgt_info type=%d\n", type);
> + switch (type) {
> + case ISCSI_BOOT_TGT_NAME:
> + rc = sprintf(buf, "%.*s\n",
> + (int)strlen(phba->boot_sess.target_name),
Did you get a compile warning if you did not cast this to a int?
> + (char *)&phba->boot_sess.target_name);
> + break;
> + case ISCSI_BOOT_TGT_IP_ADDR:
> + if (phba->boot_sess.conn_list[0].dest_ipaddr.ip_type == 0x1)
> + rc = sprintf(buf, "%pI4\n",
> + (char *)&phba->boot_sess.conn_list[0].
> + dest_ipaddr.ip_address);
> + else
> + rc = sprintf(str, "%pI6\n",
> + (char *)&phba->boot_sess.conn_list[0].
> + dest_ipaddr.ip_address);
> + break;
> + case ISCSI_BOOT_TGT_PORT:
> + rc = sprintf(str, "%d\n", phba->boot_sess.conn_list[0].
> + dest_port);
> + break;
> +
> + case ISCSI_BOOT_TGT_CHAP_NAME:
> + rc = sprintf(str, "%.*s\n",
> + phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + target_chap_name_length,
> + (char *)&phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + target_chap_name);
> + break;
> + case ISCSI_BOOT_TGT_CHAP_SECRET:
> + rc = sprintf(str, "%.*s\n",
> + phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + target_secret_length,
> + (char *)&phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + target_secret);
> +
> + break;
> + case ISCSI_BOOT_TGT_REV_CHAP_NAME:
> + rc = sprintf(str, "%.*s\n",
> + phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + intr_chap_name_length,
> + (char *)&phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + intr_chap_name);
> +
> + break;
> + case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
> + rc = sprintf(str, "%.*s\n",
> + phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + intr_secret_length,
> + (char *)&phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + intr_secret);
> + break;
> + case ISCSI_BOOT_TGT_FLAGS:
> + rc = sprintf(str, "2\n");
> + break;
> + case ISCSI_BOOT_TGT_NIC_ASSOC:
> + rc = sprintf(str, "0\n");
> + break;
> + default:
> + rc = -ENOSYS;
> + break;
> + }
> + return rc;
> +}
> +
> +static ssize_t beiscsi_show_boot_ini_info(void *data, int type, char *buf)
> +{
> + struct beiscsi_hba *phba = data;
> + char *str = buf;
> + int rc;
> +
> + printk(KERN_ERR " In beiscsi_show_boot_ini_info type=%d\n", type);
> + switch (type) {
> + case ISCSI_BOOT_INI_INITIATOR_NAME:
> + rc = sprintf(str, "%s\n", phba->boot_sess.initiator_iscsiname);
> + break;
> + default:
> + rc = -ENOSYS;
> + break;
> + }
> + return rc;
> +}
> +
> +static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf)
> +{
> + struct beiscsi_hba *phba = data;
> + char *str = buf;
> + int rc;
> +
> + printk(KERN_ERR " In beiscsi_show_boot_eth_info type = %d\n", type);
> + switch (type) {
> + case ISCSI_BOOT_ETH_FLAGS:
> + rc = sprintf(str, "2\n");
> + break;
> + case ISCSI_BOOT_ETH_INDEX:
> + rc = sprintf(str, "0\n");
> + break;
> + case ISCSI_BOOT_ETH_MAC:
> + {
> + struct be_cmd_resp_get_mac_addr *resp;
> + struct be_mcc_wrb *wrb;
> + unsigned int tag, wrb_num;
> + unsigned short status, extd_status;
> + struct be_queue_info *mccq =&phba->ctrl.mcc_obj.q;
That chunk above should have some tabs I think.
> +
> + tag = be_cmd_get_mac_addr(phba);
> + if (!tag) {
> + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
> + return -1;
> + } else
> + wait_event_interruptible(phba->ctrl.mcc_wait[tag],
> + phba->ctrl.mcc_numtag[tag]);
> +
> + wrb_num = (phba->ctrl.mcc_numtag[tag]& 0x00FF0000)>> 16;
> + extd_status = (phba->ctrl.mcc_numtag[tag]& 0x0000FF00)>> 8;
> + status = phba->ctrl.mcc_numtag[tag]& 0x000000FF;
> + if (status || extd_status) {
> + SE_DEBUG(DBG_LVL_1, "Failed to get be_cmd_get_mac_addr"
> + " status = %d extd_status = %d\n",
> + status, extd_status);
> + free_mcc_tag(&phba->ctrl, tag);
> + return -1;
> + } else {
> + wrb = queue_get_wrb(mccq, wrb_num);
> + free_mcc_tag(&phba->ctrl, tag);
> + resp = embedded_payload(wrb);
> + memcpy(phba->mac_address, resp->mac_address, ETH_ALEN);
> + rc = sysfs_format_mac(buf, phba->mac_address,
> + ETH_ALEN);
> + }
Can't you get this info in the host setup functions and then use the
cached version? Or if it changes can you update the cached info?
This also looks like the same code in beiscsi_get_host_param so it
should at least be a function.
> + }
> +
> + break;
> + default:
> + rc = -ENOSYS;
> + break;
> + }
> + return rc;
> +}
> +
> +
> +static mode_t beiscsi_tgt_get_attr_visibility(void *data, int type)
> +{
> + int rc;
> +
> + switch (type) {
> + case ISCSI_BOOT_TGT_NAME:
> + case ISCSI_BOOT_TGT_IP_ADDR:
> + case ISCSI_BOOT_TGT_PORT:
> + case ISCSI_BOOT_TGT_CHAP_NAME:
> + case ISCSI_BOOT_TGT_CHAP_SECRET:
> + case ISCSI_BOOT_TGT_REV_CHAP_NAME:
> + case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
> + case ISCSI_BOOT_TGT_NIC_ASSOC:
> + case ISCSI_BOOT_TGT_FLAGS:
> + rc = S_IRUGO;
> + break;
> + default:
> + rc = 0;
> + break;
> + }
> + return rc;
> +}
> +
> +static mode_t beiscsi_ini_get_attr_visibility(void *data, int type)
> +{
> + int rc;
> +
> + switch (type) {
> + case ISCSI_BOOT_INI_INITIATOR_NAME:
> + rc = S_IRUGO;
> + break;
> + default:
> + rc = 0;
> + break;
> + }
> + return rc;
> +}
> +
> +
> +static mode_t beiscsi_eth_get_attr_visibility(void *data, int type)
> +{
> + int rc;
> +
> + switch (type) {
> + case ISCSI_BOOT_ETH_FLAGS:
> + case ISCSI_BOOT_ETH_MAC:
> + case ISCSI_BOOT_ETH_INDEX:
> + rc = S_IRUGO;
> + break;
> + default:
> + rc = 0;
> + break;
> + }
> + return rc;
> +}
> +
> +static int beiscsi_setup_boot_info(struct beiscsi_hba *phba)
> +{
> + struct iscsi_boot_kobj *boot_kobj;
> + char *set_name;
> +
> + set_name = kasprintf(GFP_KERNEL, "iscsi_boot%u", phba->shost->host_no);
> + if (!set_name)
> + return -ENOMEM;
> +
> + phba->boot_kset = iscsi_boot_create_kset(set_name);
> + if (!phba->boot_kset) {
> + kfree(set_name);
> + return -ENOMEM;
> + }
> +
> + /* get boot info using mgmt cmd */
> + boot_kobj = iscsi_boot_create_target(phba->boot_kset, 0, phba,
> + beiscsi_show_boot_tgt_info,
> + beiscsi_tgt_get_attr_visibility);
> + if (!boot_kobj)
> + goto free_kset;
> +
> + boot_kobj = iscsi_boot_create_initiator(phba->boot_kset, 0, phba,
> + beiscsi_show_boot_ini_info,
> + beiscsi_ini_get_attr_visibility);
> + if (!boot_kobj)
> + goto free_kset;
> +
> + boot_kobj = iscsi_boot_create_ethernet(phba->boot_kset, 0, phba,
> + beiscsi_show_boot_eth_info,
> + beiscsi_eth_get_attr_visibility);
> + if (!boot_kobj)
> + goto free_kset;
> + return 0;
> +
> +free_kset:
> + kfree(set_name);
> + iscsi_boot_destroy_kset(phba->boot_kset);
> + return -ENOMEM;
> +}
> +
> /*------------------- PCI Driver operations and data ----------------- */
> static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
> { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
> @@ -270,6 +523,15 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
>
> if (iscsi_host_add(shost,&phba->pcidev->dev))
> goto free_devices;
> +
> + if (beiscsi_setup_boot_info(phba))
> + /*
> + * log error but continue, because we may not be using
> + * iscsi boot.
> + */
> + shost_printk(KERN_ERR, phba->shost, "Could not set up "
> + "iSCSI boot info.");
> +
> return phba;
>
> free_devices:
> @@ -3263,6 +3525,89 @@ static void hwi_disable_intr(struct beiscsi_hba *phba)
> "In hwi_disable_intr, Already Disabled\n");
> }
>
> +static char beiscsi_get_boot_info(struct beiscsi_hba *phba)
> +{
> + struct be_cmd_resp_get_boot_target *boot_resp;
> + struct be_cmd_resp_geta_session *session_resp;
> + struct be_mcc_wrb *wrb;
> + struct be_dma_mem nonemb_cmd;
> + unsigned int tag, wrb_num;
> + unsigned short status, extd_status;
> + struct be_queue_info *mccq =&phba->ctrl.mcc_obj.q;
> +
> + tag = beiscsi_get_boot_target(phba);
> + if (!tag) {
> + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
> + return -1;
> + } else
> + wait_event_interruptible(phba->ctrl.mcc_wait[tag],
> + phba->ctrl.mcc_numtag[tag]);
> +
> + wrb_num = (phba->ctrl.mcc_numtag[tag]& 0x00FF0000)>> 16;
> + extd_status = (phba->ctrl.mcc_numtag[tag]& 0x0000FF00)>> 8;
> + status = phba->ctrl.mcc_numtag[tag]& 0x000000FF;
> + if (status || extd_status) {
> + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
> + " status = %d extd_status = %d\n",
> + status, extd_status);
> + free_mcc_tag(&phba->ctrl, tag);
> + return -1;
> + }
> + wrb = queue_get_wrb(mccq, wrb_num);
> + free_mcc_tag(&phba->ctrl, tag);
> + boot_resp = embedded_payload(wrb);
> +
> + if (boot_resp->boot_session_handle>= 0) {
> +
extra newline.
You also probably can change this up to be
if (boot_resp->boot_session_handle < 0) {
printk(KERN_ERR "No Boot Session for this pci_func,"
"session Hndl = %d\n", boot_resp->boot_session_handle);
return 0;
}
nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
sizeof(*session_resp),
&nonemb_cmd.dma);
.......
tag = beiscsi_geta_session_info(phba,
boot_resp->boot_session_handle,&nonemb_cmd);
if (!tag)
goto free_nonemb;
....
if (something else fails)
goto free_nonemb;
.....
free_nonemb:
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size
return 0;
> + nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
> + sizeof(*session_resp),
> + &nonemb_cmd.dma);
> + if (nonemb_cmd.va == NULL) {
> + SE_DEBUG(DBG_LVL_1,
> + "Failed to allocate memory for"
> + "beiscsi_geta_session_info\n");
> + return -1;
> + }
> +
> + memset(nonemb_cmd.va, 0, sizeof(*session_resp));
> + tag = beiscsi_geta_session_info(phba,
> + boot_resp->boot_session_handle,&nonemb_cmd);
> + if (!tag) {
> + SE_DEBUG(DBG_LVL_1, "beiscsi_geta_session_info"
> + " Failed\n");
> + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> + nonemb_cmd.va, nonemb_cmd.dma);
> + return -1;
> + } else
> + wait_event_interruptible(phba->ctrl.mcc_wait[tag],
> + phba->ctrl.mcc_numtag[tag]);
> +
> + wrb_num = (phba->ctrl.mcc_numtag[tag]& 0x00FF0000)>> 16;
> + extd_status = (phba->ctrl.mcc_numtag[tag]& 0x0000FF00)>> 8;
> + status = phba->ctrl.mcc_numtag[tag]& 0x000000FF;
> + if (status || extd_status) {
> + SE_DEBUG(DBG_LVL_1, "beiscsi_geta_session_info Failed"
> + " status = %d extd_status = %d\n",
> + status, extd_status);
> + free_mcc_tag(&phba->ctrl, tag);
> + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> + nonemb_cmd.va, nonemb_cmd.dma);
> + return -1;
> + }
> + wrb = queue_get_wrb(mccq, wrb_num);
> + free_mcc_tag(&phba->ctrl, tag);
> + session_resp = nonemb_cmd.va ;
> + memcpy(&phba->boot_sess,&session_resp->session_info,
> + sizeof(struct mgmt_session_info));
> + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> + nonemb_cmd.va, nonemb_cmd.dma);
> + } else {
> + printk(KERN_ERR "No Boot Session for this pci_func,"
> + "session Hndl = %d\n", boot_resp->boot_session_handle);
> + }
> + return 0;
> +}
> +
> static int beiscsi_init_port(struct beiscsi_hba *phba)
> {
> int ret;
> @@ -3825,6 +4170,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
> iscsi_host_remove(phba->shost);
> pci_dev_put(phba->pcidev);
> iscsi_host_free(phba->shost);
> + iscsi_boot_destroy_kset(phba->boot_kset);
> }
>
> static void beiscsi_msix_enable(struct beiscsi_hba *phba)
> @@ -3985,6 +4331,13 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
> "Failed to hwi_enable_intr\n");
> goto free_intr;
> }
> + ret = beiscsi_get_boot_info(phba);
Fix return value. Should be returning -Exyx code like the code does/should.
> + if (ret< 0) {
> + shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
> + "Failed to hwi_enable_intr\n");
> + goto free_intr;
> + }
> +
> SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n");
> return 0;
>
> diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
> index 08996d0..978a57d 100644
> --- a/drivers/scsi/be2iscsi/be_main.h
> +++ b/drivers/scsi/be2iscsi/be_main.h
> @@ -311,6 +311,7 @@ struct beiscsi_hba {
> struct list_head hba_queue;
> unsigned short *cid_array;
> struct iscsi_endpoint **ep_array;
> + struct iscsi_boot_kset *boot_kset;
> struct Scsi_Host *shost;
> struct {
> /**
> @@ -341,6 +342,7 @@ struct beiscsi_hba {
> struct work_struct work_cqs; /* The work being queued */
> struct be_ctrl_info ctrl;
> unsigned int generation;
> + struct mgmt_session_info boot_sess;
> struct invalidate_command_table inv_tbl[128];
>
> };
> diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
> index c33aa3c..ee85898 100644
> --- a/drivers/scsi/be2iscsi/be_mgmt.c
> +++ b/drivers/scsi/be2iscsi/be_mgmt.c
> @@ -20,6 +20,77 @@
>
> #include "be_mgmt.h"
> #include "be_iscsi.h"
> +#include<scsi/scsi_transport_iscsi.h>
> +
> +unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba)
> +{
> + struct be_ctrl_info *ctrl =&phba->ctrl;
> + struct be_mcc_wrb *wrb;
> + struct be_cmd_req_get_mac_addr *req;
> + unsigned int tag = 0;
> +
> + SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n");
> + spin_lock(&ctrl->mbox_lock);
> + tag = alloc_mcc_tag(phba);
> + if (!tag) {
> + spin_unlock(&ctrl->mbox_lock);
> + return tag;
> + }
> +
> + wrb = wrb_from_mccq(phba);
> + req = embedded_payload(wrb);
> + wrb->tag0 |= tag;
> + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
> + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
> + OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
> + sizeof(*req));
> +
> + be_mcc_notify(phba);
> + spin_unlock(&ctrl->mbox_lock);
> + return tag;
> +}
> +
> +unsigned int beiscsi_geta_session_info(struct beiscsi_hba *phba,
Probably just wanted to name this beiscsi_get_session_info
> + u32 boot_session_handle,
> + struct be_dma_mem *nonemb_cmd)
> +{
> + struct be_ctrl_info *ctrl =&phba->ctrl;
> + struct be_mcc_wrb *wrb;
> + unsigned int tag = 0;
> + struct be_cmd_req_geta_session *req;
> + struct be_cmd_resp_geta_session *resp;
> + struct be_sge *sge;
> +
> + SE_DEBUG(DBG_LVL_8, "In beiscsi_geta_session_info\n");
> + spin_lock(&ctrl->mbox_lock);
> + tag = alloc_mcc_tag(phba);
> + if (!tag) {
> + spin_unlock(&ctrl->mbox_lock);
> + return tag;
> + }
> +
> + nonemb_cmd->size = sizeof(*resp);
> + req = nonemb_cmd->va;
> + memset(req, 0, sizeof(*req));
> + wrb = wrb_from_mccq(phba);
> + sge = nonembedded_sgl(wrb);
> + wrb->tag0 |= tag;
> +
> +
> + wrb->tag0 |= tag;
> + be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
> + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
> + OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
> + sizeof(*resp));
> + req->session_handle = boot_session_handle;
> + 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;
> +}
>
> unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
> struct beiscsi_hba *phba)
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH 09/12] be2iscsi: Add support for iscsi boot
2010-07-04 20:16 ` Mike Christie
@ 2010-07-05 20:40 ` Konrad Rzeszutek Wilk
0 siblings, 0 replies; 4+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-07-05 20:40 UTC (permalink / raw)
To: Mike Christie; +Cc: Jayamohan Kalickal, linux-scsi, James.Bottomley
On Sunday 04 July 2010 16:16:32 Mike Christie wrote:
> ccing Konrad to give him some heads up that there is going to be another
> user of the boot lib.
Excellent. Jayamohan when you get to post a new version of the patches please
CC so that I can review them.
>
> On 06/29/2010 07:02 PM, Jayamohan Kallickal wrote:
> > +static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char
> > *buf) +{
> > + struct beiscsi_hba *phba = data;
> > + char *str = buf;
> > + int rc;
> > +
> > + printk(KERN_ERR " In beiscsi_show_boot_tgt_info type=%d\n", type);
> > + switch (type) {
> > + case ISCSI_BOOT_TGT_NAME:
> > + rc = sprintf(buf, "%.*s\n",
> > + (int)strlen(phba->boot_sess.target_name),
>
> Did you get a compile warning if you did not cast this to a int?
>
> > + (char *)&phba->boot_sess.target_name);
> > + break;
> > + case ISCSI_BOOT_TGT_IP_ADDR:
> > + if (phba->boot_sess.conn_list[0].dest_ipaddr.ip_type == 0x1)
> > + rc = sprintf(buf, "%pI4\n",
> > + (char *)&phba->boot_sess.conn_list[0].
> > + dest_ipaddr.ip_address);
> > + else
> > + rc = sprintf(str, "%pI6\n",
> > + (char *)&phba->boot_sess.conn_list[0].
> > + dest_ipaddr.ip_address);
> > + break;
> > + case ISCSI_BOOT_TGT_PORT:
> > + rc = sprintf(str, "%d\n", phba->boot_sess.conn_list[0].
> > + dest_port);
> > + break;
> > +
> > + case ISCSI_BOOT_TGT_CHAP_NAME:
> > + rc = sprintf(str, "%.*s\n",
> > + phba->boot_sess.conn_list[0].
> > + negotiated_login_options.auth_data.chap.
> > + target_chap_name_length,
> > + (char *)&phba->boot_sess.conn_list[0].
> > + negotiated_login_options.auth_data.chap.
> > + target_chap_name);
> > + break;
> > + case ISCSI_BOOT_TGT_CHAP_SECRET:
> > + rc = sprintf(str, "%.*s\n",
> > + phba->boot_sess.conn_list[0].
> > + negotiated_login_options.auth_data.chap.
> > + target_secret_length,
> > + (char *)&phba->boot_sess.conn_list[0].
> > + negotiated_login_options.auth_data.chap.
> > + target_secret);
> > +
> > + break;
> > + case ISCSI_BOOT_TGT_REV_CHAP_NAME:
> > + rc = sprintf(str, "%.*s\n",
> > + phba->boot_sess.conn_list[0].
> > + negotiated_login_options.auth_data.chap.
> > + intr_chap_name_length,
> > + (char *)&phba->boot_sess.conn_list[0].
> > + negotiated_login_options.auth_data.chap.
> > + intr_chap_name);
> > +
> > + break;
> > + case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
> > + rc = sprintf(str, "%.*s\n",
> > + phba->boot_sess.conn_list[0].
> > + negotiated_login_options.auth_data.chap.
> > + intr_secret_length,
> > + (char *)&phba->boot_sess.conn_list[0].
> > + negotiated_login_options.auth_data.chap.
> > + intr_secret);
> > + break;
> > + case ISCSI_BOOT_TGT_FLAGS:
> > + rc = sprintf(str, "2\n");
> > + break;
> > + case ISCSI_BOOT_TGT_NIC_ASSOC:
> > + rc = sprintf(str, "0\n");
> > + break;
> > + default:
> > + rc = -ENOSYS;
> > + break;
> > + }
> > + return rc;
> > +}
> > +
> > +static ssize_t beiscsi_show_boot_ini_info(void *data, int type, char
> > *buf) +{
> > + struct beiscsi_hba *phba = data;
> > + char *str = buf;
> > + int rc;
> > +
> > + printk(KERN_ERR " In beiscsi_show_boot_ini_info type=%d\n", type);
Remove that.
> > + switch (type) {
> > + case ISCSI_BOOT_INI_INITIATOR_NAME:
> > + rc = sprintf(str, "%s\n", phba->boot_sess.initiator_iscsiname);
> > + break;
> > + default:
> > + rc = -ENOSYS;
> > + break;
> > + }
> > + return rc;
> > +}
> > +
> > +static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char
> > *buf) +{
> > + struct beiscsi_hba *phba = data;
> > + char *str = buf;
> > + int rc;
> > +
> > + printk(KERN_ERR " In beiscsi_show_boot_eth_info type = %d\n", type);
Ditto.
> > + switch (type) {
> > + case ISCSI_BOOT_ETH_FLAGS:
> > + rc = sprintf(str, "2\n");
> > + break;
> > + case ISCSI_BOOT_ETH_INDEX:
> > + rc = sprintf(str, "0\n");
> > + break;
> > + case ISCSI_BOOT_ETH_MAC:
> > + {
> > + tag = be_cmd_get_mac_addr(phba);
> > + if (!tag) {
> > + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
You are missing a period at the end.
> > + return -1;
use the rc. Set it to the appropiate -E<value> and break out here.
> > + } else
> > + wait_event_interruptible(phba->ctrl.mcc_wait[tag],
> > + phba->ctrl.mcc_numtag[tag]);
> > +
> > + wrb_num = (phba->ctrl.mcc_numtag[tag]& 0x00FF0000)>> 16;
> > + extd_status = (phba->ctrl.mcc_numtag[tag]& 0x0000FF00)>> 8;
> > + status = phba->ctrl.mcc_numtag[tag]& 0x000000FF;
> > + if (status || extd_status) {
> > + SE_DEBUG(DBG_LVL_1, "Failed to get be_cmd_get_mac_addr"
> > + " status = %d extd_status = %d\n",
Missing period.
> > + status, extd_status);
> > + free_mcc_tag(&phba->ctrl, tag);
> > + return -1;
ditto.
> > + } else {
> > + wrb = queue_get_wrb(mccq, wrb_num);
> > + free_mcc_tag(&phba->ctrl, tag);
> > + resp = embedded_payload(wrb);
> > + memcpy(phba->mac_address, resp->mac_address, ETH_ALEN);
> > + rc = sysfs_format_mac(buf, phba->mac_address,
> > + ETH_ALEN);
> > + }
>
> Can't you get this info in the host setup functions and then use the
> cached version? Or if it changes can you update the cached info?
>
> This also looks like the same code in beiscsi_get_host_param so it
> should at least be a function.
>
> > + }
> > +
> > + break;
> > + default:
> > + rc = -ENOSYS;
> > + break;
> > + }
> > + return rc;
> > +}
> > +
> > +
> > +static mode_t beiscsi_tgt_get_attr_visibility(void *data, int type)
> > +{
> > + int rc;
> > +
> > + switch (type) {
> > + case ISCSI_BOOT_TGT_NAME:
> > + case ISCSI_BOOT_TGT_IP_ADDR:
> > + case ISCSI_BOOT_TGT_PORT:
> > + case ISCSI_BOOT_TGT_CHAP_NAME:
> > + case ISCSI_BOOT_TGT_CHAP_SECRET:
> > + case ISCSI_BOOT_TGT_REV_CHAP_NAME:
> > + case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
> > + case ISCSI_BOOT_TGT_NIC_ASSOC:
> > + case ISCSI_BOOT_TGT_FLAGS:
> > + rc = S_IRUGO;
> > + break;
> > + default:
> > + rc = 0;
> > + break;
> > + }
> > + return rc;
> > +}
> > +
> > +static mode_t beiscsi_ini_get_attr_visibility(void *data, int type)
> > +{
> > + int rc;
> > +
> > + switch (type) {
> > + case ISCSI_BOOT_INI_INITIATOR_NAME:
> > + rc = S_IRUGO;
> > + break;
> > + default:
> > + rc = 0;
> > + break;
> > + }
> > + return rc;
> > +}
> > +
> > +
> > +static mode_t beiscsi_eth_get_attr_visibility(void *data, int type)
> > +{
> > + int rc;
> > +
> > + switch (type) {
> > + case ISCSI_BOOT_ETH_FLAGS:
> > + case ISCSI_BOOT_ETH_MAC:
> > + case ISCSI_BOOT_ETH_INDEX:
> > + rc = S_IRUGO;
> > + break;
> > + default:
> > + rc = 0;
> > + break;
> > + }
> > + return rc;
> > +}
> > +
> > +static int beiscsi_setup_boot_info(struct beiscsi_hba *phba)
> > +{
> > + struct iscsi_boot_kobj *boot_kobj;
> > + char *set_name;
> > +
> > + set_name = kasprintf(GFP_KERNEL, "iscsi_boot%u", phba->shost->host_no);
> > + if (!set_name)
> > + return -ENOMEM;
> > +
> > + phba->boot_kset = iscsi_boot_create_kset(set_name);
> > + if (!phba->boot_kset) {
> > + kfree(set_name);
> > + return -ENOMEM;
> > + }
> > +
> > + /* get boot info using mgmt cmd */
> > + boot_kobj = iscsi_boot_create_target(phba->boot_kset, 0, phba,
> > + beiscsi_show_boot_tgt_info,
> > + beiscsi_tgt_get_attr_visibility);
> > + if (!boot_kobj)
> > + goto free_kset;
> > +
> > + boot_kobj = iscsi_boot_create_initiator(phba->boot_kset, 0, phba,
> > + beiscsi_show_boot_ini_info,
> > + beiscsi_ini_get_attr_visibility);
> > + if (!boot_kobj)
> > + goto free_kset;
> > +
> > + boot_kobj = iscsi_boot_create_ethernet(phba->boot_kset, 0, phba,
> > + beiscsi_show_boot_eth_info,
> > + beiscsi_eth_get_attr_visibility);
> > + if (!boot_kobj)
> > + goto free_kset;
> > + return 0;
> > +
> > +free_kset:
> > + kfree(set_name);
> > + iscsi_boot_destroy_kset(phba->boot_kset);
> > + return -ENOMEM;
> > +}
> > +
> > /*------------------- PCI Driver operations and data -----------------
> > */ static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
> > { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
> > @@ -270,6 +523,15 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct
> > pci_dev *pcidev)
> >
> > if (iscsi_host_add(shost,&phba->pcidev->dev))
> > goto free_devices;
> > +
> > + if (beiscsi_setup_boot_info(phba))
> > + /*
> > + * log error but continue, because we may not be using
> > + * iscsi boot.
> > + */
> > + shost_printk(KERN_ERR, phba->shost, "Could not set up "
> > + "iSCSI boot info.");
> > +
> > return phba;
> >
> > free_devices:
> > @@ -3263,6 +3525,89 @@ static void hwi_disable_intr(struct beiscsi_hba
> > *phba) "In hwi_disable_intr, Already Disabled\n");
> > }
> >
> > +static char beiscsi_get_boot_info(struct beiscsi_hba *phba)
Why is this function returning a char when you return int values?
> > +{
> > + struct be_cmd_resp_get_boot_target *boot_resp;
> > + struct be_cmd_resp_geta_session *session_resp;
> > + struct be_mcc_wrb *wrb;
> > + struct be_dma_mem nonemb_cmd;
> > + unsigned int tag, wrb_num;
> > + unsigned short status, extd_status;
> > + struct be_queue_info *mccq =&phba->ctrl.mcc_obj.q;
> > +
> > + tag = beiscsi_get_boot_target(phba);
> > + if (!tag) {
> > + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
Missing period at the end.
> > + return -1;
Should the error value be something else? Say -ENODEV or -EINVAL?
or -ENOSYS?
> > + } else
> > + wait_event_interruptible(phba->ctrl.mcc_wait[tag],
> > + phba->ctrl.mcc_numtag[tag]);
> > +
> > + wrb_num = (phba->ctrl.mcc_numtag[tag]& 0x00FF0000)>> 16;
> > + extd_status = (phba->ctrl.mcc_numtag[tag]& 0x0000FF00)>> 8;
> > + status = phba->ctrl.mcc_numtag[tag]& 0x000000FF;
> > + if (status || extd_status) {
> > + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
> > + " status = %d extd_status = %d\n",
> > + status, extd_status);
> > + free_mcc_tag(&phba->ctrl, tag);
> > + return -1;
> > + }
> > + wrb = queue_get_wrb(mccq, wrb_num);
> > + free_mcc_tag(&phba->ctrl, tag);
> > + boot_resp = embedded_payload(wrb);
> > +
> > + if (boot_resp->boot_session_handle>= 0) {
> > +
>
> extra newline.
>
> You also probably can change this up to be
>
> if (boot_resp->boot_session_handle < 0) {
> printk(KERN_ERR "No Boot Session for this pci_func,"
> "session Hndl = %d\n", boot_resp->boot_session_handle);
> return 0;
> }
>
>
> nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
> sizeof(*session_resp),
> &nonemb_cmd.dma);
>
> .......
>
>
> tag = beiscsi_geta_session_info(phba,
> boot_resp->boot_session_handle,&nonemb_cmd);
> if (!tag)
> goto free_nonemb;
>
> ....
>
> if (something else fails)
> goto free_nonemb;
>
> .....
>
> free_nonemb:
> pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size
> return 0;
>
> > + nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
> > + sizeof(*session_resp),
> > + &nonemb_cmd.dma);
> > + if (nonemb_cmd.va == NULL) {
> > + SE_DEBUG(DBG_LVL_1,
> > + "Failed to allocate memory for"
> > + "beiscsi_geta_session_info\n");
> > + return -1;
> > + }
> > +
> > + memset(nonemb_cmd.va, 0, sizeof(*session_resp));
> > + tag = beiscsi_geta_session_info(phba,
> > + boot_resp->boot_session_handle,&nonemb_cmd);
> > + if (!tag) {
> > + SE_DEBUG(DBG_LVL_1, "beiscsi_geta_session_info"
> > + " Failed\n");
> > + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> > + nonemb_cmd.va, nonemb_cmd.dma);
> > + return -1;
> > + } else
> > + wait_event_interruptible(phba->ctrl.mcc_wait[tag],
> > + phba->ctrl.mcc_numtag[tag]);
> > +
> > + wrb_num = (phba->ctrl.mcc_numtag[tag]& 0x00FF0000)>> 16;
> > + extd_status = (phba->ctrl.mcc_numtag[tag]& 0x0000FF00)>> 8;
> > + status = phba->ctrl.mcc_numtag[tag]& 0x000000FF;
> > + if (status || extd_status) {
> > + SE_DEBUG(DBG_LVL_1, "beiscsi_geta_session_info Failed"
> > + " status = %d extd_status = %d\n",
> > + status, extd_status);
> > + free_mcc_tag(&phba->ctrl, tag);
> > + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> > + nonemb_cmd.va, nonemb_cmd.dma);
> > + return -1;
> > + }
> > + wrb = queue_get_wrb(mccq, wrb_num);
> > + free_mcc_tag(&phba->ctrl, tag);
> > + session_resp = nonemb_cmd.va ;
> > + memcpy(&phba->boot_sess,&session_resp->session_info,
> > + sizeof(struct mgmt_session_info));
> > + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> > + nonemb_cmd.va, nonemb_cmd.dma);
> > + } else {
> > + printk(KERN_ERR "No Boot Session for this pci_func,"
> > + "session Hndl = %d\n", boot_resp->boot_session_handle);
> > + }
> > + return 0;
> > +}
> > +
> > static int beiscsi_init_port(struct beiscsi_hba *phba)
> > {
> > int ret;
> > @@ -3825,6 +4170,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
> > iscsi_host_remove(phba->shost);
> > pci_dev_put(phba->pcidev);
> > iscsi_host_free(phba->shost);
> > + iscsi_boot_destroy_kset(phba->boot_kset);
> > }
> >
> > static void beiscsi_msix_enable(struct beiscsi_hba *phba)
> > @@ -3985,6 +4331,13 @@ static int __devinit beiscsi_dev_probe(struct
> > pci_dev *pcidev, "Failed to hwi_enable_intr\n");
> > goto free_intr;
> > }
> > + ret = beiscsi_get_boot_info(phba);
>
> Fix return value. Should be returning -Exyx code like the code does/should.
>
> > + if (ret< 0) {
> > + shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
> > + "Failed to hwi_enable_intr\n");
> > + goto free_intr;
> > + }
> > +
> > SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n");
> > return 0;
> >
> > diff --git a/drivers/scsi/be2iscsi/be_main.h
> > b/drivers/scsi/be2iscsi/be_main.h index 08996d0..978a57d 100644
> > --- a/drivers/scsi/be2iscsi/be_main.h
> > +++ b/drivers/scsi/be2iscsi/be_main.h
> > @@ -311,6 +311,7 @@ struct beiscsi_hba {
> > struct list_head hba_queue;
> > unsigned short *cid_array;
> > struct iscsi_endpoint **ep_array;
> > + struct iscsi_boot_kset *boot_kset;
> > struct Scsi_Host *shost;
> > struct {
> > /**
> > @@ -341,6 +342,7 @@ struct beiscsi_hba {
> > struct work_struct work_cqs; /* The work being queued */
> > struct be_ctrl_info ctrl;
> > unsigned int generation;
> > + struct mgmt_session_info boot_sess;
> > struct invalidate_command_table inv_tbl[128];
> >
> > };
> > diff --git a/drivers/scsi/be2iscsi/be_mgmt.c
> > b/drivers/scsi/be2iscsi/be_mgmt.c index c33aa3c..ee85898 100644
> > --- a/drivers/scsi/be2iscsi/be_mgmt.c
> > +++ b/drivers/scsi/be2iscsi/be_mgmt.c
> > @@ -20,6 +20,77 @@
> >
> > #include "be_mgmt.h"
> > #include "be_iscsi.h"
> > +#include<scsi/scsi_transport_iscsi.h>
> > +
> > +unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba)
> > +{
> > + struct be_ctrl_info *ctrl =&phba->ctrl;
> > + struct be_mcc_wrb *wrb;
> > + struct be_cmd_req_get_mac_addr *req;
> > + unsigned int tag = 0;
> > +
> > + SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n");
> > + spin_lock(&ctrl->mbox_lock);
> > + tag = alloc_mcc_tag(phba);
> > + if (!tag) {
> > + spin_unlock(&ctrl->mbox_lock);
> > + return tag;
> > + }
> > +
> > + wrb = wrb_from_mccq(phba);
> > + req = embedded_payload(wrb);
> > + wrb->tag0 |= tag;
> > + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
> > + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
> > + OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
> > + sizeof(*req));
> > +
> > + be_mcc_notify(phba);
> > + spin_unlock(&ctrl->mbox_lock);
> > + return tag;
> > +}
> > +
> > +unsigned int beiscsi_geta_session_info(struct beiscsi_hba *phba,
>
> Probably just wanted to name this beiscsi_get_session_info
>
> > + u32 boot_session_handle,
> > + struct be_dma_mem *nonemb_cmd)
> > +{
> > + struct be_ctrl_info *ctrl =&phba->ctrl;
> > + struct be_mcc_wrb *wrb;
> > + unsigned int tag = 0;
> > + struct be_cmd_req_geta_session *req;
> > + struct be_cmd_resp_geta_session *resp;
> > + struct be_sge *sge;
> > +
> > + SE_DEBUG(DBG_LVL_8, "In beiscsi_geta_session_info\n");
> > + spin_lock(&ctrl->mbox_lock);
> > + tag = alloc_mcc_tag(phba);
> > + if (!tag) {
> > + spin_unlock(&ctrl->mbox_lock);
> > + return tag;
> > + }
> > +
> > + nonemb_cmd->size = sizeof(*resp);
> > + req = nonemb_cmd->va;
> > + memset(req, 0, sizeof(*req));
> > + wrb = wrb_from_mccq(phba);
> > + sge = nonembedded_sgl(wrb);
> > + wrb->tag0 |= tag;
> > +
> > +
> > + wrb->tag0 |= tag;
> > + be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
> > + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
> > + OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
> > + sizeof(*resp));
> > + req->session_handle = boot_session_handle;
> > + 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;
> > +}
> >
> > unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
> > struct beiscsi_hba *phba)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 09/12] be2iscsi: Add support for iscsi boot
@ 2010-07-09 18:47 Jayamohan Kalickal
0 siblings, 0 replies; 4+ messages in thread
From: Jayamohan Kalickal @ 2010-07-09 18:47 UTC (permalink / raw)
To: Mike Christie; +Cc: linux-scsi, James.Bottomley, Konrad Rzeszutek
_____
From: Mike Christie [mailto:michaelc@cs.wisc.edu]
To: Jayamohan Kalickal [mailto:jayamohank@serverengines.com]
Cc: linux-scsi@vger.kernel.org, James.Bottomley@suse.de, Konrad Rzeszutek [mailto:konrad@darnok.org]
Sent: Sun, 04 Jul 2010 13:16:32 -0700
Subject: Re: [PATCH 09/12] be2iscsi: Add support for iscsi boot
ccing Konrad to give him some heads up that there is going to be another
user of the boot lib.
On 06/29/2010 07:02 PM, Jayamohan Kallickal wrote:
> +static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf)
> +{
> + struct beiscsi_hba *phba = data;
> + char *str = buf;
> + int rc;
> +
> + printk(KERN_ERR " In beiscsi_show_boot_tgt_info type=%d\n", type);
> + switch (type) {
> + case ISCSI_BOOT_TGT_NAME:
> + rc = sprintf(buf, "%.*s\n",
> + (int)strlen(phba->boot_sess.target_name),
Did you get a compile warning if you did not cast this to a int?Yes, I did get a compile warning for this.
Will submit another set of patches with the changes required
> + (char *)&phba->boot_sess.target_name);
> + break;
> + case ISCSI_BOOT_TGT_IP_ADDR:
> + if (phba->boot_sess.conn_list[0].dest_ipaddr.ip_type == 0x1)
> + rc = sprintf(buf, "%pI4\n",
> + (char *)&phba->boot_sess.conn_list[0].
> + dest_ipaddr.ip_address);
> + else
> + rc = sprintf(str, "%pI6\n",
> + (char *)&phba->boot_sess.conn_list[0].
> + dest_ipaddr.ip_address);
> + break;
> + case ISCSI_BOOT_TGT_PORT:
> + rc = sprintf(str, "%d\n", phba->boot_sess.conn_list[0].
> + dest_port);
> + break;
> +
> + case ISCSI_BOOT_TGT_CHAP_NAME:
> + rc = sprintf(str, "%.*s\n",
> + phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + target_chap_name_length,
> + (char *)&phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + target_chap_name);
> + break;
> + case ISCSI_BOOT_TGT_CHAP_SECRET:
> + rc = sprintf(str, "%.*s\n",
> + phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + target_secret_length,
> + (char *)&phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + target_secret);
> +
> + break;
> + case ISCSI_BOOT_TGT_REV_CHAP_NAME:
> + rc = sprintf(str, "%.*s\n",
> + phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + intr_chap_name_length,
> + (char *)&phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + intr_chap_name);
> +
> + break;
> + case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
> + rc = sprintf(str, "%.*s\n",
> + phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + intr_secret_length,
> + (char *)&phba->boot_sess.conn_list[0].
> + negotiated_login_options.auth_data.chap.
> + intr_secret);
> + break;
> + case ISCSI_BOOT_TGT_FLAGS:
> + rc = sprintf(str, "2\n");
> + break;
> + case ISCSI_BOOT_TGT_NIC_ASSOC:
> + rc = sprintf(str, "0\n");
> + break;
> + default:
> + rc = -ENOSYS;
> + break;
> + }
> + return rc;
> +}
> +
> +static ssize_t beiscsi_show_boot_ini_info(void *data, int type, char *buf)
> +{
> + struct beiscsi_hba *phba = data;
> + char *str = buf;
> + int rc;
> +
> + printk(KERN_ERR " In beiscsi_show_boot_ini_info type=%d\n", type);
> + switch (type) {
> + case ISCSI_BOOT_INI_INITIATOR_NAME:
> + rc = sprintf(str, "%s\n", phba->boot_sess.initiator_iscsiname);
> + break;
> + default:
> + rc = -ENOSYS;
> + break;
> + }
> + return rc;
> +}
> +
> +static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf)
> +{
> + struct beiscsi_hba *phba = data;
> + char *str = buf;
> + int rc;
> +
> + printk(KERN_ERR " In beiscsi_show_boot_eth_info type = %d\n", type);
> + switch (type) {
> + case ISCSI_BOOT_ETH_FLAGS:
> + rc = sprintf(str, "2\n");
> + break;
> + case ISCSI_BOOT_ETH_INDEX:
> + rc = sprintf(str, "0\n");
> + break;
> + case ISCSI_BOOT_ETH_MAC:
> + {
> + struct be_cmd_resp_get_mac_addr *resp;
> + struct be_mcc_wrb *wrb;
> + unsigned int tag, wrb_num;
> + unsigned short status, extd_status;
> + struct be_queue_info *mccq =&phba->ctrl.mcc_obj.q;
That chunk above should have some tabs I think.
> +
> + tag = be_cmd_get_mac_addr(phba);
> + if (!tag) {
> + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
> + return -1;
> + } else
> + wait_event_interruptible(phba->ctrl.mcc_wait[tag],
> + phba->ctrl.mcc_numtag[tag]);
> +
> + wrb_num = (phba->ctrl.mcc_numtag[tag]& 0x00FF0000)>> 16;
> + extd_status = (phba->ctrl.mcc_numtag[tag]& 0x0000FF00)>> 8;
> + status = phba->ctrl.mcc_numtag[tag]& 0x000000FF;
> + if (status || extd_status) {
> + SE_DEBUG(DBG_LVL_1, "Failed to get be_cmd_get_mac_addr"
> + " status = %d extd_status = %d\n",
> + status, extd_status);
> + free_mcc_tag(&phba->ctrl, tag);
> + return -1;
> + } else {
> + wrb = queue_get_wrb(mccq, wrb_num);
> + free_mcc_tag(&phba->ctrl, tag);
> + resp = embedded_payload(wrb);
> + memcpy(phba->mac_address, resp->mac_address, ETH_ALEN);
> + rc = sysfs_format_mac(buf, phba->mac_address,
> + ETH_ALEN);
> + }
Can't you get this info in the host setup functions and then use the
cached version? Or if it changes can you update the cached info?
This also looks like the same code in beiscsi_get_host_param so it
should at least be a function.
> + }
> +
> + break;
> + default:
> + rc = -ENOSYS;
> + break;
> + }
> + return rc;
> +}
> +
> +
> +static mode_t beiscsi_tgt_get_attr_visibility(void *data, int type)
> +{
> + int rc;
> +
> + switch (type) {
> + case ISCSI_BOOT_TGT_NAME:
> + case ISCSI_BOOT_TGT_IP_ADDR:
> + case ISCSI_BOOT_TGT_PORT:
> + case ISCSI_BOOT_TGT_CHAP_NAME:
> + case ISCSI_BOOT_TGT_CHAP_SECRET:
> + case ISCSI_BOOT_TGT_REV_CHAP_NAME:
> + case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
> + case ISCSI_BOOT_TGT_NIC_ASSOC:
> + case ISCSI_BOOT_TGT_FLAGS:
> + rc = S_IRUGO;
> + break;
> + default:
> + rc = 0;
> + break;
> + }
> + return rc;
> +}
> +
> +static mode_t beiscsi_ini_get_attr_visibility(void *data, int type)
> +{
> + int rc;
> +
> + switch (type) {
> + case ISCSI_BOOT_INI_INITIATOR_NAME:
> + rc = S_IRUGO;
> + break;
> + default:
> + rc = 0;
> + break;
> + }
> + return rc;
> +}
> +
> +
> +static mode_t beiscsi_eth_get_attr_visibility(void *data, int type)
> +{
> + int rc;
> +
> + switch (type) {
> + case ISCSI_BOOT_ETH_FLAGS:
> + case ISCSI_BOOT_ETH_MAC:
> + case ISCSI_BOOT_ETH_INDEX:
> + rc = S_IRUGO;
> + break;
> + default:
> + rc = 0;
> + break;
> + }
> + return rc;
> +}
> +
> +static int beiscsi_setup_boot_info(struct beiscsi_hba *phba)
> +{
> + struct iscsi_boot_kobj *boot_kobj;
> + char *set_name;
> +
> + set_name = kasprintf(GFP_KERNEL, "iscsi_boot%u", phba->shost->host_no);
> + if (!set_name)
> + return -ENOMEM;
> +
> + phba->boot_kset = iscsi_boot_create_kset(set_name);
> + if (!phba->boot_kset) {
> + kfree(set_name);
> + return -ENOMEM;
> + }
> +
> + /* get boot info using mgmt cmd */
> + boot_kobj = iscsi_boot_create_target(phba->boot_kset, 0, phba,
> + beiscsi_show_boot_tgt_info,
> + beiscsi_tgt_get_attr_visibility);
> + if (!boot_kobj)
> + goto free_kset;
> +
> + boot_kobj = iscsi_boot_create_initiator(phba->boot_kset, 0, phba,
> + beiscsi_show_boot_ini_info,
> + beiscsi_ini_get_attr_visibility);
> + if (!boot_kobj)
> + goto free_kset;
> +
> + boot_kobj = iscsi_boot_create_ethernet(phba->boot_kset, 0, phba,
> + beiscsi_show_boot_eth_info,
> + beiscsi_eth_get_attr_visibility);
> + if (!boot_kobj)
> + goto free_kset;
> + return 0;
> +
> +free_kset:
> + kfree(set_name);
> + iscsi_boot_destroy_kset(phba->boot_kset);
> + return -ENOMEM;
> +}
> +
> /*------------------- PCI Driver operations and data ----------------- */
> static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
> { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
> @@ -270,6 +523,15 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
>
> if (iscsi_host_add(shost,&phba->pcidev->dev))
> goto free_devices;
> +
> + if (beiscsi_setup_boot_info(phba))
> + /*
> + * log error but continue, because we may not be using
> + * iscsi boot.
> + */
> + shost_printk(KERN_ERR, phba->shost, "Could not set up "
> + "iSCSI boot info.");
> +
> return phba;
>
> free_devices:
> @@ -3263,6 +3525,89 @@ static void hwi_disable_intr(struct beiscsi_hba *phba)
> "In hwi_disable_intr, Already Disabled\n");
> }
>
> +static char beiscsi_get_boot_info(struct beiscsi_hba *phba)
> +{
> + struct be_cmd_resp_get_boot_target *boot_resp;
> + struct be_cmd_resp_geta_session *session_resp;
> + struct be_mcc_wrb *wrb;
> + struct be_dma_mem nonemb_cmd;
> + unsigned int tag, wrb_num;
> + unsigned short status, extd_status;
> + struct be_queue_info *mccq =&phba->ctrl.mcc_obj.q;
> +
> + tag = beiscsi_get_boot_target(phba);
> + if (!tag) {
> + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
> + return -1;
> + } else
> + wait_event_interruptible(phba->ctrl.mcc_wait[tag],
> + phba->ctrl.mcc_numtag[tag]);
> +
> + wrb_num = (phba->ctrl.mcc_numtag[tag]& 0x00FF0000)>> 16;
> + extd_status = (phba->ctrl.mcc_numtag[tag]& 0x0000FF00)>> 8;
> + status = phba->ctrl.mcc_numtag[tag]& 0x000000FF;
> + if (status || extd_status) {
> + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
> + " status = %d extd_status = %d\n",
> + status, extd_status);
> + free_mcc_tag(&phba->ctrl, tag);
> + return -1;
> + }
> + wrb = queue_get_wrb(mccq, wrb_num);
> + free_mcc_tag(&phba->ctrl, tag);
> + boot_resp = embedded_payload(wrb);
> +
> + if (boot_resp->boot_session_handle>= 0) {
> +
extra newline.
You also probably can change this up to be
if (boot_resp->boot_session_handle < 0) {
printk(KERN_ERR "No Boot Session for this pci_func,"
"session Hndl = %d\n", boot_resp->boot_session_handle);
return 0;
}
nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
sizeof(*session_resp),
&nonemb_cmd.dma);
.......
tag = beiscsi_geta_session_info(phba,
boot_resp->boot_session_handle,&nonemb_cmd);
if (!tag)
goto free_nonemb;
....
if (something else fails)
goto free_nonemb;
.....
free_nonemb:
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size
return 0;
> + nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
> + sizeof(*session_resp),
> + &nonemb_cmd.dma);
> + if (nonemb_cmd.va == NULL) {
> + SE_DEBUG(DBG_LVL_1,
> + "Failed to allocate memory for"
> + "beiscsi_geta_session_info\n");
> + return -1;
> + }
> +
> + memset(nonemb_cmd.va, 0, sizeof(*session_resp));
> + tag = beiscsi_geta_session_info(phba,
> + boot_resp->boot_session_handle,&nonemb_cmd);
> + if (!tag) {
> + SE_DEBUG(DBG_LVL_1, "beiscsi_geta_session_info"
> + " Failed\n");
> + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> + nonemb_cmd.va, nonemb_cmd.dma);
> + return -1;
> + } else
> + wait_event_interruptible(phba->ctrl.mcc_wait[tag],
> + phba->ctrl.mcc_numtag[tag]);
> +
> + wrb_num = (phba->ctrl.mcc_numtag[tag]& 0x00FF0000)>> 16;
> + extd_status = (phba->ctrl.mcc_numtag[tag]& 0x0000FF00)>> 8;
> + status = phba->ctrl.mcc_numtag[tag]& 0x000000FF;
> + if (status || extd_status) {
> + SE_DEBUG(DBG_LVL_1, "beiscsi_geta_session_info Failed"
> + " status = %d extd_status = %d\n",
> + status, extd_status);
> + free_mcc_tag(&phba->ctrl, tag);
> + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> + nonemb_cmd.va, nonemb_cmd.dma);
> + return -1;
> + }
> + wrb = queue_get_wrb(mccq, wrb_num);
> + free_mcc_tag(&phba->ctrl, tag);
> + session_resp = nonemb_cmd.va ;
> + memcpy(&phba->boot_sess,&session_resp->session_info,
> + sizeof(struct mgmt_session_info));
> + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> + nonemb_cmd.va, nonemb_cmd.dma);
> + } else {
> + printk(KERN_ERR "No Boot Session for this pci_func,"
> + "session Hndl = %d\n", boot_resp->boot_session_handle);
> + }
> + return 0;
> +}
> +
> static int beiscsi_init_port(struct beiscsi_hba *phba)
> {
> int ret;
> @@ -3825,6 +4170,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
> iscsi_host_remove(phba->shost);
> pci_dev_put(phba->pcidev);
> iscsi_host_free(phba->shost);
> + iscsi_boot_destroy_kset(phba->boot_kset);
> }
>
> static void beiscsi_msix_enable(struct beiscsi_hba *phba)
> @@ -3985,6 +4331,13 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
> "Failed to hwi_enable_intr\n");
> goto free_intr;
> }
> + ret = beiscsi_get_boot_info(phba);
Fix return value. Should be returning -Exyx code like the code does/should.
> + if (ret< 0) {
> + shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
> + "Failed to hwi_enable_intr\n");
> + goto free_intr;
> + }
> +
> SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n");
> return 0;
>
> diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
> index 08996d0..978a57d 100644
> --- a/drivers/scsi/be2iscsi/be_main.h
> +++ b/drivers/scsi/be2iscsi/be_main.h
> @@ -311,6 +311,7 @@ struct beiscsi_hba {
> struct list_head hba_queue;
> unsigned short *cid_array;
> struct iscsi_endpoint **ep_array;
> + struct iscsi_boot_kset *boot_kset;
> struct Scsi_Host *shost;
> struct {
> /**
> @@ -341,6 +342,7 @@ struct beiscsi_hba {
> struct work_struct work_cqs; /* The work being queued */
> struct be_ctrl_info ctrl;
> unsigned int generation;
> + struct mgmt_session_info boot_sess;
> struct invalidate_command_table inv_tbl[128];
>
> };
> diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
> index c33aa3c..ee85898 100644
> --- a/drivers/scsi/be2iscsi/be_mgmt.c
> +++ b/drivers/scsi/be2iscsi/be_mgmt.c
> @@ -20,6 +20,77 @@
>
> #include "be_mgmt.h"
> #include "be_iscsi.h"
> +#include<scsi/scsi_transport_iscsi.h>
> +
> +unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba)
> +{
> + struct be_ctrl_info *ctrl =&phba->ctrl;
> + struct be_mcc_wrb *wrb;
> + struct be_cmd_req_get_mac_addr *req;
> + unsigned int tag = 0;
> +
> + SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n");
> + spin_lock(&ctrl->mbox_lock);
> + tag = alloc_mcc_tag(phba);
> + if (!tag) {
> + spin_unlock(&ctrl->mbox_lock);
> + return tag;
> + }
> +
> + wrb = wrb_from_mccq(phba);
> + req = embedded_payload(wrb);
> + wrb->tag0 |= tag;
> + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
> + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
> + OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
> + sizeof(*req));
> +
> + be_mcc_notify(phba);
> + spin_unlock(&ctrl->mbox_lock);
> + return tag;
> +}
> +
> +unsigned int beiscsi_geta_session_info(struct beiscsi_hba *phba,
Probably just wanted to name this beiscsi_get_session_info
> + u32 boot_session_handle,
> + struct be_dma_mem *nonemb_cmd)
> +{
> + struct be_ctrl_info *ctrl =&phba->ctrl;
> + struct be_mcc_wrb *wrb;
> + unsigned int tag = 0;
> + struct be_cmd_req_geta_session *req;
> + struct be_cmd_resp_geta_session *resp;
> + struct be_sge *sge;
> +
> + SE_DEBUG(DBG_LVL_8, "In beiscsi_geta_session_info\n");
> + spin_lock(&ctrl->mbox_lock);
> + tag = alloc_mcc_tag(phba);
> + if (!tag) {
> + spin_unlock(&ctrl->mbox_lock);
> + return tag;
> + }
> +
> + nonemb_cmd->size = sizeof(*resp);
> + req = nonemb_cmd->va;
> + memset(req, 0, sizeof(*req));
> + wrb = wrb_from_mccq(phba);
> + sge = nonembedded_sgl(wrb);
> + wrb->tag0 |= tag;
> +
> +
> + wrb->tag0 |= tag;
> + be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
> + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
> + OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
> + sizeof(*resp));
> + req->session_handle = boot_session_handle;
> + 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;
> +}
>
> unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
> struct beiscsi_hba *phba)
___________________________________________________________________________________
This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines Corporation and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited. If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-07-09 18:47 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-30 0:02 [PATCH 09/12] be2iscsi: Add support for iscsi boot Jayamohan Kallickal
2010-07-04 20:16 ` Mike Christie
2010-07-05 20:40 ` Konrad Rzeszutek Wilk
-- strict thread matches above, loose matches on Subject: below --
2010-07-09 18:47 Jayamohan Kalickal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).