diff options
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/Kconfig | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be.h | 6 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 116 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 27 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 199 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 333 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 29 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 64 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.h | 19 |
10 files changed, 512 insertions, 285 deletions
diff --git a/drivers/scsi/be2iscsi/Kconfig b/drivers/scsi/be2iscsi/Kconfig index 2952fcd008ea..84c275fb9f6b 100644 --- a/drivers/scsi/be2iscsi/Kconfig +++ b/drivers/scsi/be2iscsi/Kconfig @@ -1,6 +1,6 @@ config BE2ISCSI tristate "ServerEngines' 10Gbps iSCSI - BladeEngine 2" - depends on PCI && SCSI + depends on PCI && SCSI && NET select SCSI_ISCSI_ATTRS help diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index 136b49cea791..1cb8a5e85c7f 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h @@ -128,8 +128,8 @@ struct be_ctrl_info { #define mcc_timeout 120000 /* 5s timeout */ /* Returns number of pages spanned by the data starting at the given addr */ -#define PAGES_4K_SPANNED(_address, size) \ - ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \ +#define PAGES_4K_SPANNED(_address, size) \ + ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \ (size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K)) /* Byte offset into the page corresponding to given address */ @@ -137,7 +137,7 @@ struct be_ctrl_info { ((size_t)(addr) & (PAGE_SIZE_4K-1)) /* Returns bit offset within a DWORD of a bitfield */ -#define AMAP_BIT_OFFSET(_struct, field) \ +#define AMAP_BIT_OFFSET(_struct, field) \ (((size_t)&(((_struct *)0)->field))%32) /* Returns the bit mask of the field that is NOT shifted into location. */ diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index cda6642c7368..7c7537335c88 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -19,6 +19,86 @@ #include "be_mgmt.h" #include "be_main.h" +int beiscsi_pci_soft_reset(struct beiscsi_hba *phba) +{ + u32 sreset; + u8 *pci_reset_offset = 0; + u8 *pci_online0_offset = 0; + u8 *pci_online1_offset = 0; + u32 pconline0 = 0; + u32 pconline1 = 0; + u32 i; + + pci_reset_offset = (u8 *)phba->pci_va + BE2_SOFT_RESET; + pci_online0_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE0; + pci_online1_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE1; + sreset = readl((void *)pci_reset_offset); + sreset |= BE2_SET_RESET; + writel(sreset, (void *)pci_reset_offset); + + i = 0; + while (sreset & BE2_SET_RESET) { + if (i > 64) + break; + msleep(100); + sreset = readl((void *)pci_reset_offset); + i++; + } + + if (sreset & BE2_SET_RESET) { + printk(KERN_ERR "Soft Reset did not deassert\n"); + return -EIO; + } + pconline1 = BE2_MPU_IRAM_ONLINE; + writel(pconline0, (void *)pci_online0_offset); + writel(pconline1, (void *)pci_online1_offset); + + sreset = BE2_SET_RESET; + writel(sreset, (void *)pci_reset_offset); + + i = 0; + while (sreset & BE2_SET_RESET) { + if (i > 64) + break; + msleep(1); + sreset = readl((void *)pci_reset_offset); + i++; + } + if (sreset & BE2_SET_RESET) { + printk(KERN_ERR "MPU Online Soft Reset did not deassert\n"); + return -EIO; + } + return 0; +} + +int be_chk_reset_complete(struct beiscsi_hba *phba) +{ + unsigned int num_loop; + u8 *mpu_sem = 0; + u32 status; + + num_loop = 1000; + mpu_sem = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE; + msleep(5000); + + while (num_loop) { + status = readl((void *)mpu_sem); + + if ((status & 0x80000000) || (status & 0x0000FFFF) == 0xC000) + break; + msleep(60); + num_loop--; + } + + if ((status & 0x80000000) || (!num_loop)) { + printk(KERN_ERR "Failed in be_chk_reset_complete" + "status = 0x%x\n", status); + return -EIO; + } + + return 0; +} + void be_mcc_notify(struct beiscsi_hba *phba) { struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; @@ -98,7 +178,7 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl, dev_err(&ctrl->pdev->dev, "error in cmd completion: status(compl/extd)=%d/%d\n", compl_status, extd_status); - return -1; + return -EBUSY; } return 0; } @@ -151,20 +231,20 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba, { switch (evt->port_link_status) { case ASYNC_EVENT_LINK_DOWN: - SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n", - evt->physical_port); + SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d\n", + evt->physical_port); phba->state |= BE_ADAPTER_LINK_DOWN; iscsi_host_for_each_session(phba->shost, be2iscsi_fail_session); break; case ASYNC_EVENT_LINK_UP: phba->state = BE_ADAPTER_UP; - SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n", + SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d\n", evt->physical_port); break; default: SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on" - "Physical Port %d \n", + "Physical Port %d\n", evt->port_link_status, evt->physical_port); } @@ -199,7 +279,7 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba) else SE_DEBUG(DBG_LVL_1, " Unsupported Async Event, flags" - " = 0x%08x \n", compl->flags); + " = 0x%08x\n", compl->flags); } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { status = be_mcc_compl_process(ctrl, compl); @@ -231,7 +311,7 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba) } if (i == mcc_timeout) { dev_err(&phba->pcidev->dev, "mccq poll timed out\n"); - return -1; + return -EBUSY; } return 0; } @@ -257,7 +337,7 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) if (cnt > 6000000) { dev_err(&ctrl->pdev->dev, "mbox_db poll timed out\n"); - return -1; + return -EBUSY; } if (cnt > 50) { @@ -286,7 +366,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl) status = be_mbox_db_ready_wait(ctrl); if (status != 0) { - SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed 1\n"); + SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n"); return status; } val = 0; @@ -297,19 +377,19 @@ int be_mbox_notify(struct be_ctrl_info *ctrl) status = be_mbox_db_ready_wait(ctrl); if (status != 0) { - SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed 2\n"); + SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n"); return status; } if (be_mcc_compl_is_new(compl)) { status = be_mcc_compl_process(ctrl, &mbox->compl); be_mcc_compl_use(compl); if (status) { - SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process \n"); + SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process\n"); return status; } } else { dev_err(&ctrl->pdev->dev, "invalid mailbox completion\n"); - return -1; + return -EBUSY; } return 0; } @@ -355,7 +435,7 @@ static int be_mbox_notify_wait(struct beiscsi_hba *phba) return status; } else { dev_err(&phba->pcidev->dev, "invalid mailbox completion\n"); - return -1; + return -EBUSY; } return 0; } @@ -500,7 +580,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl) status = be_mbox_notify(ctrl); if (status) - SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed \n"); + SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed\n"); spin_unlock(&ctrl->mbox_lock); return status; @@ -517,7 +597,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, void *ctxt = &req->context; int status; - SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create \n"); + SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create\n"); spin_lock(&ctrl->mbox_lock); memset(wrb, 0, sizeof(*wrb)); @@ -550,7 +630,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, cq->id = le16_to_cpu(resp->cq_id); cq->created = true; } else - SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x \n", + SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x\n", status); spin_unlock(&ctrl->mbox_lock); @@ -619,7 +699,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, u8 subsys = 0, opcode = 0; int status; - SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy \n"); + SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy\n"); spin_lock(&ctrl->mbox_lock); memset(wrb, 0, sizeof(*wrb)); be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); @@ -652,7 +732,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, default: spin_unlock(&ctrl->mbox_lock); BUG(); - return -1; + return -ENXIO; } be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req)); if (queue_type != QTYPE_SGL) diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 49fcc787ee8b..40641d0845f4 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h @@ -47,8 +47,8 @@ struct be_mcc_wrb { #define CQE_FLAGS_VALID_MASK (1 << 31) #define CQE_FLAGS_ASYNC_MASK (1 << 30) -#define CQE_FLAGS_COMPLETED_MASK (1 << 28) -#define CQE_FLAGS_CONSUMED_MASK (1 << 27) +#define CQE_FLAGS_COMPLETED_MASK (1 << 28) +#define CQE_FLAGS_CONSUMED_MASK (1 << 27) /* Completion Status */ #define MCC_STATUS_SUCCESS 0x0 @@ -56,7 +56,7 @@ struct be_mcc_wrb { #define CQE_STATUS_COMPL_MASK 0xFFFF #define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */ #define CQE_STATUS_EXTD_MASK 0xFFFF -#define CQE_STATUS_EXTD_SHIFT 0 /* bits 0 - 15 */ +#define CQE_STATUS_EXTD_SHIFT 16 /* bits 0 - 15 */ struct be_mcc_compl { u32 status; /* dword 0 */ @@ -143,14 +143,14 @@ struct be_mcc_mailbox { */ #define OPCODE_COMMON_CQ_CREATE 12 #define OPCODE_COMMON_EQ_CREATE 13 -#define OPCODE_COMMON_MCC_CREATE 21 -#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32 +#define OPCODE_COMMON_MCC_CREATE 21 +#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32 #define OPCODE_COMMON_GET_FW_VERSION 35 #define OPCODE_COMMON_MODIFY_EQ_DELAY 41 #define OPCODE_COMMON_FIRMWARE_CONFIG 42 -#define OPCODE_COMMON_MCC_DESTROY 53 -#define OPCODE_COMMON_CQ_DESTROY 54 -#define OPCODE_COMMON_EQ_DESTROY 55 +#define OPCODE_COMMON_MCC_DESTROY 53 +#define OPCODE_COMMON_CQ_DESTROY 54 +#define OPCODE_COMMON_EQ_DESTROY 55 #define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG 58 #define OPCODE_COMMON_FUNCTION_RESET 61 @@ -164,9 +164,9 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG 7 #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 +#define OPCODE_COMMON_ISCSI_DEFQ_DESTROY 65 #define OPCODE_COMMON_ISCSI_WRBQ_CREATE 66 -#define OPCODE_COMMON_ISCSI_WRBQ_DESTROY 67 +#define OPCODE_COMMON_ISCSI_WRBQ_DESTROY 67 struct be_cmd_req_hdr { u8 opcode; /* dword 0 */ @@ -423,7 +423,7 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba, struct be_queue_info *cq); int be_poll_mcc(struct be_ctrl_info *ctrl); -unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, +int mgmt_check_supported_fw(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba); unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba); void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); @@ -875,7 +875,7 @@ struct be_fw_cfg { */ #define UNSOL_HDR_NOTIFY 28 /* Unsolicited header notify.*/ #define UNSOL_DATA_NOTIFY 29 /* Unsolicited data notify.*/ -#define UNSOL_DATA_DIGEST_ERROR_NOTIFY 30 /* Unsolicited data digest +#define UNSOL_DATA_DIGEST_ERROR_NOTIFY 30 /* Unsolicited data digest * error notify. */ #define DRIVERMSG_NOTIFY 31 /* TCP acknowledge based @@ -901,6 +901,9 @@ struct be_fw_cfg { * the cxn */ +int beiscsi_pci_soft_reset(struct beiscsi_hba *phba); +int be_chk_reset_complete(struct beiscsi_hba *phba); + void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, bool embedded, u8 sge_cnt); diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index c3928cb8b042..6d63e7b312cf 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -52,7 +52,7 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep, SE_DEBUG(DBG_LVL_8, "In beiscsi_session_create\n"); if (!ep) { - SE_DEBUG(DBG_LVL_1, "beiscsi_session_create: invalid ep \n"); + SE_DEBUG(DBG_LVL_1, "beiscsi_session_create: invalid ep\n"); return NULL; } beiscsi_ep = ep->dd_data; @@ -157,7 +157,7 @@ static int beiscsi_bindconn_cid(struct beiscsi_hba *phba, "Connection table already occupied. Detected clash\n"); return -EINVAL; } else { - SE_DEBUG(DBG_LVL_8, "phba->conn_table[%d]=%p(beiscsi_conn) \n", + SE_DEBUG(DBG_LVL_8, "phba->conn_table[%d]=%p(beiscsi_conn)\n", cid, beiscsi_conn); phba->conn_table[cid] = beiscsi_conn; } @@ -196,7 +196,7 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, if (beiscsi_ep->phba != phba) { SE_DEBUG(DBG_LVL_8, - "beiscsi_ep->hba=%p not equal to phba=%p \n", + "beiscsi_ep->hba=%p not equal to phba=%p\n", beiscsi_ep->phba, phba); return -EEXIST; } @@ -204,7 +204,7 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid; beiscsi_conn->ep = beiscsi_ep; beiscsi_ep->conn = beiscsi_conn; - SE_DEBUG(DBG_LVL_8, "beiscsi_conn=%p conn=%p ep_cid=%d \n", + SE_DEBUG(DBG_LVL_8, "beiscsi_conn=%p conn=%p ep_cid=%d\n", beiscsi_conn, conn, beiscsi_ep->ep_cid); return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid); } @@ -230,7 +230,7 @@ int beiscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, if (!beiscsi_ep) { SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_get_param , no beiscsi_ep\n"); - return -1; + return -ENODEV; } switch (param) { @@ -277,6 +277,10 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, if (session->max_burst > 262144) session->max_burst = 262144; break; + case ISCSI_PARAM_MAX_XMIT_DLENGTH: + if ((conn->max_xmit_dlength > 65536) || + (conn->max_xmit_dlength == 0)) + conn->max_xmit_dlength = 65536; default: return 0; } @@ -308,8 +312,8 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, case ISCSI_HOST_PARAM_HWADDRESS: tag = be_cmd_get_mac_addr(phba); if (!tag) { - SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed \n"); - return -1; + SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n"); + return -EAGAIN; } else wait_event_interruptible(phba->ctrl.mcc_wait[tag], phba->ctrl.mcc_numtag[tag]); @@ -319,10 +323,10 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, 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 = %d extd_status = %d\n", status, extd_status); free_mcc_tag(&phba->ctrl, tag); - return -1; + return -EAGAIN; } else { wrb = queue_get_wrb(mccq, wrb_num); free_mcc_tag(&phba->ctrl, tag); @@ -442,6 +446,31 @@ static int beiscsi_get_cid(struct beiscsi_hba *phba) } /** + * beiscsi_put_cid - Free the cid + * @phba: The phba for which the cid is being freed + * @cid: The cid to free + */ +static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) +{ + phba->avlbl_cids++; + phba->cid_array[phba->cid_free++] = cid; + if (phba->cid_free == phba->params.cxns_per_ctrl) + phba->cid_free = 0; +} + +/** + * beiscsi_free_ep - free endpoint + * @ep: pointer to iscsi endpoint structure + */ +static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) +{ + struct beiscsi_hba *phba = beiscsi_ep->phba; + + beiscsi_put_cid(phba, beiscsi_ep->ep_cid); + beiscsi_ep->phba = NULL; +} + +/** * beiscsi_open_conn - Ask FW to open a TCP connection * @ep: endpoint to be used * @src_addr: The source IP address @@ -459,8 +488,9 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, struct be_mcc_wrb *wrb; struct tcp_connect_and_offload_out *ptcpcnct_out; unsigned short status, extd_status; + struct be_dma_mem nonemb_cmd; unsigned int tag, wrb_num; - int ret = -1; + int ret = -ENOMEM; SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n"); beiscsi_ep->ep_cid = beiscsi_get_cid(phba); @@ -468,22 +498,39 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, SE_DEBUG(DBG_LVL_1, "No free cid available\n"); return ret; } - SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d ", + SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d\n", beiscsi_ep->ep_cid); phba->ep_array[beiscsi_ep->ep_cid - phba->fw_config.iscsi_cid_start] = ep; if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start + phba->params.cxns_per_ctrl * 2)) { SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n"); - return ret; + beiscsi_put_cid(phba, beiscsi_ep->ep_cid); + goto free_ep; } beiscsi_ep->cid_vld = 0; - tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep); + nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, + sizeof(struct tcp_connect_and_offload_in), + &nonemb_cmd.dma); + if (nonemb_cmd.va == NULL) { + SE_DEBUG(DBG_LVL_1, + "Failed to allocate memory for mgmt_open_connection" + "\n"); + beiscsi_put_cid(phba, beiscsi_ep->ep_cid); + return -ENOMEM; + } + nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in); + memset(nonemb_cmd.va, 0, nonemb_cmd.size); + tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd); if (!tag) { SE_DEBUG(DBG_LVL_1, - "mgmt_open_connection Failed for cid=%d \n", + "mgmt_open_connection Failed for cid=%d\n", beiscsi_ep->ep_cid); + beiscsi_put_cid(phba, beiscsi_ep->ep_cid); + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); + return -EAGAIN; } else { wait_event_interruptible(phba->ctrl.mcc_wait[tag], phba->ctrl.mcc_numtag[tag]); @@ -493,46 +540,31 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; if (status || extd_status) { SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed" - " status = %d extd_status = %d \n", + " status = %d extd_status = %d\n", status, extd_status); + beiscsi_put_cid(phba, beiscsi_ep->ep_cid); free_mcc_tag(&phba->ctrl, tag); - return -1; + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); + 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->fw_handle = ptcpcnct_out->connection_handle; beiscsi_ep->cid_vld = 1; SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n"); } + beiscsi_put_cid(phba, beiscsi_ep->ep_cid); + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); return 0; -} - -/** - * beiscsi_put_cid - Free the cid - * @phba: The phba for which the cid is being freed - * @cid: The cid to free - */ -static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) -{ - phba->avlbl_cids++; - phba->cid_array[phba->cid_free++] = cid; - if (phba->cid_free == phba->params.cxns_per_ctrl) - phba->cid_free = 0; -} - -/** - * beiscsi_free_ep - free endpoint - * @ep: pointer to iscsi endpoint structure - */ -static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) -{ - struct beiscsi_hba *phba = beiscsi_ep->phba; - beiscsi_put_cid(phba, beiscsi_ep->ep_cid); - beiscsi_ep->phba = NULL; +free_ep: + beiscsi_free_ep(beiscsi_ep); + return -EBUSY; } /** @@ -552,18 +584,18 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, struct iscsi_endpoint *ep; int ret; - SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_connect \n"); + SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_connect\n"); if (shost) phba = iscsi_host_priv(shost); else { ret = -ENXIO; - SE_DEBUG(DBG_LVL_1, "shost is NULL \n"); + SE_DEBUG(DBG_LVL_1, "shost is NULL\n"); return ERR_PTR(ret); } if (phba->state != BE_ADAPTER_UP) { ret = -EBUSY; - SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP \n"); + SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP\n"); return ERR_PTR(ret); } @@ -576,16 +608,16 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, beiscsi_ep = ep->dd_data; beiscsi_ep->phba = phba; beiscsi_ep->openiscsi_ep = ep; - if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) { - SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n"); - ret = -ENOMEM; + ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking); + if (ret) { + SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn\n"); goto free_ep; } return ep; free_ep: - beiscsi_free_ep(beiscsi_ep); + iscsi_destroy_endpoint(ep); return ERR_PTR(ret); } @@ -620,9 +652,9 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag); if (!tag) { - SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", + SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x\n", beiscsi_ep->ep_cid); - ret = -1; + ret = -EAGAIN; } else { wait_event_interruptible(phba->ctrl.mcc_wait[tag], phba->ctrl.mcc_numtag[tag]); @@ -632,30 +664,6 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) } /** - * beiscsi_ep_disconnect - Tears down the TCP connection - * @ep: endpoint to be used - * - * Tears down the TCP connection - */ -void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) -{ - struct beiscsi_conn *beiscsi_conn; - struct beiscsi_endpoint *beiscsi_ep; - struct beiscsi_hba *phba; - - beiscsi_ep = ep->dd_data; - phba = beiscsi_ep->phba; - SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n", - beiscsi_ep->ep_cid); - - if (beiscsi_ep->conn) { - beiscsi_conn = beiscsi_ep->conn; - iscsi_suspend_queue(beiscsi_conn->conn); - } - -} - -/** * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table * @phba: The phba instance * @cid: The cid to free @@ -666,50 +674,57 @@ static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba, if (phba->conn_table[cid]) phba->conn_table[cid] = NULL; else { - SE_DEBUG(DBG_LVL_8, "Connection table Not occupied. \n"); + SE_DEBUG(DBG_LVL_8, "Connection table Not occupied.\n"); return -EINVAL; } return 0; } /** - * beiscsi_conn_stop - Invalidate and stop the connection - * @cls_conn: pointer to get iscsi_conn - * @flag: The type of connection closure + * beiscsi_ep_disconnect - Tears down the TCP connection + * @ep: endpoint to be used + * + * Tears down the TCP connection */ -void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) +void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) { - struct iscsi_conn *conn = cls_conn->dd_data; - struct beiscsi_conn *beiscsi_conn = conn->dd_data; + struct beiscsi_conn *beiscsi_conn; struct beiscsi_endpoint *beiscsi_ep; - struct iscsi_session *session = conn->session; - struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); - struct beiscsi_hba *phba = iscsi_host_priv(shost); + struct beiscsi_hba *phba; unsigned int tag; unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; - beiscsi_ep = beiscsi_conn->ep; - if (!beiscsi_ep) { - SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n"); + beiscsi_ep = ep->dd_data; + phba = beiscsi_ep->phba; + SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n", + beiscsi_ep->ep_cid); + + if (!beiscsi_ep->conn) { + SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect, no " + "beiscsi_ep\n"); return; } - SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop ep_cid = %d\n", - beiscsi_ep->ep_cid); + beiscsi_conn = beiscsi_ep->conn; + iscsi_suspend_queue(beiscsi_conn->conn); + + SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect ep_cid = %d\n", + beiscsi_ep->ep_cid); + tag = mgmt_invalidate_connection(phba, beiscsi_ep, beiscsi_ep->ep_cid, 1, savecfg_flag); if (!tag) { SE_DEBUG(DBG_LVL_1, - "mgmt_invalidate_connection Failed for cid=%d \n", + "mgmt_invalidate_connection Failed for cid=%d\n", 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_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL); beiscsi_free_ep(beiscsi_ep); - iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); - iscsi_conn_stop(cls_conn, flag); + iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); } diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h index 1f512c28cbf9..870cdb2a73e4 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.h +++ b/drivers/scsi/be2iscsi/be_iscsi.h @@ -59,8 +59,6 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn); -void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag); - struct iscsi_endpoint *beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, int non_blocking); diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index dd5b105f8f47..7436c5ad5697 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -41,6 +41,8 @@ static unsigned int be_iopoll_budget = 10; static unsigned int be_max_phys_size = 64; static unsigned int enable_msix = 1; +static unsigned int gcrashmode = 0; +static unsigned int num_hba = 0; MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); @@ -69,6 +71,7 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc) struct beiscsi_hba *phba; struct iscsi_session *session; struct invalidate_command_table *inv_tbl; + struct be_dma_mem nonemb_cmd; unsigned int cid, tag, num_invalidate; cls_session = starget_to_session(scsi_target(sc->device)); @@ -99,18 +102,34 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc) inv_tbl->cid = cid; inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index; num_invalidate = 1; - tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid); + nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, + sizeof(struct invalidate_commands_params_in), + &nonemb_cmd.dma); + if (nonemb_cmd.va == NULL) { + SE_DEBUG(DBG_LVL_1, + "Failed to allocate memory for" + "mgmt_invalidate_icds\n"); + return FAILED; + } + nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); + + tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, + cid, &nonemb_cmd); if (!tag) { shost_printk(KERN_WARNING, phba->shost, "mgmt_invalidate_icds could not be" " submitted\n"); + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); + return FAILED; } else { wait_event_interruptible(phba->ctrl.mcc_wait[tag], phba->ctrl.mcc_numtag[tag]); free_mcc_tag(&phba->ctrl, tag); } - + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); return iscsi_eh_abort(sc); } @@ -124,6 +143,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) struct iscsi_session *session; struct iscsi_cls_session *cls_session; struct invalidate_command_table *inv_tbl; + struct be_dma_mem nonemb_cmd; unsigned int cid, tag, i, num_invalidate; int rc = FAILED; @@ -158,18 +178,33 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) spin_unlock_bh(&session->lock); inv_tbl = phba->inv_tbl; - tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid); + nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, + sizeof(struct invalidate_commands_params_in), + &nonemb_cmd.dma); + if (nonemb_cmd.va == NULL) { + SE_DEBUG(DBG_LVL_1, + "Failed to allocate memory for" + "mgmt_invalidate_icds\n"); + return FAILED; + } + nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); + memset(nonemb_cmd.va, 0, nonemb_cmd.size); + tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, + cid, &nonemb_cmd); if (!tag) { shost_printk(KERN_WARNING, phba->shost, "mgmt_invalidate_icds could not be" " submitted\n"); + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); return FAILED; } else { wait_event_interruptible(phba->ctrl.mcc_wait[tag], phba->ctrl.mcc_numtag[tag]); free_mcc_tag(&phba->ctrl, tag); } - + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); return iscsi_eh_device_reset(sc); unlock: spin_unlock_bh(&session->lock); @@ -216,7 +251,7 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev) shost = iscsi_host_alloc(&beiscsi_sht, sizeof(*phba), 0); if (!shost) { dev_err(&pcidev->dev, "beiscsi_hba_alloc -" - "iscsi_host_alloc failed \n"); + "iscsi_host_alloc failed\n"); return NULL; } shost->dma_boundary = pcidev->dma_mask; @@ -371,7 +406,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba) + BE2_TMFS) / 512) + 1) * 512; phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024) ? 1024 : phba->params.num_eq_entries; - SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d \n", + SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d\n", phba->params.num_eq_entries); phba->params.num_cq_entries = (((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2 @@ -616,7 +651,7 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba) struct pci_dev *pcidev = phba->pcidev; struct hwi_controller *phwi_ctrlr; struct hwi_context_memory *phwi_context; - int ret, msix_vec, i = 0; + int ret, msix_vec, i, j; char desc[32]; phwi_ctrlr = phba->phwi_ctrlr; @@ -628,10 +663,25 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba) msix_vec = phba->msix_entries[i].vector; ret = request_irq(msix_vec, be_isr_msix, 0, desc, &phwi_context->be_eq[i]); + if (ret) { + shost_printk(KERN_ERR, phba->shost, + "beiscsi_init_irqs-Failed to" + "register msix for i = %d\n", i); + if (!i) + return ret; + goto free_msix_irqs; + } } msix_vec = phba->msix_entries[i].vector; ret = request_irq(msix_vec, be_isr_mcc, 0, "beiscsi_msix_mcc", &phwi_context->be_eq[i]); + if (ret) { + shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-" + "Failed to register beiscsi_msix_mcc\n"); + i++; + goto free_msix_irqs; + } + } else { ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED, "beiscsi", phba); @@ -642,6 +692,10 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba) } } return 0; +free_msix_irqs: + for (j = i - 1; j == 0; j++) + free_irq(msix_vec, &phwi_context->be_eq[j]); + return ret; } static void hwi_ring_cq_db(struct beiscsi_hba *phba, @@ -692,7 +746,7 @@ beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn, break; default: shost_printk(KERN_WARNING, phba->shost, - "Unrecognized opcode 0x%x in async msg \n", + "Unrecognized opcode 0x%x in async msg\n", (ppdu-> dw[offsetof(struct amap_pdu_base, opcode) / 32] & PDUBASE_OPCODE_MASK)); @@ -711,7 +765,7 @@ static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba) if (phba->io_sgl_hndl_avbl) { SE_DEBUG(DBG_LVL_8, - "In alloc_io_sgl_handle,io_sgl_alloc_index=%d \n", + "In alloc_io_sgl_handle,io_sgl_alloc_index=%d\n", phba->io_sgl_alloc_index); psgl_handle = phba->io_sgl_hndl_base[phba-> io_sgl_alloc_index]; @@ -730,7 +784,7 @@ static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba) static void free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) { - SE_DEBUG(DBG_LVL_8, "In free_,io_sgl_free_index=%d \n", + SE_DEBUG(DBG_LVL_8, "In free_,io_sgl_free_index=%d\n", phba->io_sgl_free_index); if (phba->io_sgl_hndl_base[phba->io_sgl_free_index]) { /* @@ -739,7 +793,7 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) */ SE_DEBUG(DBG_LVL_8, "Double Free in IO SGL io_sgl_free_index=%d," - "value there=%p \n", phba->io_sgl_free_index, + "value there=%p\n", phba->io_sgl_free_index, phba->io_sgl_hndl_base[phba->io_sgl_free_index]); return; } @@ -804,7 +858,7 @@ free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context, SE_DEBUG(DBG_LVL_8, "FREE WRB: pwrb_handle=%p free_index=0x%x" - "wrb_handles_available=%d \n", + "wrb_handles_available=%d\n", pwrb_handle, pwrb_context->free_index, pwrb_context->wrb_handles_available); } @@ -816,7 +870,7 @@ static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba) if (phba->eh_sgl_hndl_avbl) { psgl_handle = phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index]; phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index] = NULL; - SE_DEBUG(DBG_LVL_8, "mgmt_sgl_alloc_index=%d=0x%x \n", + SE_DEBUG(DBG_LVL_8, "mgmt_sgl_alloc_index=%d=0x%x\n", phba->eh_sgl_alloc_index, phba->eh_sgl_alloc_index); phba->eh_sgl_hndl_avbl--; if (phba->eh_sgl_alloc_index == @@ -834,7 +888,7 @@ void free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) { - SE_DEBUG(DBG_LVL_8, "In free_mgmt_sgl_handle,eh_sgl_free_index=%d \n", + SE_DEBUG(DBG_LVL_8, "In free_mgmt_sgl_handle,eh_sgl_free_index=%d\n", phba->eh_sgl_free_index); if (phba->eh_sgl_hndl_base[phba->eh_sgl_free_index]) { /* @@ -842,7 +896,7 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle) * failed in xmit_task or alloc_pdu. */ SE_DEBUG(DBG_LVL_8, - "Double Free in eh SGL ,eh_sgl_free_index=%d \n", + "Double Free in eh SGL ,eh_sgl_free_index=%d\n", phba->eh_sgl_free_index); return; } @@ -1081,7 +1135,7 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, case HWH_TYPE_LOGIN: SE_DEBUG(DBG_LVL_1, "\t\t No HWH_TYPE_LOGIN Expected in hwi_complete_cmd" - "- Solicited path \n"); + "- Solicited path\n"); break; case HWH_TYPE_NOP: @@ -1164,7 +1218,7 @@ hwi_get_async_handle(struct beiscsi_hba *phba, default: pbusy_list = NULL; shost_printk(KERN_WARNING, phba->shost, - "Unexpected code=%d \n", + "Unexpected code=%d\n", pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, code) / 32] & PDUCQE_CODE_MASK); return NULL; @@ -1552,7 +1606,7 @@ static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba) else SE_DEBUG(DBG_LVL_1, " Unsupported Async Event, flags" - " = 0x%08x \n", mcc_compl->flags); + " = 0x%08x\n", mcc_compl->flags); } else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) { be_mcc_compl_process_isr(&phba->ctrl, mcc_compl); atomic_dec(&phba->ctrl.mcc_obj.q.used); @@ -1611,7 +1665,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) hwi_complete_cmd(beiscsi_conn, phba, sol); break; case DRIVERMSG_NOTIFY: - SE_DEBUG(DBG_LVL_8, "Received DRIVERMSG_NOTIFY \n"); + SE_DEBUG(DBG_LVL_8, "Received DRIVERMSG_NOTIFY\n"); dmsg = (struct dmsg_cqe *)sol; hwi_complete_drvr_msgs(beiscsi_conn, phba, sol); break; @@ -1782,9 +1836,9 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg, sg_len = sg_dma_len(sg); addr = (u64) sg_dma_address(sg); AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb, - (addr & 0xFFFFFFFF)); + ((u32)(addr & 0xFFFFFFFF))); AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb, - (addr >> 32)); + ((u32)(addr >> 32))); AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb, sg_len); sge_len = sg_len; @@ -1794,9 +1848,9 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg, sg_len = sg_dma_len(sg); addr = (u64) sg_dma_address(sg); AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_addr_lo, pwrb, - (addr & 0xFFFFFFFF)); + ((u32)(addr & 0xFFFFFFFF))); AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_addr_hi, pwrb, - (addr >> 32)); + ((u32)(addr >> 32))); AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_len, pwrb, sg_len); } @@ -1872,9 +1926,9 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task) addr = 0; } AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb, - (addr & 0xFFFFFFFF)); + ((u32)(addr & 0xFFFFFFFF))); AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb, - (addr >> 32)); + ((u32)(addr >> 32))); AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb, task->data_count); @@ -1904,9 +1958,9 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task) psgl++; if (task->data) { AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, - (addr & 0xFFFFFFFF)); + ((u32)(addr & 0xFFFFFFFF))); AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl, - (addr >> 32)); + ((u32)(addr >> 32))); } AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, 0x106); } @@ -2054,7 +2108,8 @@ free_mem: mem_descr->mem_array[j - 1].size, mem_descr->mem_array[j - 1]. virtual_address, - mem_descr->mem_array[j - 1]. + (unsigned long)mem_descr-> + mem_array[j - 1]. bus_address.u.a64.address); } if (i) { @@ -2223,10 +2278,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) if (mem_descr->mem_array[0].virtual_address) { SE_DEBUG(DBG_LVL_8, "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_BUF" - "va=%p \n", mem_descr->mem_array[0].virtual_address); + "va=%p\n", mem_descr->mem_array[0].virtual_address); } else shost_printk(KERN_WARNING, phba->shost, - "No Virtual address \n"); + "No Virtual address\n"); pasync_ctx->async_header.va_base = mem_descr->mem_array[0].virtual_address; @@ -2239,10 +2294,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) if (mem_descr->mem_array[0].virtual_address) { SE_DEBUG(DBG_LVL_8, "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_RING" - "va=%p \n", mem_descr->mem_array[0].virtual_address); + "va=%p\n", mem_descr->mem_array[0].virtual_address); } else shost_printk(KERN_WARNING, phba->shost, - "No Virtual address \n"); + "No Virtual address\n"); pasync_ctx->async_header.ring_base = mem_descr->mem_array[0].virtual_address; @@ -2251,10 +2306,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) if (mem_descr->mem_array[0].virtual_address) { SE_DEBUG(DBG_LVL_8, "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_HANDLE" - "va=%p \n", mem_descr->mem_array[0].virtual_address); + "va=%p\n", mem_descr->mem_array[0].virtual_address); } else shost_printk(KERN_WARNING, phba->shost, - "No Virtual address \n"); + "No Virtual address\n"); pasync_ctx->async_header.handle_base = mem_descr->mem_array[0].virtual_address; @@ -2266,10 +2321,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) if (mem_descr->mem_array[0].virtual_address) { SE_DEBUG(DBG_LVL_8, "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_BUF" - "va=%p \n", mem_descr->mem_array[0].virtual_address); + "va=%p\n", mem_descr->mem_array[0].virtual_address); } else shost_printk(KERN_WARNING, phba->shost, - "No Virtual address \n"); + "No Virtual address\n"); pasync_ctx->async_data.va_base = mem_descr->mem_array[0].virtual_address; pasync_ctx->async_data.pa_base.u.a64.address = @@ -2280,10 +2335,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) if (mem_descr->mem_array[0].virtual_address) { SE_DEBUG(DBG_LVL_8, "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_RING" - "va=%p \n", mem_descr->mem_array[0].virtual_address); + "va=%p\n", mem_descr->mem_array[0].virtual_address); } else shost_printk(KERN_WARNING, phba->shost, - "No Virtual address \n"); + "No Virtual address\n"); pasync_ctx->async_data.ring_base = mem_descr->mem_array[0].virtual_address; @@ -2292,7 +2347,7 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) mem_descr += HWI_MEM_ASYNC_DATA_HANDLE; if (!mem_descr->mem_array[0].virtual_address) shost_printk(KERN_WARNING, phba->shost, - "No Virtual address \n"); + "No Virtual address\n"); pasync_ctx->async_data.handle_base = mem_descr->mem_array[0].virtual_address; @@ -2364,7 +2419,7 @@ be_sgl_create_contiguous(void *virtual_address, WARN_ON(!sgl); sgl->va = virtual_address; - sgl->dma = physical_address; + sgl->dma = (unsigned long)physical_address; sgl->size = length; return 0; @@ -2447,7 +2502,7 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba, sizeof(struct be_eq_entry), eq_vaddress); if (ret) { shost_printk(KERN_ERR, phba->shost, - "be_fill_queue Failed for EQ \n"); + "be_fill_queue Failed for EQ\n"); goto create_eq_error; } @@ -2457,7 +2512,7 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba, if (ret) { shost_printk(KERN_ERR, phba->shost, "beiscsi_cmd_eq_create" - "Failedfor EQ \n"); + "Failedfor EQ\n"); goto create_eq_error; } SE_DEBUG(DBG_LVL_8, "eqid = %d\n", phwi_context->be_eq[i].q.id); @@ -2505,7 +2560,7 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba, sizeof(struct sol_cqe), cq_vaddress); if (ret) { shost_printk(KERN_ERR, phba->shost, - "be_fill_queue Failed for ISCSI CQ \n"); + "be_fill_queue Failed for ISCSI CQ\n"); goto create_cq_error; } @@ -2515,7 +2570,7 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba, if (ret) { shost_printk(KERN_ERR, phba->shost, "beiscsi_cmd_eq_create" - "Failed for ISCSI CQ \n"); + "Failed for ISCSI CQ\n"); goto create_cq_error; } SE_DEBUG(DBG_LVL_8, "iscsi cq_id is %d for eq_id %d\n", @@ -2565,7 +2620,8 @@ beiscsi_create_def_hdr(struct beiscsi_hba *phba, "be_fill_queue Failed for DEF PDU HDR\n"); return ret; } - mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address; + mem->dma = (unsigned long)mem_descr->mem_array[idx]. + bus_address.u.a64.address; ret = be_cmd_create_default_pdu_queue(&phba->ctrl, cq, dq, def_pdu_ring_sz, phba->params.defpdu_hdr_sz); @@ -2609,7 +2665,8 @@ beiscsi_create_def_data(struct beiscsi_hba *phba, "be_fill_queue Failed for DEF PDU DATA\n"); return ret; } - mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address; + mem->dma = (unsigned long)mem_descr->mem_array[idx]. + bus_address.u.a64.address; ret = be_cmd_create_default_pdu_queue(&phba->ctrl, cq, dataq, def_pdu_ring_sz, phba->params.defpdu_data_sz); @@ -2623,7 +2680,7 @@ beiscsi_create_def_data(struct beiscsi_hba *phba, SE_DEBUG(DBG_LVL_8, "iscsi def data id is %d\n", phwi_context->be_def_dataq.id); hwi_post_async_buffers(phba, 0); - SE_DEBUG(DBG_LVL_8, "DEFAULT PDU DATA RING CREATED \n"); + SE_DEBUG(DBG_LVL_8, "DEFAULT PDU DATA RING CREATED\n"); return 0; } @@ -2655,7 +2712,7 @@ beiscsi_post_pages(struct beiscsi_hba *phba) } pm_arr++; } - SE_DEBUG(DBG_LVL_8, "POSTED PAGES \n"); + SE_DEBUG(DBG_LVL_8, "POSTED PAGES\n"); return 0; } @@ -2678,7 +2735,7 @@ static int be_queue_alloc(struct beiscsi_hba *phba, struct be_queue_info *q, mem->size = len * entry_size; mem->va = pci_alloc_consistent(phba->pcidev, mem->size, &mem->dma); if (!mem->va) - return -1; + return -ENOMEM; memset(mem->va, 0, mem->size); return 0; } @@ -2750,6 +2807,7 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, if (status != 0) { shost_printk(KERN_ERR, phba->shost, "wrbq create failed."); + kfree(pwrb_arr); return status; } phwi_ctrlr->wrb_context[i * 2].cid = phwi_context->be_wrbq[i]. @@ -2873,7 +2931,7 @@ mcc_cq_destroy: mcc_cq_free: be_queue_free(phba, cq); err: - return -1; + return -ENOMEM; } static int find_num_cpus(void) @@ -2884,7 +2942,7 @@ static int find_num_cpus(void) if (num_cpus >= MAX_CPUS) num_cpus = MAX_CPUS - 1; - SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", num_cpus); + SE_DEBUG(DBG_LVL_8, "num_cpus = %d\n", num_cpus); return num_cpus; } @@ -2907,7 +2965,7 @@ static int hwi_init_port(struct beiscsi_hba *phba) status = beiscsi_create_eqs(phba, phwi_context); if (status != 0) { - shost_printk(KERN_ERR, phba->shost, "EQ not created \n"); + shost_printk(KERN_ERR, phba->shost, "EQ not created\n"); goto error; } @@ -2918,7 +2976,7 @@ static int hwi_init_port(struct beiscsi_hba *phba) status = mgmt_check_supported_fw(ctrl, phba); if (status != 0) { shost_printk(KERN_ERR, phba->shost, - "Unsupported fw version \n"); + "Unsupported fw version\n"); goto error; } @@ -2974,7 +3032,7 @@ static int hwi_init_controller(struct beiscsi_hba *phba) if (1 == phba->init_mem[HWI_MEM_ADDN_CONTEXT].num_elements) { phwi_ctrlr->phwi_ctxt = (struct hwi_context_memory *)phba-> init_mem[HWI_MEM_ADDN_CONTEXT].mem_array[0].virtual_address; - SE_DEBUG(DBG_LVL_8, " phwi_ctrlr->phwi_ctxt=%p \n", + SE_DEBUG(DBG_LVL_8, " phwi_ctrlr->phwi_ctxt=%p\n", phwi_ctrlr->phwi_ctxt); } else { shost_printk(KERN_ERR, phba->shost, @@ -3007,8 +3065,8 @@ static void beiscsi_free_mem(struct beiscsi_hba *phba) pci_free_consistent(phba->pcidev, mem_descr->mem_array[j - 1].size, mem_descr->mem_array[j - 1].virtual_address, - mem_descr->mem_array[j - 1].bus_address. - u.a64.address); + (unsigned long)mem_descr->mem_array[j - 1]. + bus_address.u.a64.address); } kfree(mem_descr->mem_array); mem_descr++; @@ -3024,7 +3082,7 @@ static int beiscsi_init_controller(struct beiscsi_hba *phba) ret = beiscsi_get_memory(phba); if (ret < 0) { shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe -" - "Failed in beiscsi_alloc_memory \n"); + "Failed in beiscsi_alloc_memory\n"); return ret; } @@ -3101,12 +3159,12 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) } SE_DEBUG(DBG_LVL_8, "phba->io_sgl_hndl_avbl=%d" - "phba->eh_sgl_hndl_avbl=%d \n", + "phba->eh_sgl_hndl_avbl=%d\n", phba->io_sgl_hndl_avbl, phba->eh_sgl_hndl_avbl); mem_descr_sg = phba->init_mem; mem_descr_sg += HWI_MEM_SGE; - SE_DEBUG(DBG_LVL_8, "\n mem_descr_sg->num_elements=%d \n", + SE_DEBUG(DBG_LVL_8, "\n mem_descr_sg->num_elements=%d\n", mem_descr_sg->num_elements); arr_index = 0; idx = 0; @@ -3155,7 +3213,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) if (!phba->ep_array) { shost_printk(KERN_ERR, phba->shost, "Failed to allocate memory in " - "hba_setup_cid_tbls \n"); + "hba_setup_cid_tbls\n"); kfree(phba->cid_array); return -ENOMEM; } @@ -3168,7 +3226,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) return 0; } -static unsigned char hwi_enable_intr(struct beiscsi_hba *phba) +static void hwi_enable_intr(struct beiscsi_hba *phba) { struct be_ctrl_info *ctrl = &phba->ctrl; struct hwi_controller *phwi_ctrlr; @@ -3184,26 +3242,25 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba) addr = (u8 __iomem *) ((u8 __iomem *) ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET); reg = ioread32(addr); - SE_DEBUG(DBG_LVL_8, "reg =x%08x \n", reg); + SE_DEBUG(DBG_LVL_8, "reg =x%08x\n", reg); enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; if (!enabled) { reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; - SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr); + SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p\n", reg, addr); iowrite32(reg, addr); if (!phba->msix_enabled) { eq = &phwi_context->be_eq[0].q; - SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); + SE_DEBUG(DBG_LVL_8, "eq->id=%d\n", eq->id); hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); } else { for (i = 0; i <= phba->num_cpus; i++) { eq = &phwi_context->be_eq[i].q; - SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); + SE_DEBUG(DBG_LVL_8, "eq->id=%d\n", eq->id); hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); } } } - return true; } static void hwi_disable_intr(struct beiscsi_hba *phba) @@ -3219,7 +3276,7 @@ static void hwi_disable_intr(struct beiscsi_hba *phba) iowrite32(reg, addr); } else shost_printk(KERN_WARNING, phba->shost, - "In hwi_disable_intr, Already Disabled \n"); + "In hwi_disable_intr, Already Disabled\n"); } static int beiscsi_init_port(struct beiscsi_hba *phba) @@ -3230,14 +3287,14 @@ static int beiscsi_init_port(struct beiscsi_hba *phba) if (ret < 0) { shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe - Failed in" - "beiscsi_init_controller \n"); + "beiscsi_init_controller\n"); return ret; } ret = beiscsi_init_sgl_handle(phba); if (ret < 0) { shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe - Failed in" - "beiscsi_init_sgl_handle \n"); + "beiscsi_init_sgl_handle\n"); goto do_cleanup_ctrlr; } @@ -3291,12 +3348,12 @@ static void hwi_purge_eq(struct beiscsi_hba *phba) static void beiscsi_clean_port(struct beiscsi_hba *phba) { - unsigned char mgmt_status; + int mgmt_status; mgmt_status = mgmt_epfw_cleanup(phba, CMD_CONNECTION_CHUTE_0); if (mgmt_status) shost_printk(KERN_WARNING, phba->shost, - "mgmt_epfw_cleanup FAILED \n"); + "mgmt_epfw_cleanup FAILED\n"); hwi_purge_eq(phba); hwi_cleanup(phba); @@ -3428,14 +3485,12 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) return -ENOMEM; io_task->bhs_pa.u.a64.address = paddr; io_task->libiscsi_itt = (itt_t)task->itt; - io_task->pwrb_handle = alloc_wrb_handle(phba, - beiscsi_conn->beiscsi_conn_cid - - phba->fw_config.iscsi_cid_start - ); io_task->conn = beiscsi_conn; task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr; task->hdr_max = sizeof(struct be_cmd_bhs); + io_task->psgl_handle = NULL; + io_task->psgl_handle = NULL; if (task->sc) { spin_lock(&phba->io_sgl_lock); @@ -3443,6 +3498,11 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) spin_unlock(&phba->io_sgl_lock); if (!io_task->psgl_handle) goto free_hndls; + io_task->pwrb_handle = alloc_wrb_handle(phba, + beiscsi_conn->beiscsi_conn_cid - + phba->fw_config.iscsi_cid_start); + if (!io_task->pwrb_handle) + goto free_io_hndls; } else { io_task->scsi_cmnd = NULL; if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) { @@ -3457,9 +3517,20 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) beiscsi_conn->login_in_progress = 1; beiscsi_conn->plogin_sgl_handle = io_task->psgl_handle; + io_task->pwrb_handle = + alloc_wrb_handle(phba, + beiscsi_conn->beiscsi_conn_cid - + phba->fw_config.iscsi_cid_start); + if (!io_task->pwrb_handle) + goto free_io_hndls; + beiscsi_conn->plogin_wrb_handle = + io_task->pwrb_handle; + } else { io_task->psgl_handle = beiscsi_conn->plogin_sgl_handle; + io_task->pwrb_handle = + beiscsi_conn->plogin_wrb_handle; } } else { spin_lock(&phba->mgmt_sgl_lock); @@ -3467,6 +3538,13 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) spin_unlock(&phba->mgmt_sgl_lock); if (!io_task->psgl_handle) goto free_hndls; + io_task->pwrb_handle = + alloc_wrb_handle(phba, + beiscsi_conn->beiscsi_conn_cid - + phba->fw_config.iscsi_cid_start); + if (!io_task->pwrb_handle) + goto free_mgmt_hndls; + } } itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle-> @@ -3477,16 +3555,26 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) io_task->cmd_bhs->iscsi_hdr.itt = itt; return 0; +free_io_hndls: + spin_lock(&phba->io_sgl_lock); + free_io_sgl_handle(phba, io_task->psgl_handle); + spin_unlock(&phba->io_sgl_lock); + goto free_hndls; +free_mgmt_hndls: + spin_lock(&phba->mgmt_sgl_lock); + free_mgmt_sgl_handle(phba, io_task->psgl_handle); + spin_unlock(&phba->mgmt_sgl_lock); free_hndls: phwi_ctrlr = phba->phwi_ctrlr; pwrb_context = &phwi_ctrlr->wrb_context[ beiscsi_conn->beiscsi_conn_cid - phba->fw_config.iscsi_cid_start]; - free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); + if (io_task->pwrb_handle) + free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); io_task->pwrb_handle = NULL; pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs, io_task->bhs_pa.u.a64.address); - SE_DEBUG(DBG_LVL_1, "Alloc of SGL_ICD Failed \n"); + SE_DEBUG(DBG_LVL_1, "Alloc of SGL_ICD Failed\n"); return -ENOMEM; } @@ -3653,7 +3741,7 @@ static int beiscsi_mtask(struct iscsi_task *task) break; default: - SE_DEBUG(DBG_LVL_1, "opcode =%d Not supported \n", + SE_DEBUG(DBG_LVL_1, "opcode =%d Not supported\n", task->hdr->opcode & ISCSI_OPCODE_MASK); return -EINVAL; } @@ -3689,13 +3777,11 @@ static int beiscsi_task_xmit(struct iscsi_task *task) SE_DEBUG(DBG_LVL_1, " scsi_dma_map Failed\n") return num_sg; } - SE_DEBUG(DBG_LVL_4, "xferlen=0x%08x scmd=%p num_sg=%d sernum=%lu\n", - (scsi_bufflen(sc)), sc, num_sg, sc->serial_number); xferlen = scsi_bufflen(sc); sg = scsi_sglist(sc); if (sc->sc_data_direction == DMA_TO_DEVICE) { writedir = 1; - SE_DEBUG(DBG_LVL_4, "task->imm_count=0x%08x \n", + SE_DEBUG(DBG_LVL_4, "task->imm_count=0x%08x\n", task->imm_count); } else writedir = 0; @@ -3709,10 +3795,12 @@ static void beiscsi_remove(struct pci_dev *pcidev) struct hwi_context_memory *phwi_context; struct be_eq_obj *pbe_eq; unsigned int i, msix_vec; + u8 *real_offset = 0; + u32 value = 0; phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev); if (!phba) { - dev_err(&pcidev->dev, "beiscsi_remove called with no phba \n"); + dev_err(&pcidev->dev, "beiscsi_remove called with no phba\n"); return; } @@ -3737,6 +3825,14 @@ static void beiscsi_remove(struct pci_dev *pcidev) beiscsi_clean_port(phba); beiscsi_free_mem(phba); + real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE; + + value = readl((void *)real_offset); + + if (value & 0x00010000) { + value &= 0xfffeffff; + writel(value, (void *)real_offset); + } beiscsi_unmap_pci_function(phba); pci_free_consistent(phba->pcidev, phba->ctrl.mbox_mem_alloced.size, @@ -3769,19 +3865,21 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, struct hwi_controller *phwi_ctrlr; struct hwi_context_memory *phwi_context; struct be_eq_obj *pbe_eq; - int ret, msix_vec, num_cpus, i; + int ret, num_cpus, i; + u8 *real_offset = 0; + u32 value = 0; ret = beiscsi_enable_pci(pcidev); if (ret < 0) { - shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" - "Failed to enable pci device \n"); + dev_err(&pcidev->dev, "beiscsi_dev_probe-" + " Failed to enable pci device\n"); return ret; } phba = beiscsi_hba_alloc(pcidev); if (!phba) { dev_err(&pcidev->dev, "beiscsi_dev_probe-" - " Failed in beiscsi_hba_alloc \n"); + " Failed in beiscsi_hba_alloc\n"); goto disable_pci; } @@ -3804,7 +3902,7 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, else num_cpus = 1; phba->num_cpus = num_cpus; - SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", phba->num_cpus); + SE_DEBUG(DBG_LVL_8, "num_cpus = %d\n", phba->num_cpus); if (enable_msix) beiscsi_msix_enable(phba); @@ -3815,6 +3913,33 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, goto hba_free; } + if (!num_hba) { + real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE; + value = readl((void *)real_offset); + if (value & 0x00010000) { + gcrashmode++; + shost_printk(KERN_ERR, phba->shost, + "Loading Driver in crashdump mode\n"); + ret = beiscsi_pci_soft_reset(phba); + if (ret) { + shost_printk(KERN_ERR, phba->shost, + "Reset Failed. Aborting Crashdump\n"); + goto hba_free; + } + ret = be_chk_reset_complete(phba); + if (ret) { + shost_printk(KERN_ERR, phba->shost, + "Failed to get out of reset." + "Aborting Crashdump\n"); + goto hba_free; + } + } else { + value |= 0x00010000; + writel(value, (void *)real_offset); + num_hba++; + } + } + spin_lock_init(&phba->io_sgl_lock); spin_lock_init(&phba->mgmt_sgl_lock); spin_lock_init(&phba->isr_lock); @@ -3870,25 +3995,10 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, "Failed to beiscsi_init_irqs\n"); goto free_blkenbld; } - ret = hwi_enable_intr(phba); - if (ret < 0) { - shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" - "Failed to hwi_enable_intr\n"); - goto free_ctrlr; - } - SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED \n\n\n"); + hwi_enable_intr(phba); + SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n"); return 0; -free_ctrlr: - if (phba->msix_enabled) { - for (i = 0; i <= phba->num_cpus; i++) { - msix_vec = phba->msix_entries[i].vector; - free_irq(msix_vec, &phwi_context->be_eq[i]); - } - } else - if (phba->pcidev->irq) - free_irq(phba->pcidev->irq, phba); - pci_disable_msix(phba->pcidev); free_blkenbld: destroy_workqueue(phba->wq); if (blk_iopoll_enabled) @@ -3900,12 +4010,23 @@ free_twq: beiscsi_clean_port(phba); beiscsi_free_mem(phba); free_port: + real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE; + + value = readl((void *)real_offset); + + if (value & 0x00010000) { + value &= 0xfffeffff; + writel(value, (void *)real_offset); + } + pci_free_consistent(phba->pcidev, phba->ctrl.mbox_mem_alloced.size, phba->ctrl.mbox_mem_alloced.va, phba->ctrl.mbox_mem_alloced.dma); beiscsi_unmap_pci_function(phba); hba_free: + if (phba->msix_enabled) + pci_disable_msix(phba->pcidev); iscsi_host_remove(phba->shost); pci_dev_put(phba->pcidev); iscsi_host_free(phba->shost); @@ -3955,7 +4076,7 @@ struct iscsi_transport beiscsi_iscsi_transport = { .get_session_param = iscsi_session_get_param, .get_host_param = beiscsi_get_host_param, .start_conn = beiscsi_conn_start, - .stop_conn = beiscsi_conn_stop, + .stop_conn = iscsi_conn_stop, .send_pdu = iscsi_conn_send_pdu, .xmit_task = beiscsi_task_xmit, .cleanup_task = beiscsi_cleanup_task, @@ -3988,7 +4109,7 @@ static int __init beiscsi_module_init(void) "transport.\n"); return -ENOMEM; } - SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p \n", + SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p\n", &beiscsi_iscsi_transport); ret = pci_register_driver(&beiscsi_pci_driver); diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 87ec21280a37..c643bb3736fc 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h @@ -23,6 +23,7 @@ #include <linux/kernel.h> #include <linux/pci.h> +#include <linux/if_ether.h> #include <linux/in.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> @@ -39,7 +40,7 @@ "Linux iSCSI Driver version" BUILD_STR #define DRV_DESC BE_NAME " " "Driver" -#define BE_VENDOR_ID 0x19A2 +#define BE_VENDOR_ID 0x19A2 /* DEVICE ID's for BE2 */ #define BE_DEVICE_ID1 0x212 #define OC_DEVICE_ID1 0x702 @@ -68,8 +69,15 @@ #define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */ #define BEISCSI_NUM_DEVICES_SUPPORTED 0x01 #define BEISCSI_MAX_FRAGS_INIT 192 -#define BE_NUM_MSIX_ENTRIES 1 -#define MPU_EP_SEMAPHORE 0xac +#define BE_NUM_MSIX_ENTRIES 1 + +#define MPU_EP_CONTROL 0 +#define MPU_EP_SEMAPHORE 0xac +#define BE2_SOFT_RESET 0x5c +#define BE2_PCI_ONLINE0 0xb0 +#define BE2_PCI_ONLINE1 0xb4 +#define BE2_SET_RESET 0x80 +#define BE2_MPU_IRAM_ONLINE 0x00000080 #define BE_SENSE_INFO_SIZE 258 #define BE_ISCSI_PDU_HEADER_SIZE 64 @@ -105,7 +113,7 @@ do { \ #define HWI_GET_ASYNC_PDU_CTX(phwi) (phwi->phwi_ctxt->pasync_ctx) /********* Memory BAR register ************/ -#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc +#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc /** * Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt * Disable" may still globally block interrupts in addition to individual @@ -116,7 +124,7 @@ do { \ #define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK (1 << 29) /* bit 29 */ /********* ISR0 Register offset **********/ -#define CEV_ISR0_OFFSET 0xC18 +#define CEV_ISR0_OFFSET 0xC18 #define CEV_ISR_SIZE 4 /** @@ -139,12 +147,12 @@ do { \ #define DB_EQ_REARM_SHIFT (29) /* bit 29 */ /********* Compl Q door bell *************/ -#define DB_CQ_OFFSET 0x120 +#define DB_CQ_OFFSET 0x120 #define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */ /* Number of event entries processed */ -#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ +#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ /* Rearm bit */ -#define DB_CQ_REARM_SHIFT (29) /* bit 29 */ +#define DB_CQ_REARM_SHIFT (29) /* bit 29 */ #define GET_HWI_CONTROLLER_WS(pc) (pc->phwi_ctrlr) #define HWI_GET_DEF_BUFQ_ID(pc) (((struct hwi_controller *)\ @@ -161,12 +169,12 @@ enum be_mem_enum { HWI_MEM_WRBH, HWI_MEM_SGLH, HWI_MEM_SGE, - HWI_MEM_ASYNC_HEADER_BUF, /* 5 */ + HWI_MEM_ASYNC_HEADER_BUF, /* 5 */ HWI_MEM_ASYNC_DATA_BUF, HWI_MEM_ASYNC_HEADER_RING, HWI_MEM_ASYNC_DATA_RING, HWI_MEM_ASYNC_HEADER_HANDLE, - HWI_MEM_ASYNC_DATA_HANDLE, /* 10 */ + HWI_MEM_ASYNC_DATA_HANDLE, /* 10 */ HWI_MEM_ASYNC_PDU_CONTEXT, ISCSI_MEM_GLOBAL_HEADER, SE_MEM_MAX @@ -352,6 +360,7 @@ struct beiscsi_conn { u32 beiscsi_conn_cid; struct beiscsi_endpoint *ep; unsigned short login_in_progress; + struct wrb_handle *plogin_wrb_handle; struct sgl_handle *plogin_sgl_handle; struct beiscsi_session *beiscsi_sess; struct iscsi_task *task; diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 350cbeaae160..3f3fab91a7d1 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -21,7 +21,7 @@ #include "be_mgmt.h" #include "be_iscsi.h" -unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl, +int mgmt_get_fw_config(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba) { struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); @@ -50,7 +50,7 @@ unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl, pfw_cfg->ulp[0].sq_count; if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) { SE_DEBUG(DBG_LVL_8, - "FW reported MAX CXNS as %d \t" + "FW reported MAX CXNS as %d\t" "Max Supported = %d.\n", phba->fw_config.iscsi_cid_count, BE2_MAX_SESSIONS); @@ -58,14 +58,14 @@ unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl, } } else { shost_printk(KERN_WARNING, phba->shost, - "Failed in mgmt_get_fw_config \n"); + "Failed in mgmt_get_fw_config\n"); } spin_unlock(&ctrl->mbox_lock); return status; } -unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, +int mgmt_check_supported_fw(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba) { struct be_dma_mem nonemb_cmd; @@ -81,7 +81,7 @@ unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, SE_DEBUG(DBG_LVL_1, "Failed to allocate memory for mgmt_check_supported_fw" "\n"); - return -1; + return -ENOMEM; } nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes); req = nonemb_cmd.va; @@ -117,8 +117,7 @@ unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl, return status; } - -unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) +int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) { struct be_ctrl_info *ctrl = &phba->ctrl; struct be_mcc_wrb *wrb = wrb_from_mccq(phba); @@ -144,11 +143,12 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) return status; } -unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, +unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, struct invalidate_command_table *inv_tbl, - unsigned int num_invalidate, unsigned int cid) + unsigned int num_invalidate, unsigned int cid, + struct be_dma_mem *nonemb_cmd) + { - struct be_dma_mem nonemb_cmd; struct be_ctrl_info *ctrl = &phba->ctrl; struct be_mcc_wrb *wrb; struct be_sge *sge; @@ -162,17 +162,7 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, return tag; } - nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev, - sizeof(struct invalidate_commands_params_in), - &nonemb_cmd.dma); - if (nonemb_cmd.va == NULL) { - SE_DEBUG(DBG_LVL_1, - "Failed to allocate memory for mgmt_invalidate_icds\n"); - spin_unlock(&ctrl->mbox_lock); - return 0; - } - nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); - req = nonemb_cmd.va; + req = nonemb_cmd->va; memset(req, 0, sizeof(*req)); wrb = wrb_from_mccq(phba); sge = nonembedded_sgl(wrb); @@ -190,19 +180,16 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, req->icd_count++; inv_tbl++; } - 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); + 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); - if (nonemb_cmd.va) - pci_free_consistent(ctrl->pdev, nonemb_cmd.size, - nonemb_cmd.va, nonemb_cmd.dma); return tag; } -unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, +unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba, struct beiscsi_endpoint *beiscsi_ep, unsigned short cid, unsigned short issue_reset, @@ -239,7 +226,7 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, return tag; } -unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, +unsigned int mgmt_upload_connection(struct beiscsi_hba *phba, unsigned short cid, unsigned int upload_flag) { struct be_ctrl_info *ctrl = &phba->ctrl; @@ -269,7 +256,9 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, int mgmt_open_connection(struct beiscsi_hba *phba, struct sockaddr *dst_addr, - struct beiscsi_endpoint *beiscsi_ep) + struct beiscsi_endpoint *beiscsi_ep, + struct be_dma_mem *nonemb_cmd) + { struct hwi_controller *phwi_ctrlr; struct hwi_context_memory *phwi_context; @@ -285,6 +274,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba, unsigned int tag = 0; unsigned int i; unsigned short cid = beiscsi_ep->ep_cid; + struct be_sge *sge; phwi_ctrlr = phba->phwi_ctrlr; phwi_context = phwi_ctrlr->phwi_ctxt; @@ -300,10 +290,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba, return tag; } wrb = wrb_from_mccq(phba); - req = embedded_payload(wrb); + memset(wrb, 0, sizeof(*wrb)); + sge = nonembedded_sgl(wrb); + + req = nonemb_cmd->va; + memset(req, 0, sizeof(*req)); wrb->tag0 |= tag; - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 1); be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD, sizeof(*req)); @@ -331,6 +325,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba, shost_printk(KERN_ERR, phba->shost, "unknown addr family %d\n", dst_addr->sa_family); spin_unlock(&ctrl->mbox_lock); + free_mcc_tag(&phba->ctrl, tag); return -EINVAL; } @@ -339,13 +334,16 @@ int mgmt_open_connection(struct beiscsi_hba *phba, if (phba->nxt_cqid == phba->num_cpus) phba->nxt_cqid = 0; req->cq_id = phwi_context->be_cq[i].id; - SE_DEBUG(DBG_LVL_8, "i=%d cq_id=%d \n", i, req->cq_id); + SE_DEBUG(DBG_LVL_8, "i=%d cq_id=%d\n", i, req->cq_id); req->defq_id = def_hdr_id; req->hdr_ring_id = def_hdr_id; req->data_ring_id = def_data_id; req->do_offload = 1; req->dataout_template_pa.lo = ptemplate_address->lo; req->dataout_template_pa.hi = ptemplate_address->hi; + sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); + sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); + sge->len = cpu_to_le32(nonemb_cmd->size); be_mcc_notify(phba); spin_unlock(&ctrl->mbox_lock); return tag; diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index 3d316b82feb1..b9acedf78653 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h @@ -86,16 +86,19 @@ struct mcc_wrb { struct mcc_wrb_payload payload; }; -unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute); -int mgmt_open_connection(struct beiscsi_hba *phba, struct sockaddr *dst_addr, - struct beiscsi_endpoint *beiscsi_ep); +int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute); +int mgmt_open_connection(struct beiscsi_hba *phba, + struct sockaddr *dst_addr, + struct beiscsi_endpoint *beiscsi_ep, + struct be_dma_mem *nonemb_cmd); -unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, +unsigned int mgmt_upload_connection(struct beiscsi_hba *phba, unsigned short cid, unsigned int upload_flag); -unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, +unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, struct invalidate_command_table *inv_tbl, - unsigned int num_invalidate, unsigned int cid); + unsigned int num_invalidate, unsigned int cid, + struct be_dma_mem *nonemb_cmd); struct iscsi_invalidate_connection_params_in { struct be_cmd_req_hdr hdr; @@ -237,10 +240,10 @@ struct beiscsi_endpoint { u16 cid_vld; }; -unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl, +int mgmt_get_fw_config(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba); -unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba, +unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba, struct beiscsi_endpoint *beiscsi_ep, unsigned short cid, unsigned short issue_reset, |