dect
/
linux-2.6
Archived
13
0
Fork 0

[SCSI] be2iscsi: Issue MBX Cmd for login to boot target in crashdump mode

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.

Signed-off-by: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
John Soni Jose 2012-08-20 23:00:08 +05:30 committed by James Bottomley
parent afd96fa45b
commit 9aef4200ee
5 changed files with 175 additions and 28 deletions

View 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;
@ -911,6 +928,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

View File

@ -3466,44 +3466,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;
/* 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;
}
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;
}
nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
sizeof(*session_resp),
&nonemb_cmd.dma);
@ -3515,7 +3504,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"

View 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

View File

@ -23,6 +23,50 @@
#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;
@ -924,3 +968,92 @@ unsigned int be_cmd_get_port_speed(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;
}

View 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