]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
be2iscsi: Issue MBX Cmd for login to boot target in crashdump mode
authorJohn Soni Jose <sony.john-n@emulex.com>
Thu, 23 Aug 2012 08:55:33 +0000 (14:25 +0530)
committerJerry Snitselaar <jerry.snitselaar@oracle.com>
Thu, 30 Aug 2012 22:34:21 +0000 (15:34 -0700)
 When the driver comes up in crashdump mode, it has to explicitly
 issue command to FW for logging to the boot target. This fix issues
 MBX Cmd to login to boot target in crashdump mode.

 Patch Submitted to upstream kernel.

Signed-off-by: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
drivers/scsi/be2iscsi/be_cmds.h
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_main.h
drivers/scsi/be2iscsi/be_mgmt.c
drivers/scsi/be2iscsi/be_mgmt.h

index 60d144550f768511f2ad5a8540fa0119528ddb17..553d287ff6bb6eb91e780c435fba0b4c07f0d67e 100644 (file)
@@ -348,6 +348,23 @@ struct be_cmd_get_boot_target_resp {
        int  boot_session_handle;
 };
 
+struct be_cmd_reopen_session_req {
+       struct be_cmd_req_hdr hdr;
+#define BE_REOPEN_ALL_SESSIONS  0x00
+#define BE_REOPEN_BOOT_SESSIONS 0x01
+#define BE_REOPEN_A_SESSION     0x02
+       u16 reopen_type;
+       u16 rsvd;
+       u32 session_handle;
+} __packed;
+
+struct be_cmd_reopen_session_resp {
+       struct be_cmd_resp_hdr hdr;
+       u32 rsvd;
+       u32 session_handle;
+} __packed;
+
+
 struct be_cmd_mac_query_req {
        struct be_cmd_req_hdr hdr;
        u8 type;
@@ -887,6 +904,7 @@ struct be_cmd_get_all_if_id_req {
 #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_REOPEN_ALL_SESSIONS 36
 #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
index 8f11090f94ce034d2d891cf5c1e3bcb178acd770..e6c2af8953828d224780e65e1fa85288ee3b8944 100644 (file)
@@ -3465,44 +3465,33 @@ static void hwi_disable_intr(struct beiscsi_hba *phba)
                             "In hwi_disable_intr, Already Disabled\n");
 }
 
+/**
+ * beiscsi_get_boot_info()- Get the boot session info
+ * @phba: The device priv structure instance
+ *
+ * Get the boot target info and store in driver priv structure
+ *
+ * return values
+ *     Success: 0
+ *     Failure: Non-Zero Value
+ **/
 static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
 {
-       struct be_cmd_get_boot_target_resp *boot_resp;
        struct be_cmd_get_session_resp *session_resp;
        struct be_mcc_wrb *wrb;
        struct be_dma_mem nonemb_cmd;
        unsigned int tag, wrb_num;
        unsigned short status, extd_status;
+       unsigned int s_handle;
        struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
        int ret = -ENOMEM;
 
-       tag = mgmt_get_boot_target(phba);
-       if (!tag) {
-               SE_DEBUG(DBG_LVL_1, "beiscsi_get_boot_info Failed\n");
-               return -EAGAIN;
-       } 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_get_boot_info Failed"
-                                   " status = %d extd_status = %d\n",
-                                   status, extd_status);
-               free_mcc_tag(&phba->ctrl, tag);
-               return -EBUSY;
-       }
-       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) {
-               shost_printk(KERN_INFO, phba->shost, "No Boot Session.\n");
-               return -ENXIO;
+       /* Get the session handle of the boot target */
+       ret = be_mgmt_get_boot_shandle(phba, &s_handle);
+       if (ret) {
+               SE_DEBUG(DBG_LVL_1, "No boot session\n");
+               return ret;
        }
-
        nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
                                sizeof(*session_resp),
                                &nonemb_cmd.dma);
@@ -3514,7 +3503,7 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
        }
 
        memset(nonemb_cmd.va, 0, sizeof(*session_resp));
-       tag = mgmt_get_session_info(phba, boot_resp->boot_session_handle,
+       tag = mgmt_get_session_info(phba, s_handle,
                                    &nonemb_cmd);
        if (!tag) {
                SE_DEBUG(DBG_LVL_1, "beiscsi_get_session_info"
index 08c5b369b0a841b6f350f52cb325d52567721ac7..9c14112e9405545d720017ee7357bd6fe3e25e29 100644 (file)
@@ -84,6 +84,7 @@
 #define MAX_CMD_SZ                     65536
 #define IIOC_SCSI_DATA                  0x05   /* Write Operation */
 
+#define INVALID_SESS_HANDLE    0xFFFFFFFF
 #define DBG_LVL                                0x00000001
 #define DBG_LVL_1                      0x00000001
 #define DBG_LVL_2                      0x00000002
index 4e6d4eb312fe35fc8e881919fd291ba32df0527d..d1af3bb469907d8b8aecd9440cc4239b62cae99e 100644 (file)
 #include "be_mgmt.h"
 #include "be_iscsi.h"
 
+/**
+ * mgmt_reopen_session()- Reopen a session based on reopen_type
+ * @phba: Device priv structure instance
+ * @reopen_type: Type of reopen_session FW should do.
+ * @sess_handle: Session Handle of the session to be re-opened
+ *
+ * return
+ *     the TAG used for MBOX Command
+ *
+ **/
+unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
+                                 unsigned int reopen_type,
+                                 unsigned int sess_handle)
+{
+       struct be_ctrl_info *ctrl = &phba->ctrl;
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_reopen_session_req *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_DRIVER_REOPEN_ALL_SESSIONS,
+                          sizeof(struct be_cmd_reopen_session_resp));
+
+       /* set the reopen_type,sess_handle */
+       req->reopen_type = reopen_type;
+       req->session_handle = sess_handle;
+
+       be_mcc_notify(phba);
+       spin_unlock(&ctrl->mbox_lock);
+       return tag;
+}
+
 unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
 {
        struct be_ctrl_info *ctrl = &phba->ctrl;
@@ -897,3 +941,92 @@ unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
        spin_unlock(&ctrl->mbox_lock);
        return tag;
 }
+
+/**
+ * be_mgmt_get_boot_shandle()- Get the session handle
+ * @phba: device priv structure instance
+ * @s_handle: session handle returned for boot session.
+ *
+ * Get the boot target session handle. In case of
+ * crashdump mode driver has to issue and MBX Cmd
+ * for FW to login to boot target
+ *
+ * return
+ *     Success: 0
+ *     Failure: Non-Zero value
+ *
+ **/
+int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
+                             unsigned int *s_handle)
+{
+       struct be_cmd_get_boot_target_resp *boot_resp;
+       struct be_mcc_wrb *wrb;
+       unsigned int tag, wrb_num;
+       uint8_t boot_retry = 3;
+       unsigned short status, extd_status;
+       struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+
+       do {
+               /* Get the Boot Target Session Handle and Count*/
+               tag = mgmt_get_boot_target(phba);
+               if (!tag) {
+                       SE_DEBUG(DBG_LVL_1, "mgmt_get_boot_target Failed\n");
+                       return -EAGAIN;
+               } 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, "mgmt_get_boot_target Failed"
+                                           " status = %d extd_status = %d\n",
+                                           status, extd_status);
+                       free_mcc_tag(&phba->ctrl, tag);
+                       return -EBUSY;
+               }
+               wrb = queue_get_wrb(mccq, wrb_num);
+               free_mcc_tag(&phba->ctrl, tag);
+               boot_resp = embedded_payload(wrb);
+
+               /* Check if the there are any Boot targets configured */
+               if (!boot_resp->boot_session_count) {
+                       SE_DEBUG(DBG_LVL_8, "No boot targets configured\n");
+                       return -ENXIO;
+               }
+
+               /* FW returns the session handle of the boot session */
+               if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
+                       *s_handle = boot_resp->boot_session_handle;
+                       return 0;
+               }
+
+               /* Issue MBX Cmd to FW to login to the boot target */
+               tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
+                                         INVALID_SESS_HANDLE);
+               if (!tag) {
+                       SE_DEBUG(DBG_LVL_1, "mgmt_reopen_session Failed\n");
+                       return -EAGAIN;
+               } 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, "mgmt_reopen_session Failed"
+                                           " status = %d extd_status = %d\n",
+                                           status, extd_status);
+                       free_mcc_tag(&phba->ctrl, tag);
+                       return -EBUSY;
+               }
+               free_mcc_tag(&phba->ctrl, tag);
+
+       } while (--boot_retry);
+
+       /* Couldn't log into the boot target */
+       SE_DEBUG(DBG_LVL_1, "Login to Boot Target Failed\n");
+       return -ENXIO;
+}
index 5c2e37693ca82a863c0b459a1b58df342d80d6be..63b8e81f325018a16fcfe73b48dba2c6c0b3db9f 100644 (file)
@@ -274,6 +274,10 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
 
 unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba);
 
+unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
+                                 unsigned int reopen_type,
+                                 unsigned sess_handle);
+
 unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
                                   u32 boot_session_handle,
                                   struct be_dma_mem *nonemb_cmd);
@@ -290,4 +294,6 @@ int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
 int mgmt_set_gateway(struct beiscsi_hba *phba,
                     struct iscsi_iface_param_info *gateway_param);
 
+int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
+                             unsigned int *s_handle);
 #endif