Page MenuHomeFreeBSD

D3009.id6752.diff
No OneTemporary

D3009.id6752.diff

Index: sys/dev/ahci/ahci.h
===================================================================
--- sys/dev/ahci/ahci.h
+++ sys/dev/ahci/ahci.h
@@ -482,11 +482,15 @@
device_t dev;
bus_dma_tag_t dma_tag;
int r_rid;
+ int r_msix_tab_rid;
+ int r_msix_pba_rid;
uint16_t vendorid; /* Vendor ID from the bus */
uint16_t deviceid; /* Device ID from the bus */
uint16_t subvendorid; /* Subvendor ID from the bus */
uint16_t subdeviceid; /* Subdevice ID from the bus */
struct resource *r_mem;
+ struct resource *r_msix_table;
+ struct resource *r_msix_pba;
struct rman sc_iomem;
struct ahci_controller_irq {
struct ahci_controller *ctlr;
@@ -621,3 +625,4 @@
bus_dma_tag_t ahci_get_dma_tag(device_t dev, device_t child);
int ahci_ctlr_reset(device_t dev);
int ahci_ctlr_setup(device_t dev);
+void ahci_free_mem(device_t dev);
Index: sys/dev/ahci/ahci.c
===================================================================
--- sys/dev/ahci/ahci.c
+++ sys/dev/ahci/ahci.c
@@ -181,12 +181,12 @@
ctlr->sc_iomem.rm_type = RMAN_ARRAY;
ctlr->sc_iomem.rm_descr = "I/O memory addresses";
if ((error = rman_init(&ctlr->sc_iomem)) != 0) {
- bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
+ ahci_free_mem(dev);
return (error);
}
if ((error = rman_manage_region(&ctlr->sc_iomem,
rman_get_start(ctlr->r_mem), rman_get_end(ctlr->r_mem))) != 0) {
- bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
+ ahci_free_mem(dev);
rman_fini(&ctlr->sc_iomem);
return (error);
}
@@ -250,8 +250,7 @@
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
BUS_SPACE_MAXSIZE, BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE,
0, NULL, NULL, &ctlr->dma_tag)) {
- bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid,
- ctlr->r_mem);
+ ahci_free_mem(dev);
rman_fini(&ctlr->sc_iomem);
return (ENXIO);
}
@@ -261,8 +260,7 @@
/* Setup interrupts. */
if ((error = ahci_setup_interrupt(dev)) != 0) {
bus_dma_tag_destroy(ctlr->dma_tag);
- bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid,
- ctlr->r_mem);
+ ahci_free_mem(dev);
rman_fini(&ctlr->sc_iomem);
return (error);
}
@@ -367,9 +365,26 @@
bus_dma_tag_destroy(ctlr->dma_tag);
/* Free memory. */
rman_fini(&ctlr->sc_iomem);
+ ahci_free_mem(dev);
+ return (0);
+}
+
+void
+ahci_free_mem(device_t dev)
+{
+ struct ahci_controller *ctlr = device_get_softc(dev);
+
+ /* Release memory resources */
if (ctlr->r_mem)
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
- return (0);
+ if (ctlr->r_msix_table)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ ctlr->r_msix_tab_rid, ctlr->r_msix_table);
+ if (ctlr->r_msix_pba)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ ctlr->r_msix_pba_rid, ctlr->r_msix_pba);
+
+ ctlr->r_msix_pba = ctlr->r_mem = ctlr->r_msix_table = NULL;
}
int
Index: sys/dev/ahci/ahci_pci.c
===================================================================
--- sys/dev/ahci/ahci_pci.c
+++ sys/dev/ahci/ahci_pci.c
@@ -41,6 +41,7 @@
#include <machine/resource.h>
#include <machine/bus.h>
#include <sys/rman.h>
+#include <sys/pciio.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include "ahci.h"
@@ -380,6 +381,11 @@
int error, i;
uint32_t devid = pci_get_devid(dev);
uint8_t revid = pci_get_revid(dev);
+ struct pci_devinfo *dinfo;
+ int msi_count, msix_count;
+
+ msi_count = pci_msi_count(dev);
+ msix_count = pci_msix_count(dev);
i = 0;
while (ahci_ids[i].id != 0 &&
@@ -406,10 +412,35 @@
if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&ctlr->r_rid, RF_ACTIVE)))
return ENXIO;
+
+ if (msix_count > 0) {
+ /* Allocate resources for MSI-X table and PBA */
+ /* No need to check dinfo for NULL as it is allocated before by
+ * pci during device discovery */
+ dinfo = (struct pci_devinfo *)device_get_ivars(dev);
+ ctlr->r_msix_tab_rid = dinfo->cfg.msix.msix_table_bar;
+ ctlr->r_msix_pba_rid = dinfo->cfg.msix.msix_pba_bar;
+ if (!(ctlr->r_msix_table = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &ctlr->r_msix_tab_rid, RF_ACTIVE))) {
+ ahci_free_mem(dev);
+ return ENXIO;
+ }
+
+ if (ctlr->r_msix_tab_rid != ctlr->r_msix_pba_rid) {
+ /* Separate BAR for PBA */
+ if (!(ctlr->r_msix_pba = bus_alloc_resource_any(dev,
+ SYS_RES_MEMORY, &ctlr->r_msix_pba_rid,
+ RF_ACTIVE))) {
+ ahci_free_mem(dev);
+ return ENXIO;
+ }
+ }
+ }
+
pci_enable_busmaster(dev);
/* Reset controller */
if ((error = ahci_pci_ctlr_reset(dev)) != 0) {
- bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
+ ahci_free_mem(dev);
return (error);
};
@@ -428,22 +459,42 @@
ctlr->numirqs = 1;
if (ctlr->msi < 0)
ctlr->msi = 0;
- else if (ctlr->msi == 1)
- ctlr->msi = min(1, pci_msi_count(dev));
+ else if (ctlr->msi == 1) {
+ if (msi_count == 0 && msix_count == 0)
+ ctlr->msi = 0;
+ else
+ ctlr->msi = 1;
+ }
else if (ctlr->msi > 1) {
ctlr->msi = 2;
- ctlr->numirqs = pci_msi_count(dev);
+ ctlr->numirqs = (msix_count > 0) ? msix_count: msi_count;
}
- /* Allocate MSI if needed/present. */
- if (ctlr->msi && pci_alloc_msi(dev, &ctlr->numirqs) != 0) {
+ /* Allocate MSI/MSI-x if needed/present. */
+ if (ctlr->msi > 0) {
+ error = -1;
+ if (msix_count > 0)
+ error = pci_alloc_msix(dev, &ctlr->numirqs);
+
+ /*
+ * Try to allocate MSI if msi_count is greater than 0
+ * and if msix allocation failed.
+ */
+ if ((error != 0) && (msi_count > 0))
+ error = pci_alloc_msi(dev, &ctlr->numirqs);
+
+ /* We don't have any MSI or MSI-x */
+ if (error) {
ctlr->msi = 0;
ctlr->numirqs = 1;
}
+ }
error = ahci_attach(dev);
- if (error != 0)
- if (ctlr->msi)
+ if (error != 0) {
+ if (ctlr->msi > 0 && (msix_count > 0 || msi_count > 0))
pci_release_msi(dev);
+ ahci_free_mem(dev);
+ }
return error;
}

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 20, 7:48 PM (13 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27100363
Default Alt Text
D3009.id6752.diff (5 KB)

Event Timeline