Index: sys/dev/pci/pci.c =================================================================== --- sys/dev/pci/pci.c +++ sys/dev/pci/pci.c @@ -4744,7 +4744,7 @@ static struct resource * pci_reserve_map(device_t dev, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int num, + rman_res_t *start, rman_res_t *end, rman_res_t *count, u_int num, u_int flags) { struct pci_devinfo *dinfo = device_get_ivars(child); @@ -4811,30 +4811,49 @@ * situation where we might allocate the excess to * another driver, which won't work. */ - count = ((pci_addr_t)1 << mapsize) * num; + *count = ((pci_addr_t)1 << mapsize) * num; if (RF_ALIGNMENT(flags) < mapsize) flags = (flags & ~RF_ALIGNMENT_MASK) | RF_ALIGNMENT_LOG2(mapsize); if (PCI_BAR_MEM(map) && (map & PCIM_BAR_MEM_PREFETCH)) flags |= RF_PREFETCHABLE; + if ((*start == 0UL) && (*end == ~0UL)) { + + /* Mask the information bits */ + if (PCI_BAR_MEM(map)) + map &= PCIM_BAR_MEM_BASE; + else + map &= PCIM_BAR_IO_BASE; + + if (PCI_BAR_MEM(testval)) + testval &= PCIM_BAR_MEM_BASE; + else + testval &= PCIM_BAR_IO_BASE; + + *start = map; + if (*count == 0) + *count = (~testval) + 1; + *end = *start + *count - 1; + } + /* * Allocate enough resource, and then write back the * appropriate BAR for that resource. */ - resource_list_add(rl, type, *rid, start, end, count); - res = resource_list_reserve(rl, dev, child, type, rid, start, end, - count, flags & ~RF_ACTIVE); + resource_list_add(rl, type, *rid, *start, *end, *count); + res = resource_list_reserve(rl, dev, child, type, rid, *start, *end, + *count, flags & ~RF_ACTIVE); if (res == NULL) { resource_list_delete(rl, type, *rid); device_printf(child, "%#lx bytes of rid %#x res %d failed (%#lx, %#lx).\n", - count, *rid, type, start, end); + *count, *rid, type, *start, *end); goto out; } if (bootverbose) device_printf(child, "Lazy allocation of %#lx bytes rid %#x type %d at %#lx\n", - count, *rid, type, rman_get_start(res)); + *count, *rid, type, rman_get_start(res)); map = rman_get_start(res); pci_write_bar(child, pm, map); out: @@ -4907,8 +4926,8 @@ /* Reserve resources for this BAR if needed. */ rle = resource_list_find(rl, type, *rid); if (rle == NULL) { - res = pci_reserve_map(dev, child, type, rid, start, end, - count, num, flags); + res = pci_reserve_map(dev, child, type, rid, &start, + &end, &count, num, flags); if (res == NULL) return (NULL); }