/* * Uninitialize the resources used during PQI initialization. */ void pqisrc_pqi_uninit(pqisrc_softstate_t *softs) { int i; DBG_FUNC("IN\n"); if(softs->devlist_lockcreated==true){ os_uninit_spinlock(&softs->devlist_lock); softs->devlist_lockcreated = false; } for (i = 0; i < softs->num_op_raid_ibq; i++) { /* OP RAID IB Q */ if(softs->op_raid_ib_q[i].lockcreated==true){ OS_UNINIT_PQILOCK(&softs->op_raid_ib_q[i].lock); softs->op_raid_ib_q[i].lockcreated = false; } /* OP AIO IB Q */ if(softs->op_aio_ib_q[i].lockcreated==true){ OS_UNINIT_PQILOCK(&softs->op_aio_ib_q[i].lock); softs->op_aio_ib_q[i].lockcreated = false; } } /* Free Op queues */ os_dma_mem_free(softs, &softs->op_ibq_dma_mem); os_dma_mem_free(softs, &softs->op_obq_dma_mem); os_dma_mem_free(softs, &softs->event_q_dma_mem); /* Complete all pending commands. */ os_complete_outstanding_cmds_nodevice(softs); /* Free rcb */ pqisrc_free_rcb(softs, softs->max_outstanding_io + 1); /* Free request id lists */ pqisrc_destroy_taglist(softs,&softs->taglist); if(softs->admin_ib_queue.lockcreated==true){ OS_UNINIT_PQILOCK(&softs->admin_ib_queue.lock); softs->admin_ib_queue.lockcreated = false; } /* Free Admin Queue */ os_dma_mem_free(softs, &softs->admin_queue_dma_mem); /* Switch back to SIS mode */ if (pqisrc_force_sis(softs)) { DBG_ERR("Failed to switch back the adapter to SIS mode!\n"); } DBG_FUNC("OUT\n"); }
/* * Function used to deallocate the used rcb. */ void pqisrc_free_rcb(pqisrc_softstate_t *softs, int req_count) { uint32_t num_req; size_t size; int i; DBG_FUNC("IN\n"); num_req = softs->max_outstanding_io + 1; size = num_req * sizeof(rcb_t); for (i = 1; i < req_count; i++) os_dma_mem_free(softs, &softs->sg_dma_desc[i]); os_mem_free(softs, (void *)softs->rcb, size); softs->rcb = NULL; DBG_FUNC("OUT\n"); }
/* * Request the adapter to get PQI capabilities supported. */ static int pqisrc_report_pqi_capability(pqisrc_softstate_t *softs) { int ret = PQI_STATUS_SUCCESS; DBG_FUNC("IN\n"); gen_adm_req_iu_t admin_req; gen_adm_resp_iu_t admin_resp; dma_mem_t pqi_cap_dma_buf; pqi_dev_cap_t *capability = NULL; pqi_iu_layer_desc_t *iu_layer_desc = NULL; /* Allocate Non DMA memory */ capability = os_mem_alloc(softs, sizeof(*capability)); if (!capability) { DBG_ERR("Failed to allocate memory for capability\n"); ret = PQI_STATUS_FAILURE; goto err_out; } memset(&admin_req, 0, sizeof(admin_req)); memset(&admin_resp, 0, sizeof(admin_resp)); memset(&pqi_cap_dma_buf, 0, sizeof(struct dma_mem)); pqi_cap_dma_buf.tag = "pqi_cap_buf"; pqi_cap_dma_buf.size = REPORT_PQI_DEV_CAP_DATA_BUF_SIZE; pqi_cap_dma_buf.align = PQISRC_DEFAULT_DMA_ALIGN; ret = os_dma_mem_alloc(softs, &pqi_cap_dma_buf); if (ret) { DBG_ERR("Failed to allocate capability DMA buffer : %d\n", ret); goto err_dma_alloc; } admin_req.fn_code = PQI_FUNCTION_REPORT_DEV_CAP; admin_req.req_type.general_func.buf_size = pqi_cap_dma_buf.size; admin_req.req_type.general_func.sg_desc.length = pqi_cap_dma_buf.size; admin_req.req_type.general_func.sg_desc.addr = pqi_cap_dma_buf.dma_addr; admin_req.req_type.general_func.sg_desc.type = SGL_DESCRIPTOR_CODE_DATA_BLOCK; ret = pqisrc_submit_admin_req(softs, &admin_req, &admin_resp); if( PQI_STATUS_SUCCESS == ret) { memcpy(capability, pqi_cap_dma_buf.virt_addr, pqi_cap_dma_buf.size); } else { DBG_ERR("Failed to send admin req report pqi device capability\n"); goto err_admin_req; } softs->pqi_dev_cap.max_iqs = capability->max_iqs; softs->pqi_dev_cap.max_iq_elements = capability->max_iq_elements; softs->pqi_dev_cap.max_iq_elem_len = capability->max_iq_elem_len; softs->pqi_dev_cap.min_iq_elem_len = capability->min_iq_elem_len; softs->pqi_dev_cap.max_oqs = capability->max_oqs; softs->pqi_dev_cap.max_oq_elements = capability->max_oq_elements; softs->pqi_dev_cap.max_oq_elem_len = capability->max_oq_elem_len; softs->pqi_dev_cap.intr_coales_time_granularity = capability->intr_coales_time_granularity; iu_layer_desc = &capability->iu_layer_desc[PQI_PROTOCOL_SOP]; softs->max_ib_iu_length_per_fw = iu_layer_desc->max_ib_iu_len; softs->ib_spanning_supported = iu_layer_desc->ib_spanning_supported; softs->ob_spanning_supported = iu_layer_desc->ob_spanning_supported; DBG_INIT("softs->pqi_dev_cap.max_iqs: %d\n", softs->pqi_dev_cap.max_iqs); DBG_INIT("softs->pqi_dev_cap.max_iq_elements: %d\n", softs->pqi_dev_cap.max_iq_elements); DBG_INIT("softs->pqi_dev_cap.max_iq_elem_len: %d\n", softs->pqi_dev_cap.max_iq_elem_len); DBG_INIT("softs->pqi_dev_cap.min_iq_elem_len: %d\n", softs->pqi_dev_cap.min_iq_elem_len); DBG_INIT("softs->pqi_dev_cap.max_oqs: %d\n", softs->pqi_dev_cap.max_oqs); DBG_INIT("softs->pqi_dev_cap.max_oq_elements: %d\n", softs->pqi_dev_cap.max_oq_elements); DBG_INIT("softs->pqi_dev_cap.max_oq_elem_len: %d\n", softs->pqi_dev_cap.max_oq_elem_len); DBG_INIT("softs->pqi_dev_cap.intr_coales_time_granularity: %d\n", softs->pqi_dev_cap.intr_coales_time_granularity); DBG_INIT("softs->max_ib_iu_length_per_fw: %d\n", softs->max_ib_iu_length_per_fw); DBG_INIT("softs->ib_spanning_supported: %d\n", softs->ib_spanning_supported); DBG_INIT("softs->ob_spanning_supported: %d\n", softs->ob_spanning_supported); os_mem_free(softs, (void *)capability, REPORT_PQI_DEV_CAP_DATA_BUF_SIZE); os_dma_mem_free(softs, &pqi_cap_dma_buf); DBG_FUNC("OUT\n"); return ret; err_admin_req: os_dma_mem_free(softs, &pqi_cap_dma_buf); err_dma_alloc: if (capability) os_mem_free(softs, (void *)capability, REPORT_PQI_DEV_CAP_DATA_BUF_SIZE); err_out: DBG_FUNC("failed OUT\n"); return PQI_STATUS_FAILURE; }