Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/mpr/mpr_pci.c
Show First 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | |||||
static int mpr_pci_probe(device_t); | static int mpr_pci_probe(device_t); | ||||
static int mpr_pci_attach(device_t); | static int mpr_pci_attach(device_t); | ||||
static int mpr_pci_detach(device_t); | static int mpr_pci_detach(device_t); | ||||
static int mpr_pci_suspend(device_t); | static int mpr_pci_suspend(device_t); | ||||
static int mpr_pci_resume(device_t); | static int mpr_pci_resume(device_t); | ||||
static void mpr_pci_free(struct mpr_softc *); | static void mpr_pci_free(struct mpr_softc *); | ||||
static int mpr_alloc_msix(struct mpr_softc *sc, int msgs); | static int mpr_alloc_msix(struct mpr_softc *sc, int msgs); | ||||
static int mpr_alloc_msi(struct mpr_softc *sc, int msgs); | static int mpr_alloc_msi(struct mpr_softc *sc, int msgs); | ||||
static int mpr_pci_alloc_interrupts(struct mpr_softc *sc); | |||||
static device_method_t mpr_methods[] = { | static device_method_t mpr_methods[] = { | ||||
DEVMETHOD(device_probe, mpr_pci_probe), | DEVMETHOD(device_probe, mpr_pci_probe), | ||||
DEVMETHOD(device_attach, mpr_pci_attach), | DEVMETHOD(device_attach, mpr_pci_attach), | ||||
DEVMETHOD(device_detach, mpr_pci_detach), | DEVMETHOD(device_detach, mpr_pci_detach), | ||||
DEVMETHOD(device_suspend, mpr_pci_suspend), | DEVMETHOD(device_suspend, mpr_pci_suspend), | ||||
DEVMETHOD(device_resume, mpr_pci_resume), | DEVMETHOD(device_resume, mpr_pci_resume), | ||||
DEVMETHOD(bus_print_child, bus_generic_print_child), | DEVMETHOD(bus_print_child, bus_generic_print_child), | ||||
▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | mpr_pci_attach(device_t dev) | ||||
int error, i; | int error, i; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
bzero(sc, sizeof(*sc)); | bzero(sc, sizeof(*sc)); | ||||
sc->mpr_dev = dev; | sc->mpr_dev = dev; | ||||
m = mpr_find_ident(dev); | m = mpr_find_ident(dev); | ||||
sc->mpr_flags = m->flags; | sc->mpr_flags = m->flags; | ||||
mpr_get_tunables(sc); | |||||
/* Twiddle basic PCI config bits for a sanity check */ | /* Twiddle basic PCI config bits for a sanity check */ | ||||
pci_enable_busmaster(dev); | pci_enable_busmaster(dev); | ||||
/* Set flag if this is a Gen3.5 IOC */ | /* Set flag if this is a Gen3.5 IOC */ | ||||
if ((m->device == MPI26_MFGPAGE_DEVID_SAS3508) || | if ((m->device == MPI26_MFGPAGE_DEVID_SAS3508) || | ||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3508_1) || | (m->device == MPI26_MFGPAGE_DEVID_SAS3508_1) || | ||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3408) || | (m->device == MPI26_MFGPAGE_DEVID_SAS3408) || | ||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3516) || | (m->device == MPI26_MFGPAGE_DEVID_SAS3516) || | ||||
Show All 33 Lines | if (bus_dma_tag_create( bus_get_dma_tag(dev), /* parent */ | ||||
0, /* flags */ | 0, /* flags */ | ||||
NULL, NULL, /* lockfunc, lockarg */ | NULL, NULL, /* lockfunc, lockarg */ | ||||
&sc->mpr_parent_dmat)) { | &sc->mpr_parent_dmat)) { | ||||
mpr_printf(sc, "Cannot allocate parent DMA tag\n"); | mpr_printf(sc, "Cannot allocate parent DMA tag\n"); | ||||
mpr_pci_free(sc); | mpr_pci_free(sc); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
if ((error = mpr_attach(sc)) != 0) | if (((error = mpr_pci_alloc_interrupts(sc)) != 0) || | ||||
((error = mpr_attach(sc)) != 0)) | |||||
mpr_pci_free(sc); | mpr_pci_free(sc); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | |||||
* Allocate, but don't assign interrupts early. Doing it before requesting | |||||
* the IOCFacts message informs the firmware that we want to do MSI-X | |||||
* multiqueue. We might not use all of the available messages, but there's | |||||
* no reason to re-alloc if we don't. | |||||
*/ | |||||
int | int | ||||
mpr_pci_setup_interrupts(struct mpr_softc *sc) | mpr_pci_alloc_interrupts(struct mpr_softc *sc) | ||||
{ | { | ||||
device_t dev; | device_t dev; | ||||
int i, error, msgs; | int error, msgs; | ||||
dev = sc->mpr_dev; | dev = sc->mpr_dev; | ||||
error = ENXIO; | error = 0; | ||||
if ((sc->disable_msix == 0) && | if ((sc->disable_msix == 0) && | ||||
((msgs = pci_msix_count(dev)) >= MPR_MSI_COUNT)) | ((msgs = pci_msix_count(dev)) >= MPR_MSI_COUNT)) | ||||
error = mpr_alloc_msix(sc, MPR_MSI_COUNT); | error = mpr_alloc_msix(sc, MPR_MSI_COUNT); | ||||
if ((error != 0) && (sc->disable_msi == 0) && | if ((error != 0) && (sc->disable_msi == 0) && | ||||
((msgs = pci_msi_count(dev)) >= MPR_MSI_COUNT)) | ((msgs = pci_msi_count(dev)) >= MPR_MSI_COUNT)) | ||||
error = mpr_alloc_msi(sc, MPR_MSI_COUNT); | error = mpr_alloc_msi(sc, MPR_MSI_COUNT); | ||||
else | |||||
msgs = 0; | |||||
if (error != 0) { | sc->msi_msgs = msgs; | ||||
return (error); | |||||
} | |||||
int | |||||
mpr_pci_setup_interrupts(struct mpr_softc *sc) | |||||
{ | |||||
device_t dev; | |||||
int i, error; | |||||
dev = sc->mpr_dev; | |||||
error = ENXIO; | |||||
if (sc->msi_msgs == 0) { | |||||
sc->mpr_flags |= MPR_FLAGS_INTX; | sc->mpr_flags |= MPR_FLAGS_INTX; | ||||
sc->mpr_irq_rid[0] = 0; | sc->mpr_irq_rid[0] = 0; | ||||
sc->mpr_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ, | sc->mpr_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ, | ||||
&sc->mpr_irq_rid[0], RF_SHAREABLE | RF_ACTIVE); | &sc->mpr_irq_rid[0], RF_SHAREABLE | RF_ACTIVE); | ||||
if (sc->mpr_irq[0] == NULL) { | if (sc->mpr_irq[0] == NULL) { | ||||
mpr_printf(sc, "Cannot allocate INTx interrupt\n"); | mpr_printf(sc, "Cannot allocate INTx interrupt\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 128 Lines • Show Last 20 Lines |