Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/mps/mps_pci.c
Show First 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
static int mps_pci_probe(device_t); | static int mps_pci_probe(device_t); | ||||
static int mps_pci_attach(device_t); | static int mps_pci_attach(device_t); | ||||
static int mps_pci_detach(device_t); | static int mps_pci_detach(device_t); | ||||
static int mps_pci_suspend(device_t); | static int mps_pci_suspend(device_t); | ||||
static int mps_pci_resume(device_t); | static int mps_pci_resume(device_t); | ||||
static void mps_pci_free(struct mps_softc *); | static void mps_pci_free(struct mps_softc *); | ||||
static int mps_alloc_msix(struct mps_softc *sc, int msgs); | static int mps_alloc_msix(struct mps_softc *sc, int msgs); | ||||
static int mps_alloc_msi(struct mps_softc *sc, int msgs); | static int mps_alloc_msi(struct mps_softc *sc, int msgs); | ||||
static int mps_pci_alloc_interrupts(struct mps_softc *sc); | |||||
static device_method_t mps_methods[] = { | static device_method_t mps_methods[] = { | ||||
DEVMETHOD(device_probe, mps_pci_probe), | DEVMETHOD(device_probe, mps_pci_probe), | ||||
DEVMETHOD(device_attach, mps_pci_attach), | DEVMETHOD(device_attach, mps_pci_attach), | ||||
DEVMETHOD(device_detach, mps_pci_detach), | DEVMETHOD(device_detach, mps_pci_detach), | ||||
DEVMETHOD(device_suspend, mps_pci_suspend), | DEVMETHOD(device_suspend, mps_pci_suspend), | ||||
DEVMETHOD(device_resume, mps_pci_resume), | DEVMETHOD(device_resume, mps_pci_resume), | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | mps_pci_attach(device_t dev) | ||||
int error; | int error; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
bzero(sc, sizeof(*sc)); | bzero(sc, sizeof(*sc)); | ||||
sc->mps_dev = dev; | sc->mps_dev = dev; | ||||
m = mps_find_ident(dev); | m = mps_find_ident(dev); | ||||
sc->mps_flags = m->flags; | sc->mps_flags = m->flags; | ||||
mps_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); | ||||
/* Allocate the System Interface Register Set */ | /* Allocate the System Interface Register Set */ | ||||
sc->mps_regs_rid = PCIR_BAR(1); | sc->mps_regs_rid = PCIR_BAR(1); | ||||
if ((sc->mps_regs_resource = bus_alloc_resource_any(dev, | if ((sc->mps_regs_resource = bus_alloc_resource_any(dev, | ||||
SYS_RES_MEMORY, &sc->mps_regs_rid, RF_ACTIVE)) == NULL) { | SYS_RES_MEMORY, &sc->mps_regs_rid, RF_ACTIVE)) == NULL) { | ||||
mps_printf(sc, "Cannot allocate PCI registers\n"); | mps_printf(sc, "Cannot allocate PCI registers\n"); | ||||
Show All 14 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->mps_parent_dmat)) { | &sc->mps_parent_dmat)) { | ||||
mps_printf(sc, "Cannot allocate parent DMA tag\n"); | mps_printf(sc, "Cannot allocate parent DMA tag\n"); | ||||
mps_pci_free(sc); | mps_pci_free(sc); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
if ((error = mps_attach(sc)) != 0) | if (((error = mps_pci_alloc_interrupts(sc)) != 0) || | ||||
((error = mps_attach(sc)) != 0)) | |||||
mps_pci_free(sc); | mps_pci_free(sc); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | /* | ||||
mps_pci_setup_interrupts(struct mps_softc *sc) | * 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. | |||||
*/ | |||||
static int | |||||
mps_pci_alloc_interrupts(struct mps_softc *sc) | |||||
{ | { | ||||
device_t dev; | device_t dev; | ||||
int i, error, msgs; | int error, msgs; | ||||
dev = sc->mps_dev; | dev = sc->mps_dev; | ||||
error = ENXIO; | error = 0; | ||||
if ((sc->disable_msix == 0) && | if ((sc->disable_msix == 0) && | ||||
((msgs = pci_msix_count(dev)) >= MPS_MSI_COUNT)) | ((msgs = pci_msix_count(dev)) >= MPS_MSI_COUNT)) | ||||
error = mps_alloc_msix(sc, MPS_MSI_COUNT); | error = mps_alloc_msix(sc, MPS_MSI_COUNT); | ||||
if ((error != 0) && (sc->disable_msi == 0) && | if ((error != 0) && (sc->disable_msi == 0) && | ||||
((msgs = pci_msi_count(dev)) >= MPS_MSI_COUNT)) | ((msgs = pci_msi_count(dev)) >= MPS_MSI_COUNT)) | ||||
error = mps_alloc_msi(sc, MPS_MSI_COUNT); | error = mps_alloc_msi(sc, MPS_MSI_COUNT); | ||||
else | |||||
msgs = 0; | |||||
if (error != 0) { | sc->msi_msgs = msgs; | ||||
return (error); | |||||
} | |||||
int | |||||
mps_pci_setup_interrupts(struct mps_softc *sc) | |||||
{ | |||||
device_t dev; | |||||
int i, error; | |||||
dev = sc->mps_dev; | |||||
error = ENXIO; | |||||
if (sc->msi_msgs == 0) { | |||||
sc->mps_flags |= MPS_FLAGS_INTX; | sc->mps_flags |= MPS_FLAGS_INTX; | ||||
sc->mps_irq_rid[0] = 0; | sc->mps_irq_rid[0] = 0; | ||||
sc->mps_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ, | sc->mps_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ, | ||||
&sc->mps_irq_rid[0], RF_SHAREABLE | RF_ACTIVE); | &sc->mps_irq_rid[0], RF_SHAREABLE | RF_ACTIVE); | ||||
if (sc->mps_irq[0] == NULL) { | if (sc->mps_irq[0] == NULL) { | ||||
mps_printf(sc, "Cannot allocate INTx interrupt\n"); | mps_printf(sc, "Cannot allocate INTx interrupt\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 128 Lines • Show Last 20 Lines |