Commit e175defe authored by John Soni Jose's avatar John Soni Jose Committed by James Bottomley

[SCSI] be2iscsi: Fix for MBX timeout issue

The MBX timeout value set to 100 and if adapter doesn;t
return response in that time driver will return from waiting
for completion with an error to the caller. In the earlier code
driver use to wait until MBX  response comes from adapter.
Signed-off-by: default avatarJohn Soni Jose <sony.john-n@emulex.com>
Signed-off-by: default avatarJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 5faf17b4
...@@ -133,6 +133,84 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba) ...@@ -133,6 +133,84 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
return tag; return tag;
} }
/*
* beiscsi_mccq_compl()- Wait for completion of MBX
* @phba: Driver private structure
* @tag: Tag for the MBX Command
* @wrb: the WRB used for the MBX Command
* @cmd_hdr: IOCTL Hdr for the MBX Cmd
*
* Waits for MBX completion with the passed TAG.
*
* return
* Success: 0
* Failure: Non-Zero
**/
int beiscsi_mccq_compl(struct beiscsi_hba *phba,
uint32_t tag, struct be_mcc_wrb **wrb,
void *cmd_hdr)
{
int rc = 0;
uint32_t mcc_tag_response;
uint16_t status = 0, addl_status = 0, wrb_num = 0;
struct be_mcc_wrb *temp_wrb;
struct be_cmd_req_hdr *ioctl_hdr;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag],
msecs_to_jiffies(
BEISCSI_HOST_MBX_TIMEOUT));
if (rc <= 0) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
BEISCSI_LOG_CONFIG,
"BC_%d : MBX Cmd Completion timed out\n");
rc = -EAGAIN;
goto release_mcc_tag;
} else
rc = 0;
mcc_tag_response = phba->ctrl.mcc_numtag[tag];
status = (mcc_tag_response & CQE_STATUS_MASK);
addl_status = ((mcc_tag_response & CQE_STATUS_ADDL_MASK) >>
CQE_STATUS_ADDL_SHIFT);
if (cmd_hdr) {
ioctl_hdr = (struct be_cmd_req_hdr *)cmd_hdr;
} else {
wrb_num = (mcc_tag_response & CQE_STATUS_WRB_MASK) >>
CQE_STATUS_WRB_SHIFT;
temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
ioctl_hdr = embedded_payload(temp_wrb);
if (wrb)
*wrb = temp_wrb;
}
if (status || addl_status) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
BEISCSI_LOG_CONFIG,
"BC_%d : MBX Cmd Failed for "
"Subsys : %d Opcode : %d with "
"Status : %d and Extd_Status : %d\n",
ioctl_hdr->subsystem,
ioctl_hdr->opcode,
status, addl_status);
rc = -EAGAIN;
}
release_mcc_tag:
/* Release the MCC entry */
free_mcc_tag(&phba->ctrl, tag);
return rc;
}
void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag) void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
{ {
spin_lock(&ctrl->mbox_lock); spin_lock(&ctrl->mbox_lock);
...@@ -168,11 +246,24 @@ static inline void be_mcc_compl_use(struct be_mcc_compl *compl) ...@@ -168,11 +246,24 @@ static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
compl->flags = 0; compl->flags = 0;
} }
/*
* be_mcc_compl_process()- Check the MBX comapletion status
* @ctrl: Function specific MBX data structure
* @compl: Completion status of MBX Command
*
* Check for the MBX completion status when BMBX method used
*
* return
* Success: Zero
* Failure: Non-Zero
**/
static int be_mcc_compl_process(struct be_ctrl_info *ctrl, static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
struct be_mcc_compl *compl) struct be_mcc_compl *compl)
{ {
u16 compl_status, extd_status; u16 compl_status, extd_status;
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
struct be_cmd_req_hdr *hdr = embedded_payload(wrb);
be_dws_le_to_cpu(compl, 4); be_dws_le_to_cpu(compl, 4);
...@@ -184,7 +275,10 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl, ...@@ -184,7 +275,10 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : error in cmd completion: status(compl/extd)=%d/%d\n", "BC_%d : error in cmd completion: "
"Subsystem : %d Opcode : %d "
"status(compl/extd)=%d/%d\n",
hdr->subsystem, hdr->opcode,
compl_status, extd_status); compl_status, extd_status);
return -EBUSY; return -EBUSY;
...@@ -314,11 +408,24 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba) ...@@ -314,11 +408,24 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
return status; return status;
} }
/* Wait till no more pending mcc requests are present */ /*
* be_mcc_wait_compl()- Wait for MBX completion
* @phba: driver private structure
*
* Wait till no more pending mcc requests are present
*
* return
* Success: 0
* Failure: Non-Zero
*
**/
static int be_mcc_wait_compl(struct beiscsi_hba *phba) static int be_mcc_wait_compl(struct beiscsi_hba *phba)
{ {
int i, status; int i, status;
for (i = 0; i < mcc_timeout; i++) { for (i = 0; i < mcc_timeout; i++) {
if (phba->fw_timeout)
return -EIO;
status = beiscsi_process_mcc(phba); status = beiscsi_process_mcc(phba);
if (status) if (status)
return status; return status;
...@@ -330,51 +437,80 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba) ...@@ -330,51 +437,80 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba)
if (i == mcc_timeout) { if (i == mcc_timeout) {
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : mccq poll timed out\n"); "BC_%d : FW Timed Out\n");
phba->fw_timeout = true;
return -EBUSY; return -EBUSY;
} }
return 0; return 0;
} }
/* Notify MCC requests and wait for completion */ /*
* be_mcc_notify_wait()- Notify and wait for Compl
* @phba: driver private structure
*
* Notify MCC requests and wait for completion
*
* return
* Success: 0
* Failure: Non-Zero
**/
int be_mcc_notify_wait(struct beiscsi_hba *phba) int be_mcc_notify_wait(struct beiscsi_hba *phba)
{ {
be_mcc_notify(phba); be_mcc_notify(phba);
return be_mcc_wait_compl(phba); return be_mcc_wait_compl(phba);
} }
/*
* be_mbox_db_ready_wait()- Check ready status
* @ctrl: Function specific MBX data structure
*
* Check for the ready status of FW to send BMBX
* commands to adapter.
*
* return
* Success: 0
* Failure: Non-Zero
**/
static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
{ {
#define long_delay 2000
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
int cnt = 0, wait = 5; /* in usecs */ struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
int wait = 0;
u32 ready; u32 ready;
do { do {
if (phba->fw_timeout)
return -EIO;
ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK; ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
if (ready) if (ready)
break; break;
if (cnt > 12000000) { if (wait > BEISCSI_HOST_MBX_TIMEOUT) {
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : mbox_db poll timed out\n"); "BC_%d : FW Timed Out\n");
phba->fw_timeout = true;
return -EBUSY; return -EBUSY;
} }
if (cnt > 50) { mdelay(1);
wait = long_delay; wait++;
mdelay(long_delay / 1000);
} else
udelay(wait);
cnt += wait;
} while (true); } while (true);
return 0; return 0;
} }
/*
* be_mbox_notify: Notify adapter of new BMBX command
* @ctrl: Function specific MBX data structure
*
* Ring doorbell to inform adapter of a BMBX command
* to process
*
* return
* Success: 0
* Failure: Non-Zero
**/
int be_mbox_notify(struct be_ctrl_info *ctrl) int be_mbox_notify(struct be_ctrl_info *ctrl)
{ {
int status; int status;
...@@ -391,13 +527,9 @@ int be_mbox_notify(struct be_ctrl_info *ctrl) ...@@ -391,13 +527,9 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
iowrite32(val, db); iowrite32(val, db);
status = be_mbox_db_ready_wait(ctrl); status = be_mbox_db_ready_wait(ctrl);
if (status != 0) { if (status)
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : be_mbox_db_ready_wait failed\n");
return status; return status;
}
val = 0; val = 0;
val &= ~MPU_MAILBOX_DB_RDY_MASK; val &= ~MPU_MAILBOX_DB_RDY_MASK;
val &= ~MPU_MAILBOX_DB_HI_MASK; val &= ~MPU_MAILBOX_DB_HI_MASK;
...@@ -405,13 +537,9 @@ int be_mbox_notify(struct be_ctrl_info *ctrl) ...@@ -405,13 +537,9 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
iowrite32(val, db); iowrite32(val, db);
status = be_mbox_db_ready_wait(ctrl); status = be_mbox_db_ready_wait(ctrl);
if (status != 0) { if (status)
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BC_%d : be_mbox_db_ready_wait failed\n");
return status; return status;
}
if (be_mcc_compl_is_new(compl)) { if (be_mcc_compl_is_new(compl)) {
status = be_mcc_compl_process(ctrl, &mbox->compl); status = be_mcc_compl_process(ctrl, &mbox->compl);
be_mcc_compl_use(compl); be_mcc_compl_use(compl);
...@@ -499,7 +627,7 @@ void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr, ...@@ -499,7 +627,7 @@ void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
req_hdr->opcode = opcode; req_hdr->opcode = opcode;
req_hdr->subsystem = subsystem; req_hdr->subsystem = subsystem;
req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr)); req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
req_hdr->timeout = 120; req_hdr->timeout = BEISCSI_FW_MBX_TIMEOUT;
} }
static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages, static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
......
...@@ -57,6 +57,13 @@ struct be_mcc_wrb { ...@@ -57,6 +57,13 @@ struct be_mcc_wrb {
#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */ #define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */
#define CQE_STATUS_EXTD_MASK 0xFFFF #define CQE_STATUS_EXTD_MASK 0xFFFF
#define CQE_STATUS_EXTD_SHIFT 16 /* bits 0 - 15 */ #define CQE_STATUS_EXTD_SHIFT 16 /* bits 0 - 15 */
#define CQE_STATUS_ADDL_MASK 0xFF00
#define CQE_STATUS_MASK 0xFF
#define CQE_STATUS_ADDL_SHIFT 0x08
#define CQE_STATUS_WRB_MASK 0xFF0000
#define CQE_STATUS_WRB_SHIFT 16
#define BEISCSI_HOST_MBX_TIMEOUT (110 * 1000)
#define BEISCSI_FW_MBX_TIMEOUT 100
/* MBOX Command VER */ /* MBOX Command VER */
#define MBX_CMD_VER2 0x02 #define MBX_CMD_VER2 0x02
...@@ -685,6 +692,9 @@ unsigned int be_cmd_get_initname(struct beiscsi_hba *phba); ...@@ -685,6 +692,9 @@ unsigned int be_cmd_get_initname(struct beiscsi_hba *phba);
unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba); unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba);
void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
int beiscsi_mccq_compl(struct beiscsi_hba *phba,
uint32_t tag, struct be_mcc_wrb **wrb, void *cmd_va);
/*ISCSI Functuions */ /*ISCSI Functuions */
int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
......
...@@ -690,11 +690,9 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, ...@@ -690,11 +690,9 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba) static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba)
{ {
int rc; int rc;
unsigned int tag, wrb_num; unsigned int tag;
unsigned short status, extd_status;
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct be_cmd_hba_name *resp; struct be_cmd_hba_name *resp;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
tag = be_cmd_get_initname(phba); tag = be_cmd_get_initname(phba);
if (!tag) { if (!tag) {
...@@ -702,26 +700,16 @@ static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba) ...@@ -702,26 +700,16 @@ static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba)
"BS_%d : Getting Initiator Name Failed\n"); "BS_%d : Getting Initiator Name Failed\n");
return -EBUSY; return -EBUSY;
} 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) { rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
if (rc) {
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BS_%d : MailBox Command Failed with " "BS_%d : Initiator Name MBX Failed\n");
"status = %d extd_status = %d\n", return rc;
status, extd_status);
free_mcc_tag(&phba->ctrl, tag);
return -EAGAIN;
} }
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
resp = embedded_payload(wrb); resp = embedded_payload(wrb);
rc = sprintf(buf, "%s\n", resp->initiator_name); rc = sprintf(buf, "%s\n", resp->initiator_name);
return rc; return rc;
...@@ -749,13 +737,12 @@ static void beiscsi_get_port_state(struct Scsi_Host *shost) ...@@ -749,13 +737,12 @@ static void beiscsi_get_port_state(struct Scsi_Host *shost)
*/ */
static int beiscsi_get_port_speed(struct Scsi_Host *shost) static int beiscsi_get_port_speed(struct Scsi_Host *shost)
{ {
unsigned int tag, wrb_num; int rc;
unsigned short status, extd_status; unsigned int tag;
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct be_cmd_ntwk_link_status_resp *resp; struct be_cmd_ntwk_link_status_resp *resp;
struct beiscsi_hba *phba = iscsi_host_priv(shost); struct beiscsi_hba *phba = iscsi_host_priv(shost);
struct iscsi_cls_host *ihost = shost->shost_data; struct iscsi_cls_host *ihost = shost->shost_data;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
tag = be_cmd_get_port_speed(phba); tag = be_cmd_get_port_speed(phba);
if (!tag) { if (!tag) {
...@@ -763,26 +750,14 @@ static int beiscsi_get_port_speed(struct Scsi_Host *shost) ...@@ -763,26 +750,14 @@ static int beiscsi_get_port_speed(struct Scsi_Host *shost)
"BS_%d : Getting Port Speed Failed\n"); "BS_%d : Getting Port Speed Failed\n");
return -EBUSY; return -EBUSY;
} else }
wait_event_interruptible(phba->ctrl.mcc_wait[tag], rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
phba->ctrl.mcc_numtag[tag]); if (rc) {
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) {
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BS_%d : MailBox Command Failed with " "BS_%d : Port Speed MBX Failed\n");
"status = %d extd_status = %d\n", return rc;
status, extd_status);
free_mcc_tag(&phba->ctrl, tag);
return -EAGAIN;
} }
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
resp = embedded_payload(wrb); resp = embedded_payload(wrb);
switch (resp->mac_speed) { switch (resp->mac_speed) {
...@@ -1034,12 +1009,10 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, ...@@ -1034,12 +1009,10 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
{ {
struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
struct beiscsi_hba *phba = beiscsi_ep->phba; struct beiscsi_hba *phba = beiscsi_ep->phba;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct tcp_connect_and_offload_out *ptcpcnct_out; struct tcp_connect_and_offload_out *ptcpcnct_out;
unsigned short status, extd_status;
struct be_dma_mem nonemb_cmd; struct be_dma_mem nonemb_cmd;
unsigned int tag, wrb_num; unsigned int tag;
int ret = -ENOMEM; int ret = -ENOMEM;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
...@@ -1091,27 +1064,18 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, ...@@ -1091,27 +1064,18 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma); nonemb_cmd.va, nonemb_cmd.dma);
return -EAGAIN; 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; ret = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; if (ret) {
if (status || extd_status) {
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BS_%d : mgmt_open_connection Failed" "BS_%d : mgmt_open_connection 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, pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma); nonemb_cmd.va, nonemb_cmd.dma);
goto free_ep; goto free_ep;
} else { }
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
ptcpcnct_out = embedded_payload(wrb); ptcpcnct_out = embedded_payload(wrb);
beiscsi_ep = ep->dd_data; beiscsi_ep = ep->dd_data;
...@@ -1119,7 +1083,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, ...@@ -1119,7 +1083,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
beiscsi_ep->cid_vld = 1; beiscsi_ep->cid_vld = 1;
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
"BS_%d : mgmt_open_connection Success\n"); "BS_%d : mgmt_open_connection Success\n");
}
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma); nonemb_cmd.va, nonemb_cmd.dma);
return 0; return 0;
...@@ -1223,11 +1187,9 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) ...@@ -1223,11 +1187,9 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag)
beiscsi_ep->ep_cid); beiscsi_ep->ep_cid);
ret = -EAGAIN; ret = -EAGAIN;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
} }
ret = beiscsi_mccq_compl(phba, tag, NULL, NULL);
return ret; return ret;
} }
...@@ -1288,12 +1250,9 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) ...@@ -1288,12 +1250,9 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : mgmt_invalidate_connection Failed for cid=%d\n", "BS_%d : mgmt_invalidate_connection Failed for cid=%d\n",
beiscsi_ep->ep_cid); beiscsi_ep->ep_cid);
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
} }
beiscsi_mccq_compl(phba, tag, NULL, NULL);
beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); beiscsi_close_conn(beiscsi_ep, tcp_upload_flag);
beiscsi_free_ep(beiscsi_ep); beiscsi_free_ep(beiscsi_ep);
beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
......
...@@ -267,11 +267,9 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc) ...@@ -267,11 +267,9 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
nonemb_cmd.va, nonemb_cmd.dma); nonemb_cmd.va, nonemb_cmd.dma);
return FAILED; return FAILED;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
} }
beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va);
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma); nonemb_cmd.va, nonemb_cmd.dma);
return iscsi_eh_abort(sc); return iscsi_eh_abort(sc);
...@@ -342,11 +340,9 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) ...@@ -342,11 +340,9 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma); nonemb_cmd.va, nonemb_cmd.dma);
return FAILED; return FAILED;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
} }
beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va);
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma); nonemb_cmd.va, nonemb_cmd.dma);
return iscsi_eh_device_reset(sc); return iscsi_eh_device_reset(sc);
...@@ -3871,12 +3867,9 @@ static void hwi_disable_intr(struct beiscsi_hba *phba) ...@@ -3871,12 +3867,9 @@ static void hwi_disable_intr(struct beiscsi_hba *phba)
static int beiscsi_get_boot_info(struct beiscsi_hba *phba) static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
{ {
struct be_cmd_get_session_resp *session_resp; struct be_cmd_get_session_resp *session_resp;
struct be_mcc_wrb *wrb;
struct be_dma_mem nonemb_cmd; struct be_dma_mem nonemb_cmd;
unsigned int tag, wrb_num; unsigned int tag;
unsigned short status, extd_status;
unsigned int s_handle; unsigned int s_handle;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
int ret = -ENOMEM; int ret = -ENOMEM;
/* Get the session handle of the boot target */ /* Get the session handle of the boot target */
...@@ -3909,25 +3902,16 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba) ...@@ -3909,25 +3902,16 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
" Failed\n"); " Failed\n");
goto boot_freemem; goto boot_freemem;
} else }
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; ret = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va);
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; if (ret) {
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BM_%d : beiscsi_get_session_info Failed" "BM_%d : beiscsi_get_session_info Failed");
" status = %d extd_status = %d\n",
status, extd_status);
free_mcc_tag(&phba->ctrl, tag);
goto boot_freemem; goto boot_freemem;
} }
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
session_resp = nonemb_cmd.va ; session_resp = nonemb_cmd.va ;
memcpy(&phba->boot_sess, &session_resp->session_info, memcpy(&phba->boot_sess, &session_resp->session_info,
...@@ -4643,9 +4627,13 @@ static int beiscsi_bsg_request(struct bsg_job *job) ...@@ -4643,9 +4627,13 @@ static int beiscsi_bsg_request(struct bsg_job *job)
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma); nonemb_cmd.va, nonemb_cmd.dma);
return -EAGAIN; return -EAGAIN;
} else }
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]); rc = wait_event_interruptible_timeout(
phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag],
msecs_to_jiffies(
BEISCSI_HOST_MBX_TIMEOUT));
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
free_mcc_tag(&phba->ctrl, tag); free_mcc_tag(&phba->ctrl, tag);
...@@ -4807,6 +4795,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, ...@@ -4807,6 +4795,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
/* Initialize Driver configuration Paramters */ /* Initialize Driver configuration Paramters */
beiscsi_hba_attrs_init(phba); beiscsi_hba_attrs_init(phba);
phba->fw_timeout = false;
switch (pcidev->device) { switch (pcidev->device) {
case BE_DEVICE_ID1: case BE_DEVICE_ID1:
case OC_DEVICE_ID1: case OC_DEVICE_ID1:
......
...@@ -279,7 +279,6 @@ struct beiscsi_hba { ...@@ -279,7 +279,6 @@ struct beiscsi_hba {
struct be_bus_address pci_pa; /* CSR */ struct be_bus_address pci_pa; /* CSR */
/* PCI representation of our HBA */ /* PCI representation of our HBA */
struct pci_dev *pcidev; struct pci_dev *pcidev;
unsigned int state;
unsigned short asic_revision; unsigned short asic_revision;
unsigned int num_cpus; unsigned int num_cpus;
unsigned int nxt_cqid; unsigned int nxt_cqid;
...@@ -334,6 +333,11 @@ struct beiscsi_hba { ...@@ -334,6 +333,11 @@ struct beiscsi_hba {
spinlock_t cid_lock; spinlock_t cid_lock;
} fw_config; } fw_config;
unsigned int state;
bool fw_timeout;
bool ue_detected;
struct delayed_work beiscsi_hw_check_task;
u8 mac_address[ETH_ALEN]; u8 mac_address[ETH_ALEN];
char wq_name[20]; char wq_name[20];
struct workqueue_struct *wq; /* The actuak work queue */ struct workqueue_struct *wq; /* The actuak work queue */
......
...@@ -575,13 +575,20 @@ unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba) ...@@ -575,13 +575,20 @@ unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
return status; return status;
} }
/*
* mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
* @phba: Driver priv structure
* @nonemb_cmd: Address of the MBX command issued
* @resp_buf: Buffer to copy the MBX cmd response
* @resp_buf_len: respone lenght to be copied
*
**/
static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba, static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
struct be_dma_mem *nonemb_cmd, void *resp_buf, struct be_dma_mem *nonemb_cmd, void *resp_buf,
int resp_buf_len) int resp_buf_len)
{ {
struct be_ctrl_info *ctrl = &phba->ctrl; struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb = wrb_from_mccq(phba); struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
unsigned short status, extd_status;
struct be_sge *sge; struct be_sge *sge;
unsigned int tag; unsigned int tag;
int rc = 0; int rc = 0;
...@@ -599,31 +606,25 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba, ...@@ -599,31 +606,25 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1); be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
sge->len = cpu_to_le32(nonemb_cmd->size); sge->len = cpu_to_le32(nonemb_cmd->size);
be_mcc_notify(phba); be_mcc_notify(phba);
spin_unlock(&ctrl->mbox_lock); spin_unlock(&ctrl->mbox_lock);
wait_event_interruptible(phba->ctrl.mcc_wait[tag], rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va);
phba->ctrl.mcc_numtag[tag]); if (rc) {
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BG_%d : mgmt_exec_nonemb_cmd Failed status = %d" "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
"extd_status = %d\n", status, extd_status);
rc = -EIO; rc = -EIO;
goto free_tag; goto free_cmd;
} }
if (resp_buf) if (resp_buf)
memcpy(resp_buf, nonemb_cmd->va, resp_buf_len); memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
free_tag:
free_mcc_tag(&phba->ctrl, tag);
free_cmd: free_cmd:
pci_free_consistent(ctrl->pdev, nonemb_cmd->size, pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
nonemb_cmd->va, nonemb_cmd->dma); nonemb_cmd->va, nonemb_cmd->dma);
...@@ -1009,10 +1010,9 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba, ...@@ -1009,10 +1010,9 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
{ {
struct be_cmd_get_boot_target_resp *boot_resp; struct be_cmd_get_boot_target_resp *boot_resp;
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
unsigned int tag, wrb_num; unsigned int tag;
uint8_t boot_retry = 3; uint8_t boot_retry = 3;
unsigned short status, extd_status; int rc;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
do { do {
/* Get the Boot Target Session Handle and Count*/ /* Get the Boot Target Session Handle and Count*/
...@@ -1022,24 +1022,16 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba, ...@@ -1022,24 +1022,16 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
"BG_%d : Getting Boot Target Info Failed\n"); "BG_%d : Getting Boot Target Info Failed\n");
return -EAGAIN; 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; rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; if (rc) {
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BG_%d : mgmt_get_boot_target Failed" "BG_%d : MBX CMD get_boot_target Failed\n");
" status = %d extd_status = %d\n",
status, extd_status);
free_mcc_tag(&phba->ctrl, tag);
return -EBUSY; return -EBUSY;
} }
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
boot_resp = embedded_payload(wrb); boot_resp = embedded_payload(wrb);
/* Check if the there are any Boot targets configured */ /* Check if the there are any Boot targets configured */
...@@ -1064,24 +1056,15 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba, ...@@ -1064,24 +1056,15 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BG_%d : mgmt_reopen_session Failed\n"); "BG_%d : mgmt_reopen_session Failed\n");
return -EAGAIN; 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; rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; if (rc) {
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BG_%d : mgmt_reopen_session Failed" "BG_%d : mgmt_reopen_session Failed");
" status = %d extd_status = %d\n", return rc;
status, extd_status);
free_mcc_tag(&phba->ctrl, tag);
return -EBUSY;
} }
free_mcc_tag(&phba->ctrl, tag);
} while (--boot_retry); } while (--boot_retry);
/* Couldn't log into the boot target */ /* Couldn't log into the boot target */
...@@ -1106,8 +1089,9 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba, ...@@ -1106,8 +1089,9 @@ int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
int mgmt_set_vlan(struct beiscsi_hba *phba, int mgmt_set_vlan(struct beiscsi_hba *phba,
uint16_t vlan_tag) uint16_t vlan_tag)
{ {
unsigned int tag, wrb_num; int rc;
unsigned short status, extd_status; unsigned int tag;
struct be_mcc_wrb *wrb = NULL;
tag = be_cmd_set_vlan(phba, vlan_tag); tag = be_cmd_set_vlan(phba, vlan_tag);
if (!tag) { if (!tag) {
...@@ -1115,26 +1099,16 @@ int mgmt_set_vlan(struct beiscsi_hba *phba, ...@@ -1115,26 +1099,16 @@ int mgmt_set_vlan(struct beiscsi_hba *phba,
(BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX), (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
"BG_%d : VLAN Setting Failed\n"); "BG_%d : VLAN Setting Failed\n");
return -EBUSY; return -EBUSY;
} 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) { rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
if (rc) {
beiscsi_log(phba, KERN_ERR, beiscsi_log(phba, KERN_ERR,
(BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX), (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
"BS_%d : status : %d extd_status : %d\n", "BS_%d : VLAN MBX Cmd Failed\n");
status, extd_status); return rc;
free_mcc_tag(&phba->ctrl, tag);
return -EAGAIN;
} }
return rc;
free_mcc_tag(&phba->ctrl, tag);
return 0;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment