diff options
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be.h | 3 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 41 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 17 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 165 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 345 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 44 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 117 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.h | 98 |
8 files changed, 364 insertions, 466 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index b1d0fdc5d5e1..ca9440fb2325 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h @@ -84,7 +84,6 @@ static inline void queue_tail_inc(struct be_queue_info *q) /*ISCSI */ struct be_aic_obj { /* Adaptive interrupt coalescing (AIC) info */ - bool enable; u32 min_eqd; /* in usecs */ u32 max_eqd; /* in usecs */ u32 prev_eqd; /* in usecs */ @@ -94,8 +93,6 @@ struct be_aic_obj { /* Adaptive interrupt coalescing (AIC) info */ }; struct be_eq_obj { - bool todo_mcc_cq; - bool todo_cq; u32 cq_count; struct be_queue_info q; struct beiscsi_hba *phba; diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index be65da2988fb..5d59e2630ce6 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -676,10 +676,10 @@ void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, bool embedded, u8 sge_cnt) { if (embedded) - wrb->embedded |= MCC_WRB_EMBEDDED_MASK; + wrb->emb_sgecnt_special |= MCC_WRB_EMBEDDED_MASK; else - wrb->embedded |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) << - MCC_WRB_SGE_CNT_SHIFT; + wrb->emb_sgecnt_special |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) << + MCC_WRB_SGE_CNT_SHIFT; wrb->payload_length = payload_len; be_dws_cpu_to_le(wrb, 8); } @@ -1599,7 +1599,7 @@ int beiscsi_cmd_function_reset(struct beiscsi_hba *phba) { struct be_ctrl_info *ctrl = &phba->ctrl; struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct be_post_sgl_pages_req *req = embedded_payload(wrb); + struct be_post_sgl_pages_req *req; int status; mutex_lock(&ctrl->mbox_lock); @@ -1700,31 +1700,34 @@ int beiscsi_cmd_iscsi_cleanup(struct beiscsi_hba *phba, unsigned short ulp) struct be_ctrl_info *ctrl = &phba->ctrl; struct iscsi_cleanup_req_v1 *req_v1; struct iscsi_cleanup_req *req; + u16 hdr_ring_id, data_ring_id; struct be_mcc_wrb *wrb; int status; mutex_lock(&ctrl->mbox_lock); wrb = wrb_from_mbox(&ctrl->mbox_mem); - req = embedded_payload(wrb); - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, - OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req)); - /** - * TODO: Check with FW folks the chute value to be set. - * For now, use the ULP_MASK as the chute value. - */ + hdr_ring_id = HWI_GET_DEF_HDRQ_ID(phba, ulp); + data_ring_id = HWI_GET_DEF_BUFQ_ID(phba, ulp); if (is_chip_be2_be3r(phba)) { + req = embedded_payload(wrb); + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, + OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req)); req->chute = (1 << ulp); - req->hdr_ring_id = HWI_GET_DEF_HDRQ_ID(phba, ulp); - req->data_ring_id = HWI_GET_DEF_BUFQ_ID(phba, ulp); + /* BE2/BE3 FW creates 8-bit ring id */ + req->hdr_ring_id = hdr_ring_id; + req->data_ring_id = data_ring_id; } else { - req_v1 = (struct iscsi_cleanup_req_v1 *)req; + req_v1 = embedded_payload(wrb); + be_wrb_hdr_prepare(wrb, sizeof(*req_v1), true, 0); + be_cmd_hdr_prepare(&req_v1->hdr, CMD_SUBSYSTEM_ISCSI, + OPCODE_COMMON_ISCSI_CLEANUP, + sizeof(*req_v1)); req_v1->hdr.version = 1; - req_v1->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, - ulp)); - req_v1->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, - ulp)); + req_v1->chute = (1 << ulp); + req_v1->hdr_ring_id = cpu_to_le16(hdr_ring_id); + req_v1->data_ring_id = cpu_to_le16(data_ring_id); } status = be_mbox_notify(ctrl); diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 328fb5b973cd..1d40e83b0790 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h @@ -31,10 +31,16 @@ struct be_sge { __le32 len; }; -#define MCC_WRB_SGE_CNT_SHIFT 3 /* bits 3 - 7 of dword 0 */ -#define MCC_WRB_SGE_CNT_MASK 0x1F /* bits 3 - 7 of dword 0 */ struct be_mcc_wrb { - u32 embedded; /* dword 0 */ + u32 emb_sgecnt_special; /* dword 0 */ + /* bits 0 - embedded */ + /* bits 1 - 2 reserved */ + /* bits 3 - 7 sge count */ + /* bits 8 - 23 reserved */ + /* bits 24 - 31 special */ +#define MCC_WRB_EMBEDDED_MASK 1 +#define MCC_WRB_SGE_CNT_SHIFT 3 +#define MCC_WRB_SGE_CNT_MASK 0x1F u32 payload_length; /* dword 1 */ u32 tag0; /* dword 2 */ u32 tag1; /* dword 3 */ @@ -1133,11 +1139,6 @@ struct tcp_connect_and_offload_out { } __packed; -struct be_mcc_wrb_context { - struct MCC_WRB *wrb; - int *users_final_status; -} __packed; - #define DB_DEF_PDU_RING_ID_MASK 0x3FFF /* bits 0 - 13 */ #define DB_DEF_PDU_CQPROC_MASK 0x3FFF /* bits 16 - 29 */ #define DB_DEF_PDU_REARM_SHIFT 14 diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index ba258217614e..a4844578e357 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -166,33 +166,6 @@ beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid) } /** - * beiscsi_bindconn_cid - Bind the beiscsi_conn with phba connection table - * @beiscsi_conn: The pointer to beiscsi_conn structure - * @phba: The phba instance - * @cid: The cid to free - */ -static int beiscsi_bindconn_cid(struct beiscsi_hba *phba, - struct beiscsi_conn *beiscsi_conn, - unsigned int cid) -{ - uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); - - if (phba->conn_table[cri_index]) { - beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, - "BS_%d : Connection table already occupied. Detected clash\n"); - - return -EINVAL; - } else { - beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, - "BS_%d : phba->conn_table[%d]=%p(beiscsi_conn)\n", - cri_index, beiscsi_conn); - - phba->conn_table[cri_index] = beiscsi_conn; - } - return 0; -} - -/** * beiscsi_conn_bind - Binds iscsi session/connection with TCP connection * @cls_session: pointer to iscsi cls session * @cls_conn: pointer to iscsi cls conn @@ -212,6 +185,7 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, struct hwi_wrb_context *pwrb_context; struct beiscsi_endpoint *beiscsi_ep; struct iscsi_endpoint *ep; + uint16_t cri_index; ep = iscsi_lookup_endpoint(transport_fd); if (!ep) @@ -229,20 +203,34 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, return -EEXIST; } - - pwrb_context = &phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID( - beiscsi_ep->ep_cid)]; + cri_index = BE_GET_CRI_FROM_CID(beiscsi_ep->ep_cid); + if (phba->conn_table[cri_index]) { + if (beiscsi_conn != phba->conn_table[cri_index] || + beiscsi_ep != phba->conn_table[cri_index]->ep) { + __beiscsi_log(phba, KERN_ERR, + "BS_%d : conn_table not empty at %u: cid %u conn %p:%p\n", + cri_index, + beiscsi_ep->ep_cid, + beiscsi_conn, + phba->conn_table[cri_index]); + return -EINVAL; + } + } beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid; beiscsi_conn->ep = beiscsi_ep; beiscsi_ep->conn = beiscsi_conn; + /** + * Each connection is associated with a WRBQ kept in wrb_context. + * Store doorbell offset for transmit path. + */ + pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; beiscsi_conn->doorbell_offset = pwrb_context->doorbell_offset; - beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, - "BS_%d : 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); + "BS_%d : cid %d phba->conn_table[%u]=%p\n", + beiscsi_ep->ep_cid, cri_index, beiscsi_conn); + phba->conn_table[cri_index] = beiscsi_conn; + return 0; } static int beiscsi_iface_create_ipv4(struct beiscsi_hba *phba) @@ -973,9 +961,9 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) */ static int beiscsi_get_cid(struct beiscsi_hba *phba) { - unsigned short cid = 0xFFFF, cid_from_ulp; - struct ulp_cid_info *cid_info = NULL; uint16_t cid_avlbl_ulp0, cid_avlbl_ulp1; + unsigned short cid, cid_from_ulp; + struct ulp_cid_info *cid_info; /* Find the ULP which has more CID available */ cid_avlbl_ulp0 = (phba->cid_array_info[BEISCSI_ULP0]) ? @@ -984,20 +972,27 @@ static int beiscsi_get_cid(struct beiscsi_hba *phba) BEISCSI_ULP1_AVLBL_CID(phba) : 0; cid_from_ulp = (cid_avlbl_ulp0 > cid_avlbl_ulp1) ? BEISCSI_ULP0 : BEISCSI_ULP1; - - if (test_bit(cid_from_ulp, (void *)&phba->fw_config.ulp_supported)) { - cid_info = phba->cid_array_info[cid_from_ulp]; - if (!cid_info->avlbl_cids) - return cid; - - cid = cid_info->cid_array[cid_info->cid_alloc++]; - - if (cid_info->cid_alloc == BEISCSI_GET_CID_COUNT( - phba, cid_from_ulp)) - cid_info->cid_alloc = 0; - - cid_info->avlbl_cids--; + /** + * If iSCSI protocol is loaded only on ULP 0, and when cid_avlbl_ulp + * is ZERO for both, ULP 1 is returned. + * Check if ULP is loaded before getting new CID. + */ + if (!test_bit(cid_from_ulp, (void *)&phba->fw_config.ulp_supported)) + return BE_INVALID_CID; + + cid_info = phba->cid_array_info[cid_from_ulp]; + cid = cid_info->cid_array[cid_info->cid_alloc]; + if (!cid_info->avlbl_cids || cid == BE_INVALID_CID) { + __beiscsi_log(phba, KERN_ERR, + "BS_%d : failed to get cid: available %u:%u\n", + cid_info->avlbl_cids, cid_info->cid_free); + return BE_INVALID_CID; } + /* empty the slot */ + cid_info->cid_array[cid_info->cid_alloc++] = BE_INVALID_CID; + if (cid_info->cid_alloc == BEISCSI_GET_CID_COUNT(phba, cid_from_ulp)) + cid_info->cid_alloc = 0; + cid_info->avlbl_cids--; return cid; } @@ -1008,22 +1003,28 @@ static int beiscsi_get_cid(struct beiscsi_hba *phba) */ static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) { - uint16_t cid_post_ulp; - struct hwi_controller *phwi_ctrlr; - struct hwi_wrb_context *pwrb_context; - struct ulp_cid_info *cid_info = NULL; uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); + struct hwi_wrb_context *pwrb_context; + struct hwi_controller *phwi_ctrlr; + struct ulp_cid_info *cid_info; + uint16_t cid_post_ulp; phwi_ctrlr = phba->phwi_ctrlr; pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; cid_post_ulp = pwrb_context->ulp_num; cid_info = phba->cid_array_info[cid_post_ulp]; - cid_info->avlbl_cids++; - + /* fill only in empty slot */ + if (cid_info->cid_array[cid_info->cid_free] != BE_INVALID_CID) { + __beiscsi_log(phba, KERN_ERR, + "BS_%d : failed to put cid %u: available %u:%u\n", + cid, cid_info->avlbl_cids, cid_info->cid_free); + return; + } cid_info->cid_array[cid_info->cid_free++] = cid; if (cid_info->cid_free == BEISCSI_GET_CID_COUNT(phba, cid_post_ulp)) cid_info->cid_free = 0; + cid_info->avlbl_cids++; } /** @@ -1037,8 +1038,8 @@ static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) beiscsi_put_cid(phba, beiscsi_ep->ep_cid); beiscsi_ep->phba = NULL; - phba->ep_array[BE_GET_CRI_FROM_CID - (beiscsi_ep->ep_cid)] = NULL; + /* clear this to track freeing in beiscsi_ep_disconnect */ + phba->ep_array[BE_GET_CRI_FROM_CID(beiscsi_ep->ep_cid)] = NULL; /** * Check if any connection resource allocated by driver @@ -1049,6 +1050,11 @@ static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) return; beiscsi_conn = beiscsi_ep->conn; + /** + * Break ep->conn link here so that completions after + * this are ignored. + */ + beiscsi_ep->conn = NULL; if (beiscsi_conn->login_in_progress) { beiscsi_free_mgmt_task_handles(beiscsi_conn, beiscsi_conn->task); @@ -1079,7 +1085,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, "BS_%d : In beiscsi_open_conn\n"); beiscsi_ep->ep_cid = beiscsi_get_cid(phba); - if (beiscsi_ep->ep_cid == 0xFFFF) { + if (beiscsi_ep->ep_cid == BE_INVALID_CID) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, "BS_%d : No free cid available\n"); return ret; @@ -1114,7 +1120,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, nonemb_cmd.size = req_memsize; memset(nonemb_cmd.va, 0, nonemb_cmd.size); tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd); - if (tag <= 0) { + if (!tag) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, "BS_%d : mgmt_open_connection Failed for cid=%d\n", beiscsi_ep->ep_cid); @@ -1285,26 +1291,6 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) } /** - * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table - * @phba: The phba instance - * @cid: The cid to free - */ -static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba, - unsigned int cid) -{ - uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); - - if (phba->conn_table[cri_index]) - phba->conn_table[cri_index] = NULL; - else { - beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, - "BS_%d : Connection table Not occupied.\n"); - return -EINVAL; - } - return 0; -} - -/** * beiscsi_ep_disconnect - Tears down the TCP connection * @ep: endpoint to be used * @@ -1318,13 +1304,23 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) unsigned int tag; uint8_t mgmt_invalidate_flag, tcp_upload_flag; unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; + uint16_t cri_index; beiscsi_ep = ep->dd_data; phba = beiscsi_ep->phba; beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, - "BS_%d : In beiscsi_ep_disconnect for ep_cid = %d\n", + "BS_%d : In beiscsi_ep_disconnect for ep_cid = %u\n", beiscsi_ep->ep_cid); + cri_index = BE_GET_CRI_FROM_CID(beiscsi_ep->ep_cid); + if (!phba->ep_array[cri_index]) { + __beiscsi_log(phba, KERN_ERR, + "BS_%d : ep_array at %u cid %u empty\n", + cri_index, + beiscsi_ep->ep_cid); + return; + } + if (beiscsi_ep->conn) { beiscsi_conn = beiscsi_ep->conn; iscsi_suspend_queue(beiscsi_conn->conn); @@ -1356,7 +1352,12 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) free_ep: msleep(BEISCSI_LOGOUT_SYNC_DELAY); beiscsi_free_ep(beiscsi_ep); - beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); + if (!phba->conn_table[cri_index]) + __beiscsi_log(phba, KERN_ERR, + "BS_%d : conn_table empty at %u: cid %u\n", + cri_index, + beiscsi_ep->ep_cid); + phba->conn_table[cri_index] = NULL; iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); } diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index b5112d6d7e73..32b2713cec93 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -67,8 +67,6 @@ beiscsi_##_name##_disp(struct device *dev,\ { \ struct Scsi_Host *shost = class_to_shost(dev);\ struct beiscsi_hba *phba = iscsi_host_priv(shost); \ - uint32_t param_val = 0; \ - param_val = phba->attr_##_name;\ return snprintf(buf, PAGE_SIZE, "%d\n",\ phba->attr_##_name);\ } @@ -218,160 +216,156 @@ static int beiscsi_slave_configure(struct scsi_device *sdev) static int beiscsi_eh_abort(struct scsi_cmnd *sc) { + struct iscsi_task *abrt_task = (struct iscsi_task *)sc->SCp.ptr; struct iscsi_cls_session *cls_session; - struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr; - struct beiscsi_io_task *aborted_io_task; - struct iscsi_conn *conn; + struct beiscsi_io_task *abrt_io_task; struct beiscsi_conn *beiscsi_conn; - 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; + struct invldt_cmd_tbl inv_tbl; + struct beiscsi_hba *phba; + struct iscsi_conn *conn; int rc; cls_session = starget_to_session(scsi_target(sc->device)); session = cls_session->dd_data; - spin_lock_bh(&session->frwd_lock); - if (!aborted_task || !aborted_task->sc) { - /* we raced */ - spin_unlock_bh(&session->frwd_lock); - return SUCCESS; - } - - aborted_io_task = aborted_task->dd_data; - if (!aborted_io_task->scsi_cmnd) { - /* raced or invalid command */ - spin_unlock_bh(&session->frwd_lock); + /* check if we raced, task just got cleaned up under us */ + spin_lock_bh(&session->back_lock); + if (!abrt_task || !abrt_task->sc) { + spin_unlock_bh(&session->back_lock); return SUCCESS; } - spin_unlock_bh(&session->frwd_lock); - /* Invalidate WRB Posted for this Task */ - AMAP_SET_BITS(struct amap_iscsi_wrb, invld, - aborted_io_task->pwrb_handle->pwrb, - 1); - - conn = aborted_task->conn; + /* get a task ref till FW processes the req for the ICD used */ + __iscsi_get_task(abrt_task); + abrt_io_task = abrt_task->dd_data; + conn = abrt_task->conn; beiscsi_conn = conn->dd_data; phba = beiscsi_conn->phba; - - /* invalidate iocb */ - cid = beiscsi_conn->beiscsi_conn_cid; - inv_tbl = phba->inv_tbl; - memset(inv_tbl, 0x0, sizeof(*inv_tbl)); - inv_tbl->cid = cid; - inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index; - num_invalidate = 1; - nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, - sizeof(struct invalidate_commands_params_in), - &nonemb_cmd.dma); - if (nonemb_cmd.va == NULL) { - beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH, - "BM_%d : Failed to allocate memory for" - "mgmt_invalidate_icds\n"); - return FAILED; + /* mark WRB invalid which have been not processed by FW yet */ + if (is_chip_be2_be3r(phba)) { + AMAP_SET_BITS(struct amap_iscsi_wrb, invld, + abrt_io_task->pwrb_handle->pwrb, 1); + } else { + AMAP_SET_BITS(struct amap_iscsi_wrb_v2, invld, + abrt_io_task->pwrb_handle->pwrb, 1); } - nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); + inv_tbl.cid = beiscsi_conn->beiscsi_conn_cid; + inv_tbl.icd = abrt_io_task->psgl_handle->sgl_index; + spin_unlock_bh(&session->back_lock); - tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, - cid, &nonemb_cmd); - if (!tag) { + rc = beiscsi_mgmt_invalidate_icds(phba, &inv_tbl, 1); + iscsi_put_task(abrt_task); + if (rc) { beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH, - "BM_%d : mgmt_invalidate_icds could not be" - "submitted\n"); - pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, - nonemb_cmd.va, nonemb_cmd.dma); - + "BM_%d : sc %p invalidation failed %d\n", + sc, rc); return FAILED; } - rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd); - if (rc != -EBUSY) - pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, - nonemb_cmd.va, nonemb_cmd.dma); - return iscsi_eh_abort(sc); } static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) { - struct iscsi_task *abrt_task; - struct beiscsi_io_task *abrt_io_task; - struct iscsi_conn *conn; + struct beiscsi_invldt_cmd_tbl { + struct invldt_cmd_tbl tbl[BE_INVLDT_CMD_TBL_SZ]; + struct iscsi_task *task[BE_INVLDT_CMD_TBL_SZ]; + } *inv_tbl; + struct iscsi_cls_session *cls_session; struct beiscsi_conn *beiscsi_conn; - struct beiscsi_hba *phba; + struct beiscsi_io_task *io_task; 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; + struct beiscsi_hba *phba; + struct iscsi_conn *conn; + struct iscsi_task *task; + unsigned int i, nents; + int rc, more = 0; - /* invalidate iocbs */ cls_session = starget_to_session(scsi_target(sc->device)); session = cls_session->dd_data; + spin_lock_bh(&session->frwd_lock); if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN) { spin_unlock_bh(&session->frwd_lock); return FAILED; } + conn = session->leadconn; beiscsi_conn = conn->dd_data; phba = beiscsi_conn->phba; - cid = beiscsi_conn->beiscsi_conn_cid; - inv_tbl = phba->inv_tbl; - memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN); - num_invalidate = 0; + + inv_tbl = kzalloc(sizeof(*inv_tbl), GFP_ATOMIC); + if (!inv_tbl) { + spin_unlock_bh(&session->frwd_lock); + beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH, + "BM_%d : invldt_cmd_tbl alloc failed\n"); + return FAILED; + } + nents = 0; + /* take back_lock to prevent task from getting cleaned up under us */ + spin_lock(&session->back_lock); for (i = 0; i < conn->session->cmds_max; i++) { - abrt_task = conn->session->cmds[i]; - abrt_io_task = abrt_task->dd_data; - if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE) + task = conn->session->cmds[i]; + if (!task->sc) continue; - if (sc->device->lun != abrt_task->sc->device->lun) + if (sc->device->lun != task->sc->device->lun) continue; + /** + * Can't fit in more cmds? Normally this won't happen b'coz + * BEISCSI_CMD_PER_LUN is same as BE_INVLDT_CMD_TBL_SZ. + */ + if (nents == BE_INVLDT_CMD_TBL_SZ) { + more = 1; + break; + } - /* Invalidate WRB Posted for this Task */ - AMAP_SET_BITS(struct amap_iscsi_wrb, invld, - abrt_io_task->pwrb_handle->pwrb, - 1); + /* get a task ref till FW processes the req for the ICD used */ + __iscsi_get_task(task); + io_task = task->dd_data; + /* mark WRB invalid which have been not processed by FW yet */ + if (is_chip_be2_be3r(phba)) { + AMAP_SET_BITS(struct amap_iscsi_wrb, invld, + io_task->pwrb_handle->pwrb, 1); + } else { + AMAP_SET_BITS(struct amap_iscsi_wrb_v2, invld, + io_task->pwrb_handle->pwrb, 1); + } - inv_tbl->cid = cid; - inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index; - num_invalidate++; - inv_tbl++; + inv_tbl->tbl[nents].cid = beiscsi_conn->beiscsi_conn_cid; + inv_tbl->tbl[nents].icd = io_task->psgl_handle->sgl_index; + inv_tbl->task[nents] = task; + nents++; } + spin_unlock_bh(&session->back_lock); spin_unlock_bh(&session->frwd_lock); - inv_tbl = phba->inv_tbl; - nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, - sizeof(struct invalidate_commands_params_in), - &nonemb_cmd.dma); - if (nonemb_cmd.va == NULL) { + rc = SUCCESS; + if (!nents) + goto end_reset; + + if (more) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH, - "BM_%d : Failed to allocate memory for" - "mgmt_invalidate_icds\n"); - return FAILED; + "BM_%d : number of cmds exceeds size of invalidation table\n"); + rc = FAILED; + goto end_reset; } - 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) { + + if (beiscsi_mgmt_invalidate_icds(phba, &inv_tbl->tbl[0], nents)) { beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH, - "BM_%d : 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; + "BM_%d : cid %u scmds invalidation failed\n", + beiscsi_conn->beiscsi_conn_cid); + rc = FAILED; } - rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd); - if (rc != -EBUSY) - pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, - nonemb_cmd.va, nonemb_cmd.dma); - return iscsi_eh_device_reset(sc); +end_reset: + for (i = 0; i < nents; i++) + iscsi_put_task(inv_tbl->task[i]); + kfree(inv_tbl); + + if (rc == SUCCESS) + rc = iscsi_eh_device_reset(sc); + return rc; } /*------------------- PCI Driver operations and data ----------------- */ @@ -395,6 +389,7 @@ static struct scsi_host_template beiscsi_sht = { .change_queue_depth = scsi_change_queue_depth, .slave_configure = beiscsi_slave_configure, .target_alloc = iscsi_target_alloc, + .eh_timed_out = iscsi_eh_cmd_timed_out, .eh_abort_handler = beiscsi_eh_abort, .eh_device_reset_handler = beiscsi_eh_device_reset, .eh_target_reset_handler = iscsi_eh_session_reset, @@ -646,7 +641,6 @@ static void beiscsi_get_params(struct beiscsi_hba *phba) phba->params.num_sge_per_io = BE2_SGE; phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ; - phba->params.eq_timer = 64; phba->params.num_eq_entries = 1024; phba->params.num_cq_entries = 1024; phba->params.wrbs_per_cxn = 256; @@ -964,6 +958,10 @@ beiscsi_get_wrb_handle(struct hwi_wrb_context *pwrb_context, unsigned long flags; spin_lock_irqsave(&pwrb_context->wrb_lock, flags); + if (!pwrb_context->wrb_handles_available) { + spin_unlock_irqrestore(&pwrb_context->wrb_lock, flags); + return NULL; + } pwrb_handle = pwrb_context->pwrb_handle_base[pwrb_context->alloc_index]; pwrb_context->wrb_handles_available--; if (pwrb_context->alloc_index == (wrbs_per_cxn - 1)) @@ -1014,6 +1012,7 @@ beiscsi_put_wrb_handle(struct hwi_wrb_context *pwrb_context, pwrb_context->free_index = 0; else pwrb_context->free_index++; + pwrb_handle->pio_handle = NULL; spin_unlock_irqrestore(&pwrb_context->wrb_lock, flags); } @@ -1224,6 +1223,7 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, uint16_t wrb_index, cid, cri_index; struct hwi_controller *phwi_ctrlr; struct wrb_handle *pwrb_handle; + struct iscsi_session *session; struct iscsi_task *task; phwi_ctrlr = phba->phwi_ctrlr; @@ -1242,8 +1242,12 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, cri_index = BE_GET_CRI_FROM_CID(cid); pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; pwrb_handle = pwrb_context->pwrb_handle_basestd[wrb_index]; + session = beiscsi_conn->conn->session; + spin_lock_bh(&session->back_lock); task = pwrb_handle->pio_handle; - iscsi_put_task(task); + if (task) + __iscsi_put_task(task); + spin_unlock_bh(&session->back_lock); } static void @@ -1323,16 +1327,15 @@ static void adapter_get_sol_cqe(struct beiscsi_hba *phba, static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, struct beiscsi_hba *phba, struct sol_cqe *psol) { - struct hwi_wrb_context *pwrb_context; - struct wrb_handle *pwrb_handle; - struct iscsi_wrb *pwrb = NULL; - struct hwi_controller *phwi_ctrlr; - struct iscsi_task *task; - unsigned int type; struct iscsi_conn *conn = beiscsi_conn->conn; struct iscsi_session *session = conn->session; struct common_sol_cqe csol_cqe = {0}; + struct hwi_wrb_context *pwrb_context; + struct hwi_controller *phwi_ctrlr; + struct wrb_handle *pwrb_handle; + struct iscsi_task *task; uint16_t cri_index = 0; + uint8_t type; phwi_ctrlr = phba->phwi_ctrlr; @@ -1345,11 +1348,14 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, pwrb_handle = pwrb_context->pwrb_handle_basestd[ csol_cqe.wrb_index]; + spin_lock_bh(&session->back_lock); task = pwrb_handle->pio_handle; - pwrb = pwrb_handle->pwrb; + if (!task) { + spin_unlock_bh(&session->back_lock); + return; + } type = ((struct beiscsi_io_task *)task->dd_data)->wrb_type; - spin_lock_bh(&session->back_lock); switch (type) { case HWH_TYPE_IO: case HWH_TYPE_IO_RD: @@ -1711,13 +1717,12 @@ beiscsi_hdq_post_handles(struct beiscsi_hba *phba, struct list_head *hfree_list; struct phys_addr *pasync_sge; u32 ring_id, doorbell = 0; - u16 index, num_entries; u32 doorbell_offset; u16 prod = 0, cons; + u16 index; phwi_ctrlr = phba->phwi_ctrlr; pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr, ulp_num); - num_entries = pasync_ctx->num_entries; if (header) { cons = pasync_ctx->async_header.free_entries; hfree_list = &pasync_ctx->async_header.free_list; @@ -2374,13 +2379,10 @@ static int hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task) static void beiscsi_find_mem_req(struct beiscsi_hba *phba) { uint8_t mem_descr_index, ulp_num; - unsigned int num_cq_pages, num_async_pdu_buf_pages; + unsigned int num_async_pdu_buf_pages; unsigned int num_async_pdu_data_pages, wrb_sz_per_cxn; unsigned int num_async_pdu_buf_sgl_pages, num_async_pdu_data_sgl_pages; - num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \ - sizeof(struct sol_cqe)); - phba->params.hwi_ws_sz = sizeof(struct hwi_controller); phba->mem_req[ISCSI_MEM_GLOBAL_HEADER] = 2 * @@ -2737,7 +2739,7 @@ static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) { - /* get async_ctx for each ULP */ + /* get async_ctx for each ULP */ mem_descr = (struct be_mem_descriptor *)phba->init_mem; mem_descr += (HWI_MEM_ASYNC_PDU_CONTEXT_ULP0 + (ulp_num * MEM_DESCR_OFFSET)); @@ -3367,7 +3369,7 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, struct hwi_context_memory *phwi_context, struct hwi_controller *phwi_ctrlr) { - unsigned int wrb_mem_index, offset, size, num_wrb_rings; + unsigned int num_wrb_rings; u64 pa_addr_lo; unsigned int idx, num, i, ulp_num; struct mem_array *pwrb_arr; @@ -3432,10 +3434,6 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, } for (i = 0; i < phba->params.cxns_per_ctrl; i++) { - wrb_mem_index = 0; - offset = 0; - size = 0; - if (ulp_count > 1) { ulp_base_num = (ulp_base_num + 1) % BEISCSI_ULP_COUNT; @@ -3663,7 +3661,6 @@ static void hwi_cleanup_port(struct beiscsi_hba *phba) struct be_ctrl_info *ctrl = &phba->ctrl; struct hwi_controller *phwi_ctrlr; struct hwi_context_memory *phwi_context; - struct hd_async_context *pasync_ctx; int i, eq_for_mcc, ulp_num; for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) @@ -3700,8 +3697,6 @@ static void hwi_cleanup_port(struct beiscsi_hba *phba) q = &phwi_context->be_def_dataq[ulp_num]; if (q->created) beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ); - - pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx[ulp_num]; } } @@ -3804,7 +3799,6 @@ static int hwi_init_port(struct beiscsi_hba *phba) /** * Now that the default PDU rings have been created, * let EP know about it. - * Call beiscsi_cmd_iscsi_cleanup before posting? */ beiscsi_hdq_post_handles(phba, BEISCSI_DEFQ_HDR, ulp_num); @@ -3850,14 +3844,6 @@ static int hwi_init_port(struct beiscsi_hba *phba) phwi_ctrlr->wrb_context[cri].cid] = async_arr_idx++; } - /** - * Now that the default PDU rings have been created, - * let EP know about it. - */ - beiscsi_hdq_post_handles(phba, BEISCSI_DEFQ_HDR, - ulp_num); - beiscsi_hdq_post_handles(phba, BEISCSI_DEFQ_DATA, - ulp_num); } } @@ -3934,31 +3920,6 @@ static void beiscsi_free_mem(struct beiscsi_hba *phba) kfree(phba->phwi_ctrlr); } -static int beiscsi_init_controller(struct beiscsi_hba *phba) -{ - int ret = -ENOMEM; - - ret = beiscsi_get_memory(phba); - if (ret < 0) { - beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, - "BM_%d : beiscsi_dev_probe -" - "Failed in beiscsi_alloc_memory\n"); - return ret; - } - - ret = hwi_init_controller(phba); - if (ret) - goto free_init; - beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, - "BM_%d : Return success from beiscsi_init_controller"); - - return 0; - -free_init: - beiscsi_free_mem(phba); - return ret; -} - static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) { struct be_mem_descriptor *mem_descr_sglh, *mem_descr_sg; @@ -4089,9 +4050,10 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) } /* Allocate memory for CID array */ - ptr_cid_info->cid_array = kzalloc(sizeof(void *) * - BEISCSI_GET_CID_COUNT(phba, - ulp_num), GFP_KERNEL); + ptr_cid_info->cid_array = + kcalloc(BEISCSI_GET_CID_COUNT(phba, ulp_num), + sizeof(*ptr_cid_info->cid_array), + GFP_KERNEL); if (!ptr_cid_info->cid_array) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Failed to allocate memory" @@ -4231,33 +4193,30 @@ static int beiscsi_init_port(struct beiscsi_hba *phba) { int ret; - ret = beiscsi_init_controller(phba); + ret = hwi_init_controller(phba); if (ret < 0) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, - "BM_%d : beiscsi_dev_probe - Failed in" - "beiscsi_init_controller\n"); + "BM_%d : init controller failed\n"); return ret; } ret = beiscsi_init_sgl_handle(phba); if (ret < 0) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, - "BM_%d : beiscsi_dev_probe - Failed in" - "beiscsi_init_sgl_handle\n"); - goto do_cleanup_ctrlr; + "BM_%d : init sgl handles failed\n"); + goto cleanup_port; } ret = hba_setup_cid_tbls(phba); if (ret < 0) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, - "BM_%d : Failed in hba_setup_cid_tbls\n"); + "BM_%d : setup CID table failed\n"); kfree(phba->io_sgl_hndl_base); kfree(phba->eh_sgl_hndl_base); - goto do_cleanup_ctrlr; + goto cleanup_port; } - return ret; -do_cleanup_ctrlr: +cleanup_port: hwi_cleanup_port(phba); return ret; } @@ -5417,10 +5376,10 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba) phba->shost->max_id = phba->params.cxns_per_ctrl; phba->shost->can_queue = phba->params.ios_per_ctrl; - ret = hwi_init_controller(phba); - if (ret) { + ret = beiscsi_init_port(phba); + if (ret < 0) { __beiscsi_log(phba, KERN_ERR, - "BM_%d : init controller failed %d\n", ret); + "BM_%d : init port failed\n"); goto disable_msix; } @@ -5526,6 +5485,7 @@ static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload) cancel_work_sync(&pbe_eq->mcc_work); } hwi_cleanup_port(phba); + beiscsi_cleanup_port(phba); } static void beiscsi_sess_work(struct work_struct *work) @@ -5638,11 +5598,12 @@ static void beiscsi_eeh_resume(struct pci_dev *pdev) static int beiscsi_dev_probe(struct pci_dev *pcidev, const struct pci_device_id *id) { - struct beiscsi_hba *phba = NULL; - struct hwi_controller *phwi_ctrlr; struct hwi_context_memory *phwi_context; + struct hwi_controller *phwi_ctrlr; + struct beiscsi_hba *phba = NULL; struct be_eq_obj *pbe_eq; unsigned int s_handle; + char wq_name[20]; int ret, i; ret = beiscsi_enable_pci(pcidev); @@ -5680,6 +5641,8 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, case OC_DEVICE_ID2: phba->generation = BE_GEN2; phba->iotask_fn = beiscsi_iotask; + dev_warn(&pcidev->dev, + "Obsolete/Unsupported BE2 Adapter Family\n"); break; case BE_DEVICE_ID2: case OC_DEVICE_ID3: @@ -5735,11 +5698,18 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, phba->shost->max_id = phba->params.cxns_per_ctrl; phba->shost->can_queue = phba->params.ios_per_ctrl; + ret = beiscsi_get_memory(phba); + if (ret < 0) { + beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, + "BM_%d : alloc host mem failed\n"); + goto free_port; + } + ret = beiscsi_init_port(phba); if (ret < 0) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, - "BM_%d : beiscsi_dev_probe-" - "Failed in beiscsi_init_port\n"); + "BM_%d : init port failed\n"); + beiscsi_free_mem(phba); goto free_port; } @@ -5754,9 +5724,9 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0; - snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_%02x_wq", + snprintf(wq_name, sizeof(wq_name), "beiscsi_%02x_wq", phba->shost->host_no); - phba->wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 1, phba->wq_name); + phba->wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 1, wq_name); if (!phba->wq) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : beiscsi_dev_probe-" @@ -5881,7 +5851,6 @@ static void beiscsi_remove(struct pci_dev *pcidev) /* free all resources */ destroy_workqueue(phba->wq); - beiscsi_cleanup_port(phba); beiscsi_free_mem(phba); /* ctrl uninit */ diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 6376657e45f7..218857926566 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h @@ -36,7 +36,7 @@ #include <scsi/scsi_transport_iscsi.h> #define DRV_NAME "be2iscsi" -#define BUILD_STR "11.2.0.0" +#define BUILD_STR "11.2.1.0" #define BE_NAME "Emulex OneConnect" \ "Open-iSCSI Driver version" BUILD_STR #define DRV_DESC BE_NAME " " "Driver" @@ -57,7 +57,6 @@ #define BE2_IO_DEPTH 1024 #define BE2_MAX_SESSIONS 256 -#define BE2_CMDS_PER_CXN 128 #define BE2_TMFS 16 #define BE2_NOPOUT_REQ 16 #define BE2_SGE 32 @@ -72,8 +71,13 @@ #define BEISCSI_SGLIST_ELEMENTS 30 -#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ -#define BEISCSI_MAX_SECTORS 1024 /* scsi_host->max_sectors */ +/** + * BE_INVLDT_CMD_TBL_SZ is 128 which is total number commands that can + * be invalidated at a time, consider it before changing the value of + * BEISCSI_CMD_PER_LUN. + */ +#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ +#define BEISCSI_MAX_SECTORS 1024 /* scsi_host->max_sectors */ #define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */ #define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ @@ -239,19 +243,7 @@ struct hba_parameters { unsigned int num_cq_entries; unsigned int num_eq_entries; unsigned int wrbs_per_cxn; - unsigned int crashmode; - unsigned int hba_num; - - unsigned int mgmt_ws_sz; unsigned int hwi_ws_sz; - - unsigned int eto; - unsigned int ldto; - - unsigned int dbg_flags; - unsigned int num_cxn; - - unsigned int eq_timer; /** * These are calculated from other params. They're here * for debug purposes @@ -272,11 +264,6 @@ struct hba_parameters { unsigned int num_sge; }; -struct invalidate_command_table { - unsigned short icd; - unsigned short cid; -} __packed; - #define BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, cri) \ (phwi_ctrlr->wrb_context[cri].ulp_num) struct hwi_wrb_context { @@ -334,7 +321,6 @@ struct beiscsi_hba { struct be_bus_address pci_pa; /* CSR */ /* PCI representation of our HBA */ struct pci_dev *pcidev; - unsigned short asic_revision; unsigned int num_cpus; unsigned int nxt_cqid; struct msix_entry msix_entries[MAX_CPUS]; @@ -355,9 +341,9 @@ struct beiscsi_hba { spinlock_t io_sgl_lock; spinlock_t mgmt_sgl_lock; spinlock_t async_pdu_lock; - unsigned int age; struct list_head hba_queue; #define BE_MAX_SESSION 2048 +#define BE_INVALID_CID 0xffff #define BE_SET_CID_TO_CRI(cri_index, cid) \ (phba->cid_to_cri_map[cid] = cri_index) #define BE_GET_CRI_FROM_CID(cid) (phba->cid_to_cri_map[cid]) @@ -425,12 +411,10 @@ struct beiscsi_hba { u8 port_name; u8 port_speed; char fw_ver_str[BEISCSI_VER_STRLEN]; - char wq_name[20]; struct workqueue_struct *wq; /* The actuak work queue */ struct be_ctrl_info ctrl; unsigned int generation; unsigned int interface_handle; - struct invalidate_command_table inv_tbl[128]; struct be_aic_obj aic_obj[MAX_CPUS]; unsigned int attr_log_enable; @@ -525,10 +509,6 @@ struct beiscsi_io_task { struct scsi_cmnd *scsi_cmnd; int num_sg; struct hwi_wrb_context *pwrb_context; - unsigned int cmd_sn; - unsigned int flags; - unsigned short cid; - unsigned short header_len; itt_t libiscsi_itt; struct be_cmd_bhs *cmd_bhs; struct be_bus_address bhs_pa; @@ -842,7 +822,7 @@ struct amap_iscsi_wrb_v2 { u8 diff_enbl; /* DWORD 11 */ u8 u_run; /* DWORD 11 */ u8 o_run; /* DWORD 11 */ - u8 invalid; /* DWORD 11 */ + u8 invld; /* DWORD 11 */ u8 dsp; /* DWORD 11 */ u8 dmsg; /* DWORD 11 */ u8 rsvd4; /* DWORD 11 */ @@ -1042,10 +1022,8 @@ struct hwi_controller { struct list_head io_sgl_list; struct list_head eh_sgl_list; struct sgl_handle *psgl_handle_base; - unsigned int wrb_mem_index; struct hwi_wrb_context *wrb_context; - struct mcc_wrb *pmcc_wrb_base; struct be_ring default_pdu_hdr[BEISCSI_ULP_COUNT]; struct be_ring default_pdu_data[BEISCSI_ULP_COUNT]; struct hwi_context_memory *phwi_ctxt; @@ -1062,9 +1040,7 @@ enum hwh_type_enum { }; struct wrb_handle { - enum hwh_type_enum type; unsigned short wrb_index; - struct iscsi_task *pio_handle; struct iscsi_wrb *pwrb; }; diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index ac05317bba7f..2f6d5c2ac329 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -66,7 +66,6 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, struct bsg_job *job, struct be_dma_mem *nonemb_cmd) { - struct be_cmd_resp_hdr *resp; struct be_mcc_wrb *wrb; struct be_sge *mcc_sge; unsigned int tag = 0; @@ -76,7 +75,6 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, nonemb_cmd->size = job->request_payload.payload_len; memset(nonemb_cmd->va, 0, nonemb_cmd->size); - resp = nonemb_cmd->va; region = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3]; @@ -128,50 +126,6 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, return tag; } -unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, - struct invalidate_command_table *inv_tbl, - unsigned int num_invalidate, unsigned int cid, - struct be_dma_mem *nonemb_cmd) - -{ - struct be_ctrl_info *ctrl = &phba->ctrl; - struct be_mcc_wrb *wrb; - struct be_sge *sge; - struct invalidate_commands_params_in *req; - unsigned int i, tag; - - mutex_lock(&ctrl->mbox_lock); - wrb = alloc_mcc_wrb(phba, &tag); - if (!wrb) { - mutex_unlock(&ctrl->mbox_lock); - return 0; - } - - req = nonemb_cmd->va; - memset(req, 0, sizeof(*req)); - sge = nonembedded_sgl(wrb); - - be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, - OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS, - sizeof(*req)); - req->ref_handle = 0; - req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; - for (i = 0; i < num_invalidate; i++) { - req->table[i].icd = inv_tbl->icd; - req->table[i].cid = inv_tbl->cid; - 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); - - be_mcc_notify(phba, tag); - mutex_unlock(&ctrl->mbox_lock); - return tag; -} - unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba, struct beiscsi_endpoint *beiscsi_ep, unsigned short cid, @@ -1066,7 +1020,6 @@ unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba) unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba) { struct be_ctrl_info *ctrl = &phba->ctrl; - struct be_cmd_get_session_resp *resp; struct be_cmd_get_session_req *req; struct be_dma_mem *nonemb_cmd; struct be_mcc_wrb *wrb; @@ -1081,7 +1034,7 @@ unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba) } nonemb_cmd = &phba->boot_struct.nonemb_cmd; - nonemb_cmd->size = sizeof(*resp); + nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp); nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev, nonemb_cmd->size, &nonemb_cmd->dma); @@ -1096,7 +1049,7 @@ unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba) be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, OPCODE_ISCSI_INI_SESSION_GET_A_SESSION, - sizeof(*resp)); + sizeof(struct be_cmd_get_session_resp)); req->session_handle = phba->boot_struct.s_handle; sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); @@ -1309,7 +1262,8 @@ beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr, case BE_DEVICE_ID1: case OC_DEVICE_ID1: case OC_DEVICE_ID2: - return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n"); + return snprintf(buf, PAGE_SIZE, + "Obsolete/Unsupported BE2 Adapter Family\n"); break; case BE_DEVICE_ID2: case OC_DEVICE_ID3: @@ -1341,7 +1295,7 @@ beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr, struct Scsi_Host *shost = class_to_shost(dev); struct beiscsi_hba *phba = iscsi_host_priv(shost); - return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n", + return snprintf(buf, PAGE_SIZE, "Port Identifier : %u\n", phba->fw_config.phys_port); } @@ -1494,3 +1448,64 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params, (params->dw[offsetof(struct amap_beiscsi_offload_params, exp_statsn) / 32] + 1)); } + +int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba, + struct invldt_cmd_tbl *inv_tbl, + unsigned int nents) +{ + struct be_ctrl_info *ctrl = &phba->ctrl; + struct invldt_cmds_params_in *req; + struct be_dma_mem nonemb_cmd; + struct be_mcc_wrb *wrb; + unsigned int i, tag; + struct be_sge *sge; + int rc; + + if (!nents || nents > BE_INVLDT_CMD_TBL_SZ) + return -EINVAL; + + nonemb_cmd.size = sizeof(union be_invldt_cmds_params); + nonemb_cmd.va = pci_zalloc_consistent(phba->ctrl.pdev, + nonemb_cmd.size, + &nonemb_cmd.dma); + if (!nonemb_cmd.va) { + beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH, + "BM_%d : invldt_cmds_params alloc failed\n"); + return -ENOMEM; + } + + mutex_lock(&ctrl->mbox_lock); + wrb = alloc_mcc_wrb(phba, &tag); + if (!wrb) { + mutex_unlock(&ctrl->mbox_lock); + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); + return -ENOMEM; + } + + req = nonemb_cmd.va; + be_wrb_hdr_prepare(wrb, nonemb_cmd.size, false, 1); + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, + OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS, + sizeof(*req)); + req->ref_handle = 0; + req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; + for (i = 0; i < nents; i++) { + req->table[i].icd = inv_tbl[i].icd; + req->table[i].cid = inv_tbl[i].cid; + req->icd_count++; + } + sge = nonembedded_sgl(wrb); + sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); + sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd.dma)); + sge->len = cpu_to_le32(nonemb_cmd.size); + + be_mcc_notify(phba, tag); + mutex_unlock(&ctrl->mbox_lock); + + rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd); + if (rc != -EBUSY) + pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, + nonemb_cmd.va, nonemb_cmd.dma); + return rc; +} diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index b897cfd57c72..308f1472f98a 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h @@ -36,66 +36,6 @@ #define PCICFG_UE_STATUS_MASK_LOW 0xA8 #define PCICFG_UE_STATUS_MASK_HI 0xAC -/** - * Pseudo amap definition in which each bit of the actual structure is defined - * as a byte: used to calculate offset/shift/mask of each field - */ -struct amap_mcc_sge { - u8 pa_lo[32]; /* dword 0 */ - u8 pa_hi[32]; /* dword 1 */ - u8 length[32]; /* DWORD 2 */ -} __packed; - -/** - * Pseudo amap definition in which each bit of the actual structure is defined - * as a byte: used to calculate offset/shift/mask of each field - */ -struct amap_mcc_wrb_payload { - union { - struct amap_mcc_sge sgl[19]; - u8 embedded[59 * 32]; /* DWORDS 57 to 115 */ - } u; -} __packed; - -/** - * Pseudo amap definition in which each bit of the actual structure is defined - * as a byte: used to calculate offset/shift/mask of each field - */ -struct amap_mcc_wrb { - u8 embedded; /* DWORD 0 */ - u8 rsvd0[2]; /* DWORD 0 */ - u8 sge_count[5]; /* DWORD 0 */ - u8 rsvd1[16]; /* DWORD 0 */ - u8 special[8]; /* DWORD 0 */ - u8 payload_length[32]; - u8 tag[64]; /* DWORD 2 */ - u8 rsvd2[32]; /* DWORD 4 */ - struct amap_mcc_wrb_payload payload; -}; - -struct mcc_sge { - u32 pa_lo; /* dword 0 */ - u32 pa_hi; /* dword 1 */ - u32 length; /* DWORD 2 */ -} __packed; - -struct mcc_wrb_payload { - union { - struct mcc_sge sgl[19]; - u32 embedded[59]; /* DWORDS 57 to 115 */ - } u; -} __packed; - -#define MCC_WRB_EMBEDDED_MASK 0x00000001 - -struct mcc_wrb { - u32 dw[0]; /* DWORD 0 */ - u32 payload_length; - u32 tag[2]; /* DWORD 2 */ - u32 rsvd2[1]; /* DWORD 4 */ - struct mcc_wrb_payload payload; -}; - int mgmt_open_connection(struct beiscsi_hba *phba, struct sockaddr *dst_addr, struct beiscsi_endpoint *beiscsi_ep, @@ -104,10 +44,6 @@ int mgmt_open_connection(struct beiscsi_hba *phba, unsigned int mgmt_upload_connection(struct beiscsi_hba *phba, unsigned short cid, unsigned int upload_flag); -unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba, - struct invalidate_command_table *inv_tbl, - unsigned int num_invalidate, unsigned int cid, - struct be_dma_mem *nonemb_cmd); unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba, struct bsg_job *job, @@ -134,24 +70,31 @@ union iscsi_invalidate_connection_params { struct iscsi_invalidate_connection_params_out response; } __packed; -struct invalidate_commands_params_in { +#define BE_INVLDT_CMD_TBL_SZ 128 +struct invldt_cmd_tbl { + unsigned short icd; + unsigned short cid; +} __packed; + +struct invldt_cmds_params_in { struct be_cmd_req_hdr hdr; unsigned int ref_handle; unsigned int icd_count; - struct invalidate_command_table table[128]; + struct invldt_cmd_tbl table[BE_INVLDT_CMD_TBL_SZ]; unsigned short cleanup_type; unsigned short unused; } __packed; -struct invalidate_commands_params_out { +struct invldt_cmds_params_out { + struct be_cmd_resp_hdr hdr; unsigned int ref_handle; unsigned int icd_count; - unsigned int icd_status[128]; + unsigned int icd_status[BE_INVLDT_CMD_TBL_SZ]; } __packed; -union invalidate_commands_params { - struct invalidate_commands_params_in request; - struct invalidate_commands_params_out response; +union be_invldt_cmds_params { + struct invldt_cmds_params_in request; + struct invldt_cmds_params_out response; } __packed; struct mgmt_hba_attributes { @@ -231,16 +174,6 @@ struct be_bsg_vendor_cmd { #define GET_MGMT_CONTROLLER_WS(phba) (phba->pmgmt_ws) -/* MGMT CMD flags */ - -#define MGMT_CMDH_FREE (1<<0) - -/* --- MGMT_ERROR_CODES --- */ -/* Error Codes returned in the status field of the CMD response header */ -#define MGMT_STATUS_SUCCESS 0 /* The CMD completed without errors */ -#define MGMT_STATUS_FAILED 1 /* Error status in the Status field of */ - /* the CMD_RESPONSE_HEADER */ - #define ISCSI_GET_PDU_TEMPLATE_ADDRESS(pc, pa) {\ pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\ bus_address.u.a32.address_lo; \ @@ -270,6 +203,9 @@ unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba, unsigned short cid, unsigned short issue_reset, unsigned short savecfg_flag); +int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba, + struct invldt_cmd_tbl *inv_tbl, + unsigned int nents); int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type); |