Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/smartpqi/smartpqi_init.c
Show First 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | static int pqisrc_report_pqi_capability(pqisrc_softstate_t *softs) | ||||
softs->pqi_dev_cap.max_oq_elem_len = capability->max_oq_elem_len; | 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; | softs->pqi_dev_cap.intr_coales_time_granularity = capability->intr_coales_time_granularity; | ||||
iu_layer_desc = &capability->iu_layer_desc[PQI_PROTOCOL_SOP]; | 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->max_ib_iu_length_per_fw = iu_layer_desc->max_ib_iu_len; | ||||
softs->ib_spanning_supported = iu_layer_desc->ib_spanning_supported; | softs->ib_spanning_supported = iu_layer_desc->ib_spanning_supported; | ||||
softs->ob_spanning_supported = iu_layer_desc->ob_spanning_supported; | softs->ob_spanning_supported = iu_layer_desc->ob_spanning_supported; | ||||
DBG_INFO("softs->pqi_dev_cap.max_iqs: %d\n", softs->pqi_dev_cap.max_iqs); | DBG_INIT("softs->pqi_dev_cap.max_iqs: %d\n", softs->pqi_dev_cap.max_iqs); | ||||
DBG_INFO("softs->pqi_dev_cap.max_iq_elements: %d\n", softs->pqi_dev_cap.max_iq_elements); | DBG_INIT("softs->pqi_dev_cap.max_iq_elements: %d\n", softs->pqi_dev_cap.max_iq_elements); | ||||
DBG_INFO("softs->pqi_dev_cap.max_iq_elem_len: %d\n", softs->pqi_dev_cap.max_iq_elem_len); | DBG_INIT("softs->pqi_dev_cap.max_iq_elem_len: %d\n", softs->pqi_dev_cap.max_iq_elem_len); | ||||
DBG_INFO("softs->pqi_dev_cap.min_iq_elem_len: %d\n", softs->pqi_dev_cap.min_iq_elem_len); | DBG_INIT("softs->pqi_dev_cap.min_iq_elem_len: %d\n", softs->pqi_dev_cap.min_iq_elem_len); | ||||
DBG_INFO("softs->pqi_dev_cap.max_oqs: %d\n", softs->pqi_dev_cap.max_oqs); | DBG_INIT("softs->pqi_dev_cap.max_oqs: %d\n", softs->pqi_dev_cap.max_oqs); | ||||
DBG_INFO("softs->pqi_dev_cap.max_oq_elements: %d\n", softs->pqi_dev_cap.max_oq_elements); | DBG_INIT("softs->pqi_dev_cap.max_oq_elements: %d\n", softs->pqi_dev_cap.max_oq_elements); | ||||
DBG_INFO("softs->pqi_dev_cap.max_oq_elem_len: %d\n", softs->pqi_dev_cap.max_oq_elem_len); | DBG_INIT("softs->pqi_dev_cap.max_oq_elem_len: %d\n", softs->pqi_dev_cap.max_oq_elem_len); | ||||
DBG_INFO("softs->pqi_dev_cap.intr_coales_time_granularity: %d\n", softs->pqi_dev_cap.intr_coales_time_granularity); | DBG_INIT("softs->pqi_dev_cap.intr_coales_time_granularity: %d\n", softs->pqi_dev_cap.intr_coales_time_granularity); | ||||
DBG_INFO("softs->max_ib_iu_length_per_fw: %d\n", softs->max_ib_iu_length_per_fw); | DBG_INIT("softs->max_ib_iu_length_per_fw: %d\n", softs->max_ib_iu_length_per_fw); | ||||
DBG_INFO("softs->ib_spanning_supported: %d\n", softs->ib_spanning_supported); | DBG_INIT("softs->ib_spanning_supported: %d\n", softs->ib_spanning_supported); | ||||
DBG_INFO("softs->ob_spanning_supported: %d\n", softs->ob_spanning_supported); | DBG_INIT("softs->ob_spanning_supported: %d\n", softs->ob_spanning_supported); | ||||
os_mem_free(softs, (void *)capability, | os_mem_free(softs, (void *)capability, | ||||
REPORT_PQI_DEV_CAP_DATA_BUF_SIZE); | REPORT_PQI_DEV_CAP_DATA_BUF_SIZE); | ||||
os_dma_mem_free(softs, &pqi_cap_dma_buf); | os_dma_mem_free(softs, &pqi_cap_dma_buf); | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
return ret; | return ret; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | static int pqisrc_allocate_rcb(pqisrc_softstate_t *softs) | ||||
uint64_t alloc_size = 0; | uint64_t alloc_size = 0; | ||||
rcb_t *rcb = NULL; | rcb_t *rcb = NULL; | ||||
rcb_t *prcb = NULL; | rcb_t *prcb = NULL; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
/* Set maximum outstanding requests */ | /* Set maximum outstanding requests */ | ||||
/* The valid tag values are from 1, 2, ..., softs->max_outstanding_io | /* The valid tag values are from 1, 2, ..., softs->max_outstanding_io | ||||
* The rcb will be accessed by using the tag as index | * The rcb will be accessed by using the tag as index | ||||
* As 0 tag index is not used, we need to allocate one extra. | * * As 0 tag index is not used, we need to allocate one extra. | ||||
*/ | */ | ||||
softs->max_outstanding_io = softs->pqi_cap.max_outstanding_io; | softs->max_outstanding_io = softs->pqi_cap.max_outstanding_io; | ||||
num_req = softs->max_outstanding_io + 1; | num_req = softs->max_outstanding_io + 1; | ||||
DBG_INFO("Max Outstanding IO reset to %d\n", num_req); | DBG_INIT("Max Outstanding IO reset to %d\n", num_req); | ||||
alloc_size = num_req * sizeof(rcb_t); | alloc_size = num_req * sizeof(rcb_t); | ||||
/* Allocate Non DMA memory */ | /* Allocate Non DMA memory */ | ||||
rcb = os_mem_alloc(softs, alloc_size); | rcb = os_mem_alloc(softs, alloc_size); | ||||
if (!rcb) { | if (!rcb) { | ||||
DBG_ERR("Failed to allocate memory for rcb\n"); | DBG_ERR("Failed to allocate memory for rcb\n"); | ||||
ret = PQI_STATUS_FAILURE; | ret = PQI_STATUS_FAILURE; | ||||
Show All 39 Lines | |||||
* - no of ibq/obq, shared/non-shared interrupt resource, IU spanning support | * - no of ibq/obq, shared/non-shared interrupt resource, IU spanning support | ||||
*/ | */ | ||||
void pqisrc_decide_opq_config(pqisrc_softstate_t *softs) | void pqisrc_decide_opq_config(pqisrc_softstate_t *softs) | ||||
{ | { | ||||
uint16_t total_iq_elements; | uint16_t total_iq_elements; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
DBG_INFO("softs->intr_count : %d softs->num_cpus_online : %d", | DBG_INIT("softs->intr_count : %d softs->num_cpus_online : %d", | ||||
softs->intr_count, softs->num_cpus_online); | softs->intr_count, softs->num_cpus_online); | ||||
if (softs->intr_count == 1 || softs->num_cpus_online == 1) { | if (softs->intr_count == 1 || softs->num_cpus_online == 1) { | ||||
/* Share the event and Operational queue. */ | /* Share the event and Operational queue. */ | ||||
softs->num_op_obq = 1; | softs->num_op_obq = 1; | ||||
softs->share_opq_and_eventq = true; | softs->share_opq_and_eventq = true; | ||||
} | } | ||||
else { | else { | ||||
/* Note : One OBQ (OBQ0) reserved for event queue */ | /* Note : One OBQ (OBQ0) reserved for event queue */ | ||||
softs->num_op_obq = MIN(softs->num_cpus_online, | softs->num_op_obq = MIN(softs->num_cpus_online, | ||||
softs->intr_count) - 1; | softs->intr_count) - 1; | ||||
softs->num_op_obq = softs->intr_count - 1; | softs->num_op_obq = softs->intr_count - 1; | ||||
softs->share_opq_and_eventq = false; | softs->share_opq_and_eventq = false; | ||||
} | } | ||||
#ifdef MULTIPLE_MSIX | |||||
/* | /* | ||||
* softs->num_cpus_online is set as number of physical CPUs, | * softs->num_cpus_online is set as number of physical CPUs, | ||||
* So we can have more queues/interrupts . | * So we can have more queues/interrupts . | ||||
*/ | */ | ||||
if (softs->intr_count > 1) | if (softs->intr_count > 1) | ||||
softs->share_opq_and_eventq = false; | softs->share_opq_and_eventq = false; | ||||
#endif | |||||
DBG_INFO("softs->num_op_obq : %d\n",softs->num_op_obq); | DBG_INIT("softs->num_op_obq : %d\n",softs->num_op_obq); | ||||
softs->num_op_raid_ibq = softs->num_op_obq; | softs->num_op_raid_ibq = softs->num_op_obq; | ||||
softs->num_op_aio_ibq = softs->num_op_raid_ibq; | softs->num_op_aio_ibq = softs->num_op_raid_ibq; | ||||
softs->ibq_elem_size = softs->pqi_dev_cap.max_iq_elem_len * 16; | softs->ibq_elem_size = softs->pqi_dev_cap.max_iq_elem_len * 16; | ||||
softs->obq_elem_size = softs->pqi_dev_cap.max_oq_elem_len * 16; | softs->obq_elem_size = softs->pqi_dev_cap.max_oq_elem_len * 16; | ||||
if (softs->max_ib_iu_length_per_fw == 256 && | if (softs->max_ib_iu_length_per_fw == 256 && | ||||
softs->ob_spanning_supported) { | softs->ob_spanning_supported) { | ||||
/* older f/w that doesn't actually support spanning. */ | /* older f/w that doesn't actually support spanning. */ | ||||
Show All 19 Lines | void pqisrc_decide_opq_config(pqisrc_softstate_t *softs) | ||||
softs->num_elem_per_op_obq = MIN(softs->num_elem_per_op_obq, | softs->num_elem_per_op_obq = MIN(softs->num_elem_per_op_obq, | ||||
softs->pqi_dev_cap.max_oq_elements); | softs->pqi_dev_cap.max_oq_elements); | ||||
softs->max_sg_per_iu = ((softs->max_ib_iu_length - | softs->max_sg_per_iu = ((softs->max_ib_iu_length - | ||||
softs->ibq_elem_size) / | softs->ibq_elem_size) / | ||||
sizeof(sgt_t)) + | sizeof(sgt_t)) + | ||||
MAX_EMBEDDED_SG_IN_FIRST_IU; | MAX_EMBEDDED_SG_IN_FIRST_IU; | ||||
DBG_INFO("softs->max_ib_iu_length: %d\n", softs->max_ib_iu_length); | DBG_INIT("softs->max_ib_iu_length: %d\n", softs->max_ib_iu_length); | ||||
DBG_INFO("softs->num_elem_per_op_ibq: %d\n", softs->num_elem_per_op_ibq); | DBG_INIT("softs->num_elem_per_op_ibq: %d\n", softs->num_elem_per_op_ibq); | ||||
DBG_INFO("softs->num_elem_per_op_obq: %d\n", softs->num_elem_per_op_obq); | DBG_INIT("softs->num_elem_per_op_obq: %d\n", softs->num_elem_per_op_obq); | ||||
DBG_INFO("softs->max_sg_per_iu: %d\n", softs->max_sg_per_iu); | DBG_INIT("softs->max_sg_per_iu: %d\n", softs->max_sg_per_iu); | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
} | } | ||||
/* | /* | ||||
* Configure the operational queue parameters. | * Configure the operational queue parameters. | ||||
*/ | */ | ||||
int pqisrc_configure_op_queues(pqisrc_softstate_t *softs) | int pqisrc_configure_op_queues(pqisrc_softstate_t *softs) | ||||
▲ Show 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | int pqisrc_wait_for_pqi_reset_completion(pqisrc_softstate_t *softs) | ||||
int pqi_reset_timeout = 0; | int pqi_reset_timeout = 0; | ||||
uint64_t val = 0; | uint64_t val = 0; | ||||
uint32_t max_timeout = 0; | uint32_t max_timeout = 0; | ||||
val = PCI_MEM_GET64(softs, &softs->pqi_reg->pqi_dev_adminq_cap, PQI_ADMINQ_CAP); | val = PCI_MEM_GET64(softs, &softs->pqi_reg->pqi_dev_adminq_cap, PQI_ADMINQ_CAP); | ||||
max_timeout = (val & 0xFFFF00000000) >> 32; | max_timeout = (val & 0xFFFF00000000) >> 32; | ||||
DBG_INFO("max_timeout for PQI reset completion in 100 msec units = %u\n", max_timeout); | DBG_INIT("max_timeout for PQI reset completion in 100 msec units = %u\n", max_timeout); | ||||
while(1) { | while(1) { | ||||
if (pqi_reset_timeout++ == max_timeout) { | if (pqi_reset_timeout++ == max_timeout) { | ||||
return PQI_STATUS_TIMEOUT; | return PQI_STATUS_TIMEOUT; | ||||
} | } | ||||
OS_SLEEP(PQI_RESET_POLL_INTERVAL);/* 100 msec */ | OS_SLEEP(PQI_RESET_POLL_INTERVAL);/* 100 msec */ | ||||
reset_reg.all_bits = PCI_MEM_GET32(softs, | reset_reg.all_bits = PCI_MEM_GET32(softs, | ||||
&softs->pqi_reg->dev_reset, PQI_DEV_RESET); | &softs->pqi_reg->dev_reset, PQI_DEV_RESET); | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | int pqisrc_pqi_init(pqisrc_softstate_t *softs) | ||||
/* Get the No. of Online CPUs,NUMA/Processor config from OS */ | /* Get the No. of Online CPUs,NUMA/Processor config from OS */ | ||||
ret = os_get_processor_config(softs); | ret = os_get_processor_config(softs); | ||||
if (ret) { | if (ret) { | ||||
DBG_ERR("Failed to get processor config from OS %d\n", | DBG_ERR("Failed to get processor config from OS %d\n", | ||||
ret); | ret); | ||||
goto err_out; | goto err_out; | ||||
} | } | ||||
softs->intr_type = INTR_TYPE_NONE; | |||||
/* Get the interrupt count, type, priority available from OS */ | /* Get the interrupt count, type, priority available from OS */ | ||||
ret = os_get_intr_config(softs); | ret = os_get_intr_config(softs); | ||||
if (ret) { | if (ret) { | ||||
DBG_ERR("Failed to get interrupt config from OS %d\n", | DBG_ERR("Failed to get interrupt config from OS %d\n", | ||||
ret); | ret); | ||||
goto err_out; | goto err_out; | ||||
} | } | ||||
/*Enable/Set Legacy INTx Interrupt mask clear pqi register, | |||||
*if allocated interrupt is legacy type. | |||||
*/ | |||||
if (INTR_TYPE_FIXED == softs->intr_type) { | |||||
pqisrc_configure_legacy_intx(softs, true); | |||||
sis_enable_intx(softs); | |||||
} | |||||
/* Create Admin Queue pair*/ | /* Create Admin Queue pair*/ | ||||
ret = pqisrc_create_admin_queue(softs); | ret = pqisrc_create_admin_queue(softs); | ||||
if(ret) { | if(ret) { | ||||
DBG_ERR("Failed to configure admin queue\n"); | DBG_ERR("Failed to configure admin queue\n"); | ||||
goto err_admin_queue; | goto err_admin_queue; | ||||
} | } | ||||
/* For creating event and IO operational queues we have to submit | /* For creating event and IO operational queues we have to submit | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* */ | /* */ | ||||
int pqisrc_force_sis(pqisrc_softstate_t *softs) | int pqisrc_force_sis(pqisrc_softstate_t *softs) | ||||
{ | { | ||||
int ret = PQI_STATUS_SUCCESS; | int ret = PQI_STATUS_SUCCESS; | ||||
if (SIS_IS_KERNEL_PANIC(softs)) { | if (SIS_IS_KERNEL_PANIC(softs)) { | ||||
DBG_INFO("Controller FW is not runnning"); | DBG_INIT("Controller FW is not runnning"); | ||||
return PQI_STATUS_FAILURE; | return PQI_STATUS_FAILURE; | ||||
} | } | ||||
if (PQI_GET_CTRL_MODE(softs) == CTRL_SIS_MODE) { | if (PQI_GET_CTRL_MODE(softs) == CTRL_SIS_MODE) { | ||||
return ret; | return ret; | ||||
} | } | ||||
if (SIS_IS_KERNEL_UP(softs)) { | if (SIS_IS_KERNEL_UP(softs)) { | ||||
PQI_SAVE_CTRL_MODE(softs, CTRL_SIS_MODE); | PQI_SAVE_CTRL_MODE(softs, CTRL_SIS_MODE); | ||||
return ret; | return ret; | ||||
} | } | ||||
/* Disable interrupts ? */ | /* Disable interrupts ? */ | ||||
sis_disable_msix(softs); | sis_disable_interrupt(softs); | ||||
/* reset pqi, this will delete queues */ | /* reset pqi, this will delete queues */ | ||||
ret = pqi_reset(softs); | ret = pqi_reset(softs); | ||||
if (ret) { | if (ret) { | ||||
return ret; | return ret; | ||||
} | } | ||||
/* Re enable SIS */ | /* Re enable SIS */ | ||||
ret = pqisrc_reenable_sis(softs); | ret = pqisrc_reenable_sis(softs); | ||||
if (ret) { | if (ret) { | ||||
return ret; | return ret; | ||||
} | } | ||||
PQI_SAVE_CTRL_MODE(softs, CTRL_SIS_MODE); | PQI_SAVE_CTRL_MODE(softs, CTRL_SIS_MODE); | ||||
return ret; | return ret; | ||||
} | } | ||||
int pqisrc_wait_for_cmnd_complete(pqisrc_softstate_t *softs) | |||||
{ | |||||
int ret = PQI_STATUS_SUCCESS; | |||||
int tmo = PQI_CMND_COMPLETE_TMO; | |||||
COND_WAIT((softs->taglist.num_elem == softs->max_outstanding_io), tmo); | |||||
if (!tmo) { | |||||
DBG_ERR("Pending commands %x!!!",softs->taglist.num_elem); | |||||
ret = PQI_STATUS_TIMEOUT; | |||||
} | |||||
return ret; | |||||
} | |||||
void pqisrc_complete_internal_cmds(pqisrc_softstate_t *softs) | |||||
{ | |||||
int tag = 0; | |||||
rcb_t *rcb; | |||||
for (tag = 1; tag <= softs->max_outstanding_io; tag++) { | |||||
rcb = &softs->rcb[tag]; | |||||
if(rcb->req_pending && is_internal_req(rcb)) { | |||||
rcb->status = REQUEST_FAILED; | |||||
rcb->req_pending = false; | |||||
} | |||||
} | |||||
} | |||||
/* | /* | ||||
* Uninitialize the resources used during PQI initialization. | * Uninitialize the resources used during PQI initialization. | ||||
*/ | */ | ||||
void pqisrc_pqi_uninit(pqisrc_softstate_t *softs) | void pqisrc_pqi_uninit(pqisrc_softstate_t *softs) | ||||
{ | { | ||||
int i; | int i, ret; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
/* Wait for any rescan to finish */ | |||||
pqisrc_wait_for_rescan_complete(softs); | |||||
/* Wait for commands to complete */ | |||||
ret = pqisrc_wait_for_cmnd_complete(softs); | |||||
/* Complete all pending commands. */ | |||||
if(ret != PQI_STATUS_SUCCESS) { | |||||
pqisrc_complete_internal_cmds(softs); | |||||
os_complete_outstanding_cmds_nodevice(softs); | |||||
} | |||||
if(softs->devlist_lockcreated==true){ | if(softs->devlist_lockcreated==true){ | ||||
os_uninit_spinlock(&softs->devlist_lock); | os_uninit_spinlock(&softs->devlist_lock); | ||||
softs->devlist_lockcreated = false; | softs->devlist_lockcreated = false; | ||||
} | } | ||||
for (i = 0; i < softs->num_op_raid_ibq; i++) { | for (i = 0; i < softs->num_op_raid_ibq; i++) { | ||||
/* OP RAID IB Q */ | /* OP RAID IB Q */ | ||||
if(softs->op_raid_ib_q[i].lockcreated==true){ | if(softs->op_raid_ib_q[i].lockcreated==true){ | ||||
OS_UNINIT_PQILOCK(&softs->op_raid_ib_q[i].lock); | OS_UNINIT_PQILOCK(&softs->op_raid_ib_q[i].lock); | ||||
softs->op_raid_ib_q[i].lockcreated = false; | softs->op_raid_ib_q[i].lockcreated = false; | ||||
} | } | ||||
/* OP AIO IB Q */ | /* OP AIO IB Q */ | ||||
if(softs->op_aio_ib_q[i].lockcreated==true){ | if(softs->op_aio_ib_q[i].lockcreated==true){ | ||||
OS_UNINIT_PQILOCK(&softs->op_aio_ib_q[i].lock); | OS_UNINIT_PQILOCK(&softs->op_aio_ib_q[i].lock); | ||||
softs->op_aio_ib_q[i].lockcreated = false; | softs->op_aio_ib_q[i].lockcreated = false; | ||||
} | } | ||||
} | } | ||||
/* Free Op queues */ | /* Free Op queues */ | ||||
os_dma_mem_free(softs, &softs->op_ibq_dma_mem); | 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->op_obq_dma_mem); | ||||
os_dma_mem_free(softs, &softs->event_q_dma_mem); | os_dma_mem_free(softs, &softs->event_q_dma_mem); | ||||
/* Complete all pending commands. */ | |||||
os_complete_outstanding_cmds_nodevice(softs); | |||||
/* Free rcb */ | /* Free rcb */ | ||||
pqisrc_free_rcb(softs, softs->max_outstanding_io + 1); | pqisrc_free_rcb(softs, softs->max_outstanding_io + 1); | ||||
/* Free request id lists */ | /* Free request id lists */ | ||||
pqisrc_destroy_taglist(softs,&softs->taglist); | pqisrc_destroy_taglist(softs,&softs->taglist); | ||||
if(softs->admin_ib_queue.lockcreated==true){ | if(softs->admin_ib_queue.lockcreated==true){ | ||||
OS_UNINIT_PQILOCK(&softs->admin_ib_queue.lock); | OS_UNINIT_PQILOCK(&softs->admin_ib_queue.lock); | ||||
softs->admin_ib_queue.lockcreated = false; | softs->admin_ib_queue.lockcreated = false; | ||||
} | } | ||||
/* Free Admin Queue */ | /* Free Admin Queue */ | ||||
os_dma_mem_free(softs, &softs->admin_queue_dma_mem); | os_dma_mem_free(softs, &softs->admin_queue_dma_mem); | ||||
/* Switch back to SIS mode */ | /* Switch back to SIS mode */ | ||||
if (pqisrc_force_sis(softs)) { | if (pqisrc_force_sis(softs)) { | ||||
DBG_ERR("Failed to switch back the adapter to SIS mode!\n"); | DBG_ERR("Failed to switch back the adapter to SIS mode!\n"); | ||||
} | } | ||||
Show All 15 Lines | int pqisrc_init(pqisrc_softstate_t *softs) | ||||
/* Init the Sync interface */ | /* Init the Sync interface */ | ||||
ret = pqisrc_sis_init(softs); | ret = pqisrc_sis_init(softs); | ||||
if (ret) { | if (ret) { | ||||
DBG_ERR("SIS Init failed with error %d\n", ret); | DBG_ERR("SIS Init failed with error %d\n", ret); | ||||
goto err_out; | goto err_out; | ||||
} | } | ||||
ret = os_create_semaphore("scan_lock", 1, &softs->scan_lock); | |||||
if(ret != PQI_STATUS_SUCCESS){ | |||||
DBG_ERR(" Failed to initialize scan lock\n"); | |||||
goto err_scan_lock; | |||||
} | |||||
/* Init the PQI interface */ | /* Init the PQI interface */ | ||||
ret = pqisrc_pqi_init(softs); | ret = pqisrc_pqi_init(softs); | ||||
if (ret) { | if (ret) { | ||||
DBG_ERR("PQI Init failed with error %d\n", ret); | DBG_ERR("PQI Init failed with error %d\n", ret); | ||||
goto err_pqi; | goto err_pqi; | ||||
} | } | ||||
/* Setup interrupt */ | /* Setup interrupt */ | ||||
Show All 36 Lines | int pqisrc_init(pqisrc_softstate_t *softs) | ||||
ret = os_init_spinlock(softs, &softs->devlist_lock, softs->devlist_lock_name); | ret = os_init_spinlock(softs, &softs->devlist_lock, softs->devlist_lock_name); | ||||
if(ret){ | if(ret){ | ||||
DBG_ERR(" Failed to initialize devlist_lock\n"); | DBG_ERR(" Failed to initialize devlist_lock\n"); | ||||
softs->devlist_lockcreated=false; | softs->devlist_lockcreated=false; | ||||
goto err_lock; | goto err_lock; | ||||
} | } | ||||
softs->devlist_lockcreated = true; | softs->devlist_lockcreated = true; | ||||
ret = os_create_semaphore("scan_lock", 1, &softs->scan_lock); | |||||
if(ret != PQI_STATUS_SUCCESS){ | |||||
DBG_ERR(" Failed to initialize scan lock\n"); | |||||
goto err_scan_lock; | |||||
} | |||||
OS_ATOMIC64_SET(softs, num_intrs, 0); | OS_ATOMIC64_SET(softs, num_intrs, 0); | ||||
softs->prev_num_intrs = softs->num_intrs; | softs->prev_num_intrs = softs->num_intrs; | ||||
/* Get the PQI configuration table to read heart-beat counter*/ | /* Get the PQI configuration table to read heart-beat counter*/ | ||||
if (PQI_NEW_HEARTBEAT_MECHANISM(softs)) { | if (PQI_NEW_HEARTBEAT_MECHANISM(softs)) { | ||||
ret = pqisrc_process_config_table(softs); | ret = pqisrc_process_config_table(softs); | ||||
if (ret) { | if (ret) { | ||||
DBG_ERR("Failed to process PQI configuration table %d\n", ret); | DBG_ERR("Failed to process PQI configuration table %d\n", ret); | ||||
goto err_config_tab; | goto err_config_tab; | ||||
} | } | ||||
} | } | ||||
if (PQI_NEW_HEARTBEAT_MECHANISM(softs)) | if (PQI_NEW_HEARTBEAT_MECHANISM(softs)) | ||||
softs->prev_heartbeat_count = CTRLR_HEARTBEAT_CNT(softs) - OS_FW_HEARTBEAT_TIMER_INTERVAL; | softs->prev_heartbeat_count = CTRLR_HEARTBEAT_CNT(softs) - OS_FW_HEARTBEAT_TIMER_INTERVAL; | ||||
/* Init device list */ | /* Init device list */ | ||||
for(i = 0; i < PQI_MAX_DEVICES; i++) | for(i = 0; i < PQI_MAX_DEVICES; i++) | ||||
for(j = 0; j < PQI_MAX_MULTILUN; j++) | for(j = 0; j < PQI_MAX_MULTILUN; j++) | ||||
softs->device_list[i][j] = NULL; | softs->device_list[i][j] = NULL; | ||||
pqisrc_init_targetid_pool(softs); | |||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
return ret; | return ret; | ||||
err_config_tab: | err_config_tab: | ||||
os_destroy_semaphore(&softs->scan_lock); | |||||
err_scan_lock: | |||||
if(softs->devlist_lockcreated==true){ | if(softs->devlist_lockcreated==true){ | ||||
os_uninit_spinlock(&softs->devlist_lock); | os_uninit_spinlock(&softs->devlist_lock); | ||||
softs->devlist_lockcreated = false; | softs->devlist_lockcreated = false; | ||||
} | } | ||||
err_lock: | err_lock: | ||||
err_fw_version: | err_fw_version: | ||||
err_event: | err_event: | ||||
err_host_wellness: | err_host_wellness: | ||||
os_destroy_intr(softs); | os_destroy_intr(softs); | ||||
err_intr: | err_intr: | ||||
pqisrc_pqi_uninit(softs); | pqisrc_pqi_uninit(softs); | ||||
err_pqi: | err_pqi: | ||||
os_destroy_semaphore(&softs->scan_lock); | |||||
err_scan_lock: | |||||
pqisrc_sis_uninit(softs); | pqisrc_sis_uninit(softs); | ||||
err_out: | err_out: | ||||
DBG_FUNC("OUT failed\n"); | DBG_FUNC("OUT failed\n"); | ||||
return ret; | return ret; | ||||
} | } | ||||
/* | /* | ||||
* Write all data in the adapter's battery-backed cache to | * Write all data in the adapter's battery-backed cache to | ||||
Show All 40 Lines | |||||
/* | /* | ||||
* Uninitialize the adapter. | * Uninitialize the adapter. | ||||
*/ | */ | ||||
void pqisrc_uninit(pqisrc_softstate_t *softs) | void pqisrc_uninit(pqisrc_softstate_t *softs) | ||||
{ | { | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
os_destroy_intr(softs); | |||||
os_destroy_semaphore(&softs->scan_lock); | |||||
pqisrc_pqi_uninit(softs); | pqisrc_pqi_uninit(softs); | ||||
pqisrc_sis_uninit(softs); | pqisrc_sis_uninit(softs); | ||||
os_destroy_semaphore(&softs->scan_lock); | |||||
os_destroy_intr(softs); | |||||
pqisrc_cleanup_devices(softs); | pqisrc_cleanup_devices(softs); | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
} | } |