Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/smartpqi/smartpqi_intr.c
/*- | /*- | ||||
* Copyright (c) 2018 Microsemi Corporation. | * Copyright 2016-2021 Microchip Technology, Inc. and/or its subsidiaries. | ||||
* All rights reserved. | |||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
* notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the | ||||
Show All 11 Lines | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
/* $FreeBSD$ */ | /* $FreeBSD$ */ | ||||
#include "smartpqi_includes.h" | #include "smartpqi_includes.h" | ||||
/* | /* | ||||
* Function to get processor count | * Function to get processor count | ||||
*/ | */ | ||||
int os_get_processor_config(pqisrc_softstate_t *softs) | int | ||||
os_get_processor_config(pqisrc_softstate_t *softs) | |||||
{ | { | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
softs->num_cpus_online = mp_ncpus; | softs->num_cpus_online = mp_ncpus; | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
return PQI_STATUS_SUCCESS; | return PQI_STATUS_SUCCESS; | ||||
} | } | ||||
/* | /* | ||||
* Function to get interrupt count and type supported | * Function to get interrupt count and type supported | ||||
*/ | */ | ||||
int os_get_intr_config(pqisrc_softstate_t *softs) | int | ||||
os_get_intr_config(pqisrc_softstate_t *softs) | |||||
{ | { | ||||
device_t dev; | device_t dev = softs->os_specific.pqi_dev; | ||||
int msi_count = 0; | int msi_count = pci_msix_count(dev); | ||||
int error = 0; | int error = BSD_SUCCESS; | ||||
int ret = PQI_STATUS_SUCCESS; | |||||
dev = softs->os_specific.pqi_dev; | |||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
msi_count = pci_msix_count(dev); | |||||
if (msi_count > softs->num_cpus_online) | if (msi_count > softs->num_cpus_online) | ||||
msi_count = softs->num_cpus_online; | msi_count = softs->num_cpus_online; | ||||
if (msi_count > PQI_MAX_MSIX) | if (msi_count > PQI_MAX_MSIX) | ||||
msi_count = PQI_MAX_MSIX; | msi_count = PQI_MAX_MSIX; | ||||
if (msi_count == 0 || (error = pci_alloc_msix(dev, &msi_count)) != 0) { | if (msi_count == 0 || (error = pci_alloc_msix(dev, &msi_count)) != 0) { | ||||
device_printf(dev, "alloc msix failed - msi_count=%d, err=%d; " | device_printf(dev, "alloc msix failed - msi_count=%d, err=%d; " | ||||
"will try MSI\n", msi_count, error); | "will try MSI\n", msi_count, error); | ||||
pci_release_msi(dev); | pci_release_msi(dev); | ||||
Show All 19 Lines | os_get_intr_config(pqisrc_softstate_t *softs) | ||||
} | } | ||||
if (!softs->intr_type) { | if (!softs->intr_type) { | ||||
device_printf(dev, "using legacy interrupts\n"); | device_printf(dev, "using legacy interrupts\n"); | ||||
softs->intr_type = INTR_TYPE_FIXED; | softs->intr_type = INTR_TYPE_FIXED; | ||||
softs->intr_count = 1; | softs->intr_count = 1; | ||||
} | } | ||||
if(!softs->intr_type) { | |||||
DBG_FUNC("OUT failed\n"); | |||||
ret = PQI_STATUS_FAILURE; | |||||
return ret; | |||||
} | |||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
return ret; | |||||
error = bsd_status_to_pqi_status(BSD_SUCCESS); | |||||
return error; | |||||
} | } | ||||
void os_eventtaskqueue_enqueue(pqisrc_softstate_t *sc) | void | ||||
os_eventtaskqueue_enqueue(pqisrc_softstate_t *sc) | |||||
{ | { | ||||
taskqueue_enqueue(taskqueue_swi, &sc->os_specific.event_task); | taskqueue_enqueue(taskqueue_swi, &sc->os_specific.event_task); | ||||
} | } | ||||
void pqisrc_event_worker(void *arg1, int arg2) | void | ||||
pqisrc_event_worker(void *arg1, int arg2) | |||||
{ | { | ||||
pqisrc_ack_all_events(arg1); | pqisrc_ack_all_events(arg1); | ||||
} | } | ||||
/* | /* | ||||
* ithread routine to handle uniprocessor systems | * ithread routine to handle uniprocessor systems | ||||
*/ | */ | ||||
static void shared_ithread_routine(void *arg) | static void | ||||
shared_ithread_routine(void *arg) | |||||
{ | { | ||||
pqi_intr_ctx_t *intr_ctx = (pqi_intr_ctx_t *)arg; | pqi_intr_ctx_t *intr_ctx = (pqi_intr_ctx_t *)arg; | ||||
pqisrc_softstate_t *softs = device_get_softc(intr_ctx->pqi_dev); | pqisrc_softstate_t *softs = device_get_softc(intr_ctx->pqi_dev); | ||||
int oq_id = intr_ctx->oq_id; | int oq_id = intr_ctx->oq_id; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
if (softs == NULL) | |||||
return; | |||||
pqisrc_process_response_queue(softs, oq_id); | pqisrc_process_response_queue(softs, oq_id); | ||||
pqisrc_process_event_intr_src(softs, oq_id - 1); | pqisrc_process_event_intr_src(softs, oq_id - 1); | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
} | } | ||||
/* | /* | ||||
* ithread routine to process non event response | * ithread routine to process non event response | ||||
*/ | */ | ||||
static void common_ithread_routine(void *arg) | static void | ||||
common_ithread_routine(void *arg) | |||||
{ | { | ||||
pqi_intr_ctx_t *intr_ctx = (pqi_intr_ctx_t *)arg; | pqi_intr_ctx_t *intr_ctx = (pqi_intr_ctx_t *)arg; | ||||
pqisrc_softstate_t *softs = device_get_softc(intr_ctx->pqi_dev); | pqisrc_softstate_t *softs = device_get_softc(intr_ctx->pqi_dev); | ||||
int oq_id = intr_ctx->oq_id; | int oq_id = intr_ctx->oq_id; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
if (softs == NULL) | |||||
return; | |||||
pqisrc_process_response_queue(softs, oq_id); | pqisrc_process_response_queue(softs, oq_id); | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
} | } | ||||
static void event_ithread_routine(void *arg) | static void | ||||
event_ithread_routine(void *arg) | |||||
{ | { | ||||
pqi_intr_ctx_t *intr_ctx = (pqi_intr_ctx_t *)arg; | pqi_intr_ctx_t *intr_ctx = (pqi_intr_ctx_t *)arg; | ||||
pqisrc_softstate_t *softs = device_get_softc(intr_ctx->pqi_dev); | pqisrc_softstate_t *softs = device_get_softc(intr_ctx->pqi_dev); | ||||
int oq_id = intr_ctx->oq_id; | int oq_id = intr_ctx->oq_id; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
if (softs == NULL) | |||||
return; | |||||
pqisrc_process_event_intr_src(softs, oq_id); | pqisrc_process_event_intr_src(softs, oq_id); | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
} | } | ||||
/* | /* | ||||
* Registration of legacy interrupt in case MSI is unsupported | * Registration of legacy interrupt in case MSI is unsupported | ||||
*/ | */ | ||||
int register_legacy_intr(pqisrc_softstate_t *softs) | int | ||||
register_legacy_intr(pqisrc_softstate_t *softs) | |||||
{ | { | ||||
int error = 0; | int error = BSD_SUCCESS; | ||||
device_t dev; | device_t dev = softs->os_specific.pqi_dev; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
dev = softs->os_specific.pqi_dev; | |||||
softs->os_specific.pqi_irq_rid[0] = 0; | softs->os_specific.pqi_irq_rid[0] = 0; | ||||
softs->os_specific.pqi_irq[0] = bus_alloc_resource_any(dev, \ | softs->os_specific.pqi_irq[0] = bus_alloc_resource_any(dev, \ | ||||
SYS_RES_IRQ, &softs->os_specific.pqi_irq_rid[0], | SYS_RES_IRQ, &softs->os_specific.pqi_irq_rid[0], | ||||
RF_ACTIVE | RF_SHAREABLE); | RF_ACTIVE | RF_SHAREABLE); | ||||
if (NULL == softs->os_specific.pqi_irq[0]) { | if (NULL == softs->os_specific.pqi_irq[0]) { | ||||
DBG_ERR("Failed to allocate resource for interrupt\n"); | DBG_ERR("Failed to allocate resource for interrupt\n"); | ||||
return PQI_STATUS_FAILURE; | return ENXIO; | ||||
} | } | ||||
if ((softs->os_specific.msi_ctx = os_mem_alloc(softs,sizeof(pqi_intr_ctx_t))) == NULL) { | if ((softs->os_specific.msi_ctx = os_mem_alloc(softs,sizeof(pqi_intr_ctx_t))) == NULL) { | ||||
DBG_ERR("Failed to allocate memory for msi_ctx\n"); | DBG_ERR("Failed to allocate memory for msi_ctx\n"); | ||||
return PQI_STATUS_FAILURE; | return ENXIO; | ||||
} | } | ||||
softs->os_specific.msi_ctx[0].pqi_dev = dev; | softs->os_specific.msi_ctx[0].pqi_dev = dev; | ||||
/* For Legacy support oq_id should be one */ | |||||
softs->os_specific.msi_ctx[0].oq_id = 1; | softs->os_specific.msi_ctx[0].oq_id = 1; | ||||
error = bus_setup_intr(dev, softs->os_specific.pqi_irq[0], | error = bus_setup_intr(dev, softs->os_specific.pqi_irq[0], | ||||
INTR_TYPE_CAM | INTR_MPSAFE, \ | INTR_TYPE_CAM | INTR_MPSAFE, \ | ||||
NULL, shared_ithread_routine, | NULL, shared_ithread_routine, | ||||
&softs->os_specific.msi_ctx[0], | &softs->os_specific.msi_ctx[0], | ||||
&softs->os_specific.intrcookie[0]); | &softs->os_specific.intrcookie[0]); | ||||
if (error) { | if (error) { | ||||
DBG_ERR("Failed to setup legacy interrupt err = %d\n", error); | DBG_ERR("Failed to setup legacy interrupt err = %d\n", error); | ||||
return error; | return error; | ||||
} | } | ||||
softs->os_specific.intr_registered[0] = TRUE; | softs->os_specific.intr_registered[0] = TRUE; | ||||
DBG_FUNC("OUT error = %d\n", error); | DBG_FUNC("OUT error = %d\n", error); | ||||
return error; | return error; | ||||
} | } | ||||
/* | /* | ||||
* Registration of MSIx | * Registration of MSIx | ||||
*/ | */ | ||||
int register_msix_intr(pqisrc_softstate_t *softs) | int | ||||
register_msix_intr(pqisrc_softstate_t *softs) | |||||
{ | { | ||||
int error = 0; | int error = BSD_SUCCESS; | ||||
int i = 0; | int i = 0; | ||||
device_t dev; | device_t dev = softs->os_specific.pqi_dev; | ||||
dev = softs->os_specific.pqi_dev; | |||||
int msix_count = softs->intr_count; | int msix_count = softs->intr_count; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
softs->os_specific.msi_ctx = os_mem_alloc(softs, sizeof(pqi_intr_ctx_t) * msix_count); | softs->os_specific.msi_ctx = os_mem_alloc(softs, sizeof(pqi_intr_ctx_t) * msix_count); | ||||
if (!softs->os_specific.msi_ctx) { | |||||
DBG_ERR("Memory allocation failed\n"); | |||||
return ENXIO; | |||||
} | |||||
/*Add shared handler */ | /*Add shared handler */ | ||||
if (softs->share_opq_and_eventq) { | if (softs->share_opq_and_eventq) { | ||||
softs->os_specific.pqi_irq_rid[i] = i+1; | softs->os_specific.pqi_irq_rid[i] = i+1; | ||||
softs->os_specific.pqi_irq[i] = bus_alloc_resource_any(dev, \ | softs->os_specific.pqi_irq[i] = bus_alloc_resource_any(dev, \ | ||||
SYS_RES_IRQ, | SYS_RES_IRQ, | ||||
&softs->os_specific.pqi_irq_rid[i], | &softs->os_specific.pqi_irq_rid[i], | ||||
RF_SHAREABLE | RF_ACTIVE); | RF_SHAREABLE | RF_ACTIVE); | ||||
if (NULL == softs->os_specific.pqi_irq[i]) { | if (NULL == softs->os_specific.pqi_irq[i]) { | ||||
DBG_ERR("Failed to allocate \ | DBG_ERR("Failed to allocate \ | ||||
event interrupt resource\n"); | event interrupt resource\n"); | ||||
return PQI_STATUS_FAILURE; | return ENXIO; | ||||
} | } | ||||
softs->os_specific.msi_ctx[i].pqi_dev = dev; | softs->os_specific.msi_ctx[i].pqi_dev = dev; | ||||
softs->os_specific.msi_ctx[i].oq_id = i+1; | softs->os_specific.msi_ctx[i].oq_id = i+1; | ||||
error = bus_setup_intr(dev,softs->os_specific.pqi_irq[i], | error = bus_setup_intr(dev,softs->os_specific.pqi_irq[i], | ||||
INTR_TYPE_CAM | INTR_MPSAFE,\ | INTR_TYPE_CAM | INTR_MPSAFE,\ | ||||
NULL, | NULL, | ||||
shared_ithread_routine, | shared_ithread_routine, | ||||
&softs->os_specific.msi_ctx[i], | &softs->os_specific.msi_ctx[i], | ||||
&softs->os_specific.intrcookie[i]); | &softs->os_specific.intrcookie[i]); | ||||
if (error) { | if (error) { | ||||
DBG_ERR("Failed to setup interrupt for events r=%d\n", | DBG_ERR("Failed to setup interrupt for events r=%d\n", | ||||
error); | error); | ||||
return error; | return error; | ||||
} | } | ||||
softs->os_specific.intr_registered[i] = TRUE; | softs->os_specific.intr_registered[i] = TRUE; | ||||
} | } | ||||
else { | else { | ||||
/* Add event handler */ | /* Add event handler */ | ||||
softs->os_specific.pqi_irq_rid[i] = i+1; | softs->os_specific.pqi_irq_rid[i] = i+1; | ||||
softs->os_specific.pqi_irq[i] = bus_alloc_resource_any(dev, \ | softs->os_specific.pqi_irq[i] = bus_alloc_resource_any(dev, \ | ||||
SYS_RES_IRQ, | SYS_RES_IRQ, | ||||
&softs->os_specific.pqi_irq_rid[i], | &softs->os_specific.pqi_irq_rid[i], | ||||
RF_SHAREABLE | RF_ACTIVE); | RF_SHAREABLE | RF_ACTIVE); | ||||
if (NULL == softs->os_specific.pqi_irq[i]) { | if (NULL == softs->os_specific.pqi_irq[i]) { | ||||
DBG_ERR("ERR : Failed to allocate \ | DBG_ERR("Failed to allocate event interrupt resource\n"); | ||||
event interrupt resource\n"); | return ENXIO; | ||||
return PQI_STATUS_FAILURE; | |||||
} | } | ||||
softs->os_specific.msi_ctx[i].pqi_dev = dev; | softs->os_specific.msi_ctx[i].pqi_dev = dev; | ||||
softs->os_specific.msi_ctx[i].oq_id = i; | softs->os_specific.msi_ctx[i].oq_id = i; | ||||
error = bus_setup_intr(dev,softs->os_specific.pqi_irq[i], | error = bus_setup_intr(dev,softs->os_specific.pqi_irq[i], | ||||
INTR_TYPE_CAM | INTR_MPSAFE,\ | INTR_TYPE_CAM | INTR_MPSAFE,\ | ||||
NULL, | NULL, | ||||
event_ithread_routine, | event_ithread_routine, | ||||
&softs->os_specific.msi_ctx[i], | &softs->os_specific.msi_ctx[i], | ||||
&softs->os_specific.intrcookie[i]); | &softs->os_specific.intrcookie[i]); | ||||
if (error) { | if (error) { | ||||
DBG_ERR("Failed to setup interrupt for events err=%d\n", | DBG_ERR("Failed to setup interrupt for events err=%d\n", | ||||
error); | error); | ||||
return error; | return error; | ||||
} | } | ||||
softs->os_specific.intr_registered[i] = TRUE; | softs->os_specific.intr_registered[i] = TRUE; | ||||
/* Add interrupt handlers*/ | /* Add interrupt handlers*/ | ||||
for (i = 1; i < msix_count; ++i) { | for (i = 1; i < msix_count; ++i) { | ||||
softs->os_specific.pqi_irq_rid[i] = i+1; | softs->os_specific.pqi_irq_rid[i] = i+1; | ||||
softs->os_specific.pqi_irq[i] = \ | softs->os_specific.pqi_irq[i] = \ | ||||
bus_alloc_resource_any(dev, | bus_alloc_resource_any(dev, | ||||
SYS_RES_IRQ, | SYS_RES_IRQ, | ||||
&softs->os_specific.pqi_irq_rid[i], | &softs->os_specific.pqi_irq_rid[i], | ||||
RF_SHAREABLE | RF_ACTIVE); | RF_SHAREABLE | RF_ACTIVE); | ||||
if (NULL == softs->os_specific.pqi_irq[i]) { | if (NULL == softs->os_specific.pqi_irq[i]) { | ||||
DBG_ERR("Failed to allocate \ | DBG_ERR("Failed to allocate \ | ||||
msi/x interrupt resource\n"); | msi/x interrupt resource\n"); | ||||
return PQI_STATUS_FAILURE; | return ENXIO; | ||||
} | } | ||||
softs->os_specific.msi_ctx[i].pqi_dev = dev; | softs->os_specific.msi_ctx[i].pqi_dev = dev; | ||||
softs->os_specific.msi_ctx[i].oq_id = i; | softs->os_specific.msi_ctx[i].oq_id = i; | ||||
error = bus_setup_intr(dev, | error = bus_setup_intr(dev, | ||||
softs->os_specific.pqi_irq[i], | softs->os_specific.pqi_irq[i], | ||||
INTR_TYPE_CAM | INTR_MPSAFE,\ | INTR_TYPE_CAM | INTR_MPSAFE,\ | ||||
NULL, | NULL, | ||||
common_ithread_routine, | common_ithread_routine, | ||||
Show All 11 Lines | register_msix_intr(pqisrc_softstate_t *softs) | ||||
DBG_FUNC("OUT error = %d\n", error); | DBG_FUNC("OUT error = %d\n", error); | ||||
return error; | return error; | ||||
} | } | ||||
/* | /* | ||||
* Setup interrupt depending on the configuration | * Setup interrupt depending on the configuration | ||||
*/ | */ | ||||
int os_setup_intr(pqisrc_softstate_t *softs) | int | ||||
os_setup_intr(pqisrc_softstate_t *softs) | |||||
{ | { | ||||
int error = 0; | int bsd_status, pqi_status; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
if (softs->intr_type == INTR_TYPE_FIXED) { | if (softs->intr_type == INTR_TYPE_FIXED) { | ||||
error = register_legacy_intr(softs); | bsd_status = register_legacy_intr(softs); | ||||
} | } | ||||
else { | else { | ||||
error = register_msix_intr(softs); | bsd_status = register_msix_intr(softs); | ||||
} | } | ||||
if (error) { | |||||
DBG_FUNC("OUT failed error = %d\n", error); | |||||
return error; | |||||
} | |||||
DBG_FUNC("OUT error = %d\n", error); | if(bsd_status) | ||||
DBG_WARN("interrupt registration is failed, error = %d\n", bsd_status); | |||||
return error; | pqi_status = bsd_status_to_pqi_status(bsd_status); | ||||
DBG_FUNC("OUT\n"); | |||||
return pqi_status; | |||||
} | } | ||||
/* | /* | ||||
* Deregistration of legacy interrupt | * Deregistration of legacy interrupt | ||||
*/ | */ | ||||
void deregister_pqi_intx(pqisrc_softstate_t *softs) | void | ||||
deregister_pqi_intx(pqisrc_softstate_t *softs) | |||||
{ | { | ||||
device_t dev; | device_t dev = softs->os_specific.pqi_dev; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
dev = softs->os_specific.pqi_dev; | |||||
if (softs->os_specific.pqi_irq[0] != NULL) { | if (softs->os_specific.pqi_irq[0] != NULL) { | ||||
if (softs->os_specific.intr_registered[0]) { | if (softs->os_specific.intr_registered[0]) { | ||||
bus_teardown_intr(dev, softs->os_specific.pqi_irq[0], | bus_teardown_intr(dev, softs->os_specific.pqi_irq[0], | ||||
softs->os_specific.intrcookie[0]); | softs->os_specific.intrcookie[0]); | ||||
softs->os_specific.intr_registered[0] = FALSE; | softs->os_specific.intr_registered[0] = FALSE; | ||||
} | } | ||||
bus_release_resource(dev, SYS_RES_IRQ, | bus_release_resource(dev, SYS_RES_IRQ, | ||||
softs->os_specific.pqi_irq_rid[0], | softs->os_specific.pqi_irq_rid[0], | ||||
softs->os_specific.pqi_irq[0]); | softs->os_specific.pqi_irq[0]); | ||||
softs->os_specific.pqi_irq[0] = NULL; | softs->os_specific.pqi_irq[0] = NULL; | ||||
os_mem_free(softs, (char*)softs->os_specific.msi_ctx, sizeof(pqi_intr_ctx_t)); | os_mem_free(softs, (char*)softs->os_specific.msi_ctx, sizeof(pqi_intr_ctx_t)); | ||||
} | } | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
} | } | ||||
/* | /* | ||||
* Deregistration of MSIx interrupt | * Deregistration of MSIx interrupt | ||||
*/ | */ | ||||
void deregister_pqi_msix(pqisrc_softstate_t *softs) | void | ||||
deregister_pqi_msix(pqisrc_softstate_t *softs) | |||||
{ | { | ||||
device_t dev; | device_t dev = softs->os_specific.pqi_dev; | ||||
dev = softs->os_specific.pqi_dev; | |||||
int msix_count = softs->intr_count; | int msix_count = softs->intr_count; | ||||
int i = 0; | int i = 0; | ||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
os_mem_free(softs, (char*)softs->os_specific.msi_ctx, sizeof(pqi_intr_ctx_t) * msix_count); | os_mem_free(softs, (char*)softs->os_specific.msi_ctx, sizeof(pqi_intr_ctx_t) * msix_count); | ||||
softs->os_specific.msi_ctx = NULL; | softs->os_specific.msi_ctx = NULL; | ||||
for (; i < msix_count; ++i) { | for (; i < msix_count; ++i) { | ||||
if (softs->os_specific.pqi_irq[i] != NULL) { | if (softs->os_specific.pqi_irq[i] != NULL) { | ||||
if (softs->os_specific.intr_registered[i]) { | if (softs->os_specific.intr_registered[i]) { | ||||
bus_teardown_intr(dev, | bus_teardown_intr(dev, | ||||
softs->os_specific.pqi_irq[i], | softs->os_specific.pqi_irq[i], | ||||
softs->os_specific.intrcookie[i]); | softs->os_specific.intrcookie[i]); | ||||
softs->os_specific.intr_registered[i] = FALSE; | softs->os_specific.intr_registered[i] = FALSE; | ||||
} | } | ||||
bus_release_resource(dev, SYS_RES_IRQ, | bus_release_resource(dev, SYS_RES_IRQ, | ||||
softs->os_specific.pqi_irq_rid[i], | softs->os_specific.pqi_irq_rid[i], | ||||
softs->os_specific.pqi_irq[i]); | softs->os_specific.pqi_irq[i]); | ||||
softs->os_specific.pqi_irq[i] = NULL; | softs->os_specific.pqi_irq[i] = NULL; | ||||
} | } | ||||
} | } | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
} | } | ||||
/* | /* | ||||
* Function to destroy interrupts registered | * Function to destroy interrupts registered | ||||
*/ | */ | ||||
int os_destroy_intr(pqisrc_softstate_t *softs) | int | ||||
os_destroy_intr(pqisrc_softstate_t *softs) | |||||
{ | { | ||||
device_t dev; | device_t dev = softs->os_specific.pqi_dev; | ||||
dev = softs->os_specific.pqi_dev; | |||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
if (softs->intr_type == INTR_TYPE_FIXED) { | if (softs->intr_type == INTR_TYPE_FIXED) { | ||||
deregister_pqi_intx(softs); | deregister_pqi_intx(softs); | ||||
} else if (softs->intr_type == INTR_TYPE_MSIX) { | } else if (softs->intr_type == INTR_TYPE_MSIX) { | ||||
deregister_pqi_msix(softs); | deregister_pqi_msix(softs); | ||||
} | } | ||||
if (softs->os_specific.msi_enabled) { | if (softs->os_specific.msi_enabled) { | ||||
pci_release_msi(dev); | pci_release_msi(dev); | ||||
softs->os_specific.msi_enabled = FALSE; | softs->os_specific.msi_enabled = FALSE; | ||||
} | } | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
return PQI_STATUS_SUCCESS; | return PQI_STATUS_SUCCESS; | ||||
} | } | ||||
/* | /* | ||||
* Free interrupt related resources for the adapter | * Free interrupt related resources for the adapter | ||||
*/ | */ | ||||
void os_free_intr_config(pqisrc_softstate_t *softs) | void | ||||
os_free_intr_config(pqisrc_softstate_t *softs) | |||||
{ | { | ||||
device_t dev; | device_t dev = softs->os_specific.pqi_dev; | ||||
dev = softs->os_specific.pqi_dev; | |||||
DBG_FUNC("IN\n"); | DBG_FUNC("IN\n"); | ||||
if (softs->os_specific.msi_enabled) { | if (softs->os_specific.msi_enabled) { | ||||
pci_release_msi(dev); | pci_release_msi(dev); | ||||
softs->os_specific.msi_enabled = FALSE; | softs->os_specific.msi_enabled = FALSE; | ||||
} | } | ||||
DBG_FUNC("OUT\n"); | DBG_FUNC("OUT\n"); | ||||
} | } |