summaryrefslogtreecommitdiffstats
path: root/sys/dev/if_ndis
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/if_ndis')
-rw-r--r--sys/dev/if_ndis/if_ndis.c134
1 files changed, 74 insertions, 60 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index e9e756d..46ead8d 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -215,10 +215,13 @@ ndis_attach(dev)
void *img;
struct ndis_type *t;
int i, devidx = 0, defidx = 0;
+ struct resource_list *rl;
+ struct resource_list_entry *rle;
sc = device_get_softc(dev);
unit = device_get_unit(dev);
+ sc->ndis_dev = dev;
mtx_init(&sc->ndis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
@@ -228,67 +231,76 @@ ndis_attach(dev)
*/
pci_enable_busmaster(dev);
- /* Try to map iospace */
-
- sc->ndis_io_rid = NDIS_PCI_LOIO;
- sc->ndis_res_io = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sc->ndis_io_rid, 0, ~0, 1, RF_ACTIVE);
-
- /*
- * Sometimes the iospace and memspace BARs are swapped.
- * Make one more try to map I/O space using a different
- * RID.
- */
- if (sc->ndis_res_io == NULL) {
- sc->ndis_io_rid = NDIS_PCI_LOMEM;
- sc->ndis_res_io = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sc->ndis_io_rid, 0, ~0, 1, RF_ACTIVE);
- }
-
- if (sc->ndis_res_io != NULL)
- sc->ndis_rescnt++;
-
- /* Now try to mem memory space */
- sc->ndis_mem_rid = NDIS_PCI_LOMEM;
- sc->ndis_res_mem = bus_alloc_resource(dev, SYS_RES_MEMORY,
- &sc->ndis_mem_rid, 0, ~0, 1, RF_ACTIVE);
-
- /*
- * If the first attempt fails, try again with another
- * BAR.
- */
- if (sc->ndis_res_mem == NULL) {
- sc->ndis_mem_rid = NDIS_PCI_LOIO;
- sc->ndis_res_mem = bus_alloc_resource(dev, SYS_RES_MEMORY,
- &sc->ndis_mem_rid, 0, ~0, 1, RF_ACTIVE);
- }
-
- if (sc->ndis_res_mem != NULL)
- sc->ndis_rescnt++;
-
- if (!sc->ndis_rescnt) {
- printf("ndis%d: couldn't map ports/memory\n", unit);
- error = ENXIO;
- goto fail;
- }
-#ifdef notdef
- sc->ndis_btag = rman_get_bustag(sc->ndis_res);
- sc->ndis_bhandle = rman_get_bushandle(sc->ndis_res);
-#endif
-
- /* Allocate interrupt */
- rid = 0;
- sc->ndis_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_SHAREABLE | RF_ACTIVE);
-
- if (sc->ndis_irq == NULL) {
- printf("ndis%d: couldn't map interrupt\n", unit);
- error = ENXIO;
- goto fail;
+ rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
+ if (rl != NULL) {
+ SLIST_FOREACH(rle, rl, link) {
+ switch (rle->type) {
+ case SYS_RES_IOPORT:
+ sc->ndis_io_rid = rle->rid;
+ sc->ndis_res_io = bus_alloc_resource(dev,
+ SYS_RES_IOPORT, &sc->ndis_io_rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (sc->ndis_res_io == NULL) {
+ printf("ndis%d: couldn't map "
+ "iospace\n", unit);
+ error = ENXIO;
+ goto fail;
+ }
+ break;
+ case SYS_RES_MEMORY:
+ if (sc->ndis_res_altmem != NULL) {
+ printf ("ndis%d: too many memory "
+ "resources", sc->ndis_unit);
+ error = ENXIO;
+ goto fail;
+ }
+ if (sc->ndis_res_mem == NULL) {
+ sc->ndis_mem_rid = rle->rid;
+ sc->ndis_res_mem =
+ bus_alloc_resource(dev,
+ SYS_RES_MEMORY,
+ &sc->ndis_mem_rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (sc->ndis_res_mem == NULL) {
+ printf("ndis%d: couldn't map "
+ "memory\n", unit);
+ error = ENXIO;
+ goto fail;
+ }
+ } else {
+ sc->ndis_altmem_rid = rle->rid;
+ sc->ndis_res_altmem =
+ bus_alloc_resource(dev,
+ SYS_RES_MEMORY,
+ &sc->ndis_altmem_rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (sc->ndis_res_altmem == NULL) {
+ printf("ndis%d: couldn't map "
+ "alt memory\n", unit);
+ error = ENXIO;
+ goto fail;
+ }
+ }
+ break;
+ case SYS_RES_IRQ:
+ rid = rle->rid;
+ sc->ndis_irq = bus_alloc_resource(dev,
+ SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (sc->ndis_irq == NULL) {
+ printf("ndis%d: couldn't map "
+ "interrupt\n", unit);
+ error = ENXIO;
+ goto fail;
+ }
+ break;
+ default:
+ break;
+ }
+ sc->ndis_rescnt++;
+ }
}
- sc->ndis_rescnt++;
-
/*
* Hook interrupt early, since calling the driver's
* init routine may trigger an interrupt.
@@ -321,7 +333,6 @@ ndis_attach(dev)
goto fail;
img = drv_data;
- sc->ndis_dev = dev;
sc->ndis_regvals = ndis_regvals;
sc->ndis_iftype = PCIBus;
@@ -615,6 +626,9 @@ ndis_detach(dev)
if (sc->ndis_res_mem)
bus_release_resource(dev, SYS_RES_MEMORY,
sc->ndis_mem_rid, sc->ndis_res_mem);
+ if (sc->ndis_res_altmem)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ sc->ndis_altmem_rid, sc->ndis_res_altmem);
if (sc->ndis_sc)
ndis_destroy_dma(sc);
OpenPOWER on IntegriCloud