diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index c88ea309eb3d..14d46da49eee 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -397,9 +397,13 @@ ndis_convert_res(arg) ndis_resource_list *rl = NULL; cm_partial_resource_desc *prd = NULL; ndis_miniport_block *block; + device_t dev; + struct resource_list *brl; + struct resource_list_entry *brle; sc = arg; block = &sc->ndis_block; + dev = sc->ndis_dev; rl = malloc(sizeof(ndis_resource_list) + (sizeof(cm_partial_resource_desc) * (sc->ndis_rescnt - 1)), @@ -411,33 +415,35 @@ ndis_convert_res(arg) rl->cprl_version = 5; rl->cprl_version = 1; rl->cprl_count = sc->ndis_rescnt; - prd = rl->cprl_partial_descs; - if (sc->ndis_res_io) { - prd->cprd_type = CmResourceTypePort; - prd->u.cprd_port.cprd_start.np_quad = - rman_get_start(sc->ndis_res_io); - prd->u.cprd_port.cprd_len = - rman_get_size(sc->ndis_res_io); - prd++; - } - if (sc->ndis_res_mem) { - prd->cprd_type = CmResourceTypeMemory; - prd->u.cprd_mem.cprd_start.np_quad = - rman_get_start(sc->ndis_res_mem); - prd->u.cprd_mem.cprd_len = - rman_get_size(sc->ndis_res_mem); - prd++; - } - - if (sc->ndis_irq) { - prd->cprd_type = CmResourceTypeInterrupt; - prd->u.cprd_intr.cprd_level = - rman_get_start(sc->ndis_irq); - prd->u.cprd_intr.cprd_vector = - rman_get_start(sc->ndis_irq); - prd->u.cprd_intr.cprd_affinity = 0; + brl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); + if (brl != NULL) { + SLIST_FOREACH(brle, brl, link) { + switch (brle->type) { + case SYS_RES_IOPORT: + prd->cprd_type = CmResourceTypePort; + prd->u.cprd_port.cprd_start.np_quad = + brle->start; + prd->u.cprd_port.cprd_len = brle->count; + break; + case SYS_RES_MEMORY: + prd->cprd_type = CmResourceTypeMemory; + prd->u.cprd_port.cprd_start.np_quad = + brle->start; + prd->u.cprd_port.cprd_len = brle->count; + break; + case SYS_RES_IRQ: + prd->cprd_type = CmResourceTypeInterrupt; + prd->u.cprd_intr.cprd_level = brle->start; + prd->u.cprd_intr.cprd_vector = brle->start; + prd->u.cprd_intr.cprd_affinity = 0; + break; + default: + break; + } + prd++; + } } block->nmb_rlist = rl; diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index e9e756dafacb..46ead8d5cee0 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); + 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++; + } } - 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; - } - - 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);