Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/pci/pci.c
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
resource_list_add(&dinfo->resources, SYS_RES_IRQ, i + 1, irq, | resource_list_add(&dinfo->resources, SYS_RES_IRQ, i + 1, irq, | ||||
irq, 1); | irq, 1); | ||||
} | } | ||||
actual = i; | actual = i; | ||||
if (bootverbose) { | if (bootverbose) { | ||||
rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, 1); | rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, 1); | ||||
if (actual == 1) | if (actual == 1) | ||||
device_printf(child, "using IRQ %lu for MSI-X\n", | device_printf(child, "using IRQ %ju for MSI-X\n", | ||||
rle->start); | rle->start); | ||||
else { | else { | ||||
int run; | int run; | ||||
/* | /* | ||||
* Be fancy and try to print contiguous runs of | * Be fancy and try to print contiguous runs of | ||||
* IRQ values as ranges. 'irq' is the previous IRQ. | * IRQ values as ranges. 'irq' is the previous IRQ. | ||||
* 'run' is true if we are in a range. | * 'run' is true if we are in a range. | ||||
*/ | */ | ||||
device_printf(child, "using IRQs %lu", rle->start); | device_printf(child, "using IRQs %ju", rle->start); | ||||
irq = rle->start; | irq = rle->start; | ||||
run = 0; | run = 0; | ||||
for (i = 1; i < actual; i++) { | for (i = 1; i < actual; i++) { | ||||
rle = resource_list_find(&dinfo->resources, | rle = resource_list_find(&dinfo->resources, | ||||
SYS_RES_IRQ, i + 1); | SYS_RES_IRQ, i + 1); | ||||
/* Still in a run? */ | /* Still in a run? */ | ||||
if (rle->start == irq + 1) { | if (rle->start == irq + 1) { | ||||
run = 1; | run = 1; | ||||
irq++; | irq++; | ||||
continue; | continue; | ||||
} | } | ||||
/* Finish previous range. */ | /* Finish previous range. */ | ||||
if (run) { | if (run) { | ||||
printf("-%d", irq); | printf("-%d", irq); | ||||
run = 0; | run = 0; | ||||
} | } | ||||
/* Start new range. */ | /* Start new range. */ | ||||
printf(",%lu", rle->start); | printf(",%ju", rle->start); | ||||
irq = rle->start; | irq = rle->start; | ||||
} | } | ||||
/* Unfinished range? */ | /* Unfinished range? */ | ||||
if (run) | if (run) | ||||
printf("-%d", irq); | printf("-%d", irq); | ||||
printf(" for MSI-X\n"); | printf(" for MSI-X\n"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | |||||
if (type == SYS_RES_MEMORY && !pci_memen(dev)) | if (type == SYS_RES_MEMORY && !pci_memen(dev)) | ||||
return (barlen); | return (barlen); | ||||
} | } | ||||
count = (pci_addr_t)1 << mapsize; | count = (pci_addr_t)1 << mapsize; | ||||
flags = RF_ALIGNMENT_LOG2(mapsize); | flags = RF_ALIGNMENT_LOG2(mapsize); | ||||
if (prefetch) | if (prefetch) | ||||
flags |= RF_PREFETCHABLE; | flags |= RF_PREFETCHABLE; | ||||
if (basezero || base == pci_mapbase(testval) || pci_clear_bars) { | if (basezero || base == pci_mapbase(testval) || pci_clear_bars) { | ||||
jhb: I thought we had some sort of code somewhere to special case firmware-assigned BAR values that… | |||||
jhbUnsubmitted Not Done Inline ActionsThis is still not done? jhb: This is still not done? | |||||
start = 0; /* Let the parent decide. */ | start = 0; /* Let the parent decide. */ | ||||
end = ~0ul; | end = ~0; | ||||
} else { | } else { | ||||
start = base; | start = base; | ||||
end = base + count - 1; | end = base + count - 1; | ||||
} | } | ||||
resource_list_add(rl, type, reg, start, end, count); | resource_list_add(rl, type, reg, start, end, count); | ||||
/* | /* | ||||
* Try to allocate the resource for this BAR from our parent | * Try to allocate the resource for this BAR from our parent | ||||
* so that this resource range is already reserved. The | * so that this resource range is already reserved. The | ||||
* driver for this device will later inherit this resource in | * driver for this device will later inherit this resource in | ||||
* pci_alloc_resource(). | * pci_alloc_resource(). | ||||
*/ | */ | ||||
res = resource_list_reserve(rl, bus, dev, type, ®, start, end, count, | res = resource_list_reserve(rl, bus, dev, type, ®, start, end, count, | ||||
flags); | flags); | ||||
if (pci_do_realloc_bars && res == NULL && (start != 0 || end != ~0ul)) { | if (pci_do_realloc_bars && res == NULL && (start != 0 || end != ~0)) { | ||||
/* | /* | ||||
* If the allocation fails, try to allocate a resource for | * If the allocation fails, try to allocate a resource for | ||||
* this BAR using any available range. The firmware felt | * this BAR using any available range. The firmware felt | ||||
* it was important enough to assign a resource, so don't | * it was important enough to assign a resource, so don't | ||||
* disable decoding if we can help it. | * disable decoding if we can help it. | ||||
*/ | */ | ||||
resource_list_delete(rl, type, reg); | resource_list_delete(rl, type, reg); | ||||
resource_list_add(rl, type, reg, 0, ~0ul, count); | resource_list_add(rl, type, reg, 0, ~0, count); | ||||
res = resource_list_reserve(rl, bus, dev, type, ®, 0, ~0ul, | res = resource_list_reserve(rl, bus, dev, type, ®, 0, ~0, | ||||
count, flags); | count, flags); | ||||
} | } | ||||
if (res == NULL) { | if (res == NULL) { | ||||
/* | /* | ||||
* If the allocation fails, delete the resource list entry | * If the allocation fails, delete the resource list entry | ||||
* and disable decoding for this device. | * and disable decoding for this device. | ||||
* | * | ||||
* If the driver requests this resource in the future, | * If the driver requests this resource in the future, | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
#if defined(NEW_PCIB) && defined(PCI_RES_BUS) | #if defined(NEW_PCIB) && defined(PCI_RES_BUS) | ||||
static void | static void | ||||
pci_reserve_secbus(device_t bus, device_t dev, pcicfgregs *cfg, | pci_reserve_secbus(device_t bus, device_t dev, pcicfgregs *cfg, | ||||
struct resource_list *rl) | struct resource_list *rl) | ||||
{ | { | ||||
struct resource *res; | struct resource *res; | ||||
char *cp; | char *cp; | ||||
u_long start, end, count; | rman_res_t start, end, count; | ||||
int rid, sec_bus, sec_reg, sub_bus, sub_reg, sup_bus; | int rid, sec_bus, sec_reg, sub_bus, sub_reg, sup_bus; | ||||
switch (cfg->hdrtype & PCIM_HDRTYPE) { | switch (cfg->hdrtype & PCIM_HDRTYPE) { | ||||
case PCIM_HDRTYPE_BRIDGE: | case PCIM_HDRTYPE_BRIDGE: | ||||
sec_reg = PCIR_SECBUS_1; | sec_reg = PCIR_SECBUS_1; | ||||
sub_reg = PCIR_SUBBUS_1; | sub_reg = PCIR_SUBBUS_1; | ||||
break; | break; | ||||
case PCIM_HDRTYPE_CARDBUS: | case PCIM_HDRTYPE_CARDBUS: | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
if (bootverbose) | if (bootverbose) | ||||
printf("\tsecbus=%d, subbus=%d\n", sec_bus, sub_bus); | printf("\tsecbus=%d, subbus=%d\n", sec_bus, sub_bus); | ||||
if (sec_bus > 0 && sub_bus >= sec_bus) { | if (sec_bus > 0 && sub_bus >= sec_bus) { | ||||
start = sec_bus; | start = sec_bus; | ||||
end = sub_bus; | end = sub_bus; | ||||
count = end - start + 1; | count = end - start + 1; | ||||
resource_list_add(rl, PCI_RES_BUS, 0, 0ul, ~0ul, count); | resource_list_add(rl, PCI_RES_BUS, 0, 0, ~0, count); | ||||
/* | /* | ||||
* If requested, clear secondary bus registers in | * If requested, clear secondary bus registers in | ||||
* bridge devices to force a complete renumbering | * bridge devices to force a complete renumbering | ||||
* rather than reserving the existing range. However, | * rather than reserving the existing range. However, | ||||
* preserve the existing size. | * preserve the existing size. | ||||
*/ | */ | ||||
if (pci_clear_buses) | if (pci_clear_buses) | ||||
Show All 13 Lines | |||||
} | } | ||||
clear: | clear: | ||||
PCI_WRITE_CONFIG(bus, dev, sec_reg, 0, 1); | PCI_WRITE_CONFIG(bus, dev, sec_reg, 0, 1); | ||||
PCI_WRITE_CONFIG(bus, dev, sub_reg, 0, 1); | PCI_WRITE_CONFIG(bus, dev, sub_reg, 0, 1); | ||||
} | } | ||||
static struct resource * | static struct resource * | ||||
pci_alloc_secbus(device_t dev, device_t child, int *rid, u_long start, | pci_alloc_secbus(device_t dev, device_t child, int *rid, rman_res_t start, | ||||
u_long end, u_long count, u_int flags) | rman_res_t end, rman_res_t count, u_int flags) | ||||
{ | { | ||||
struct pci_devinfo *dinfo; | struct pci_devinfo *dinfo; | ||||
pcicfgregs *cfg; | pcicfgregs *cfg; | ||||
struct resource_list *rl; | struct resource_list *rl; | ||||
struct resource *res; | struct resource *res; | ||||
int sec_reg, sub_reg; | int sec_reg, sub_reg; | ||||
dinfo = device_get_ivars(child); | dinfo = device_get_ivars(child); | ||||
Show All 17 Lines | |||||
if (resource_list_find(rl, PCI_RES_BUS, *rid) == NULL) | if (resource_list_find(rl, PCI_RES_BUS, *rid) == NULL) | ||||
resource_list_add(rl, PCI_RES_BUS, *rid, start, end, count); | resource_list_add(rl, PCI_RES_BUS, *rid, start, end, count); | ||||
if (!resource_list_reserved(rl, PCI_RES_BUS, *rid)) { | if (!resource_list_reserved(rl, PCI_RES_BUS, *rid)) { | ||||
res = resource_list_reserve(rl, dev, child, PCI_RES_BUS, rid, | res = resource_list_reserve(rl, dev, child, PCI_RES_BUS, rid, | ||||
start, end, count, flags & ~RF_ACTIVE); | start, end, count, flags & ~RF_ACTIVE); | ||||
if (res == NULL) { | if (res == NULL) { | ||||
resource_list_delete(rl, PCI_RES_BUS, *rid); | resource_list_delete(rl, PCI_RES_BUS, *rid); | ||||
device_printf(child, "allocating %lu bus%s failed\n", | device_printf(child, "allocating %ju bus%s failed\n", | ||||
count, count == 1 ? "" : "es"); | count, count == 1 ? "" : "es"); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(child, | device_printf(child, | ||||
"Lazy allocation of %lu bus%s at %lu\n", count, | "Lazy allocation of %ju bus%s at %ju\n", count, | ||||
count == 1 ? "" : "es", rman_get_start(res)); | count == 1 ? "" : "es", rman_get_start(res)); | ||||
PCI_WRITE_CONFIG(dev, child, sec_reg, rman_get_start(res), 1); | PCI_WRITE_CONFIG(dev, child, sec_reg, rman_get_start(res), 1); | ||||
PCI_WRITE_CONFIG(dev, child, sub_reg, rman_get_end(res), 1); | PCI_WRITE_CONFIG(dev, child, sub_reg, rman_get_end(res), 1); | ||||
} | } | ||||
return (resource_list_alloc(rl, dev, child, PCI_RES_BUS, rid, start, | return (resource_list_alloc(rl, dev, child, PCI_RES_BUS, rid, start, | ||||
end, count, flags)); | end, count, flags)); | ||||
} | } | ||||
#endif | #endif | ||||
Show All 33 Lines | |||||
if (q->devid != 0) { | if (q->devid != 0) { | ||||
i++; | i++; | ||||
continue; | continue; | ||||
} | } | ||||
i += pci_add_map(bus, dev, PCIR_BAR(i), rl, force, | i += pci_add_map(bus, dev, PCIR_BAR(i), rl, force, | ||||
prefetchmask & (1 << i)); | prefetchmask & (1 << i)); | ||||
} | } | ||||
/* | /* | ||||
Done Inline ActionsThe braces here seem to be a gratuitous change? jhb: The braces here seem to be a gratuitous change? | |||||
Not Done Inline ActionsLeftover from other debugging. jhibbits: Leftover from other debugging. | |||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
struct resource_list *rl; | struct resource_list *rl; | ||||
int retval = 0; | int retval = 0; | ||||
dinfo = device_get_ivars(child); | dinfo = device_get_ivars(child); | ||||
rl = &dinfo->resources; | rl = &dinfo->resources; | ||||
retval += bus_print_child_header(dev, child); | retval += bus_print_child_header(dev, child); | ||||
retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx"); | retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#jx"); | ||||
retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx"); | retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); | ||||
retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); | retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd"); | ||||
if (device_get_flags(dev)) | if (device_get_flags(dev)) | ||||
retval += printf(" flags %#x", device_get_flags(dev)); | retval += printf(" flags %#x", device_get_flags(dev)); | ||||
retval += printf(" at device %d.%d", pci_get_slot(child), | retval += printf(" at device %d.%d", pci_get_slot(child), | ||||
pci_get_function(child)); | pci_get_function(child)); | ||||
retval += bus_print_child_domain(dev, child); | retval += bus_print_child_domain(dev, child); | ||||
retval += bus_print_child_footer(dev, child); | retval += bus_print_child_footer(dev, child); | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
(p->pc_device << 16) | p->pc_vendor, | (p->pc_device << 16) | p->pc_vendor, | ||||
p->pc_revid, p->pc_hdr); | p->pc_revid, p->pc_hdr); | ||||
} | } | ||||
} | } | ||||
#endif /* DDB */ | #endif /* DDB */ | ||||
static struct resource * | static struct resource * | ||||
pci_reserve_map(device_t dev, device_t child, int type, int *rid, | pci_reserve_map(device_t dev, device_t child, int type, int *rid, | ||||
u_long start, u_long end, u_long count, u_int num, u_int flags) | 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); | struct pci_devinfo *dinfo = device_get_ivars(child); | ||||
struct resource_list *rl = &dinfo->resources; | struct resource_list *rl = &dinfo->resources; | ||||
struct resource *res; | struct resource *res; | ||||
struct pci_map *pm; | struct pci_map *pm; | ||||
pci_addr_t map, testval; | pci_addr_t map, testval; | ||||
int mapsize; | int mapsize; | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
* appropriate BAR for that resource. | * appropriate BAR for that resource. | ||||
*/ | */ | ||||
resource_list_add(rl, type, *rid, start, end, count); | resource_list_add(rl, type, *rid, start, end, count); | ||||
res = resource_list_reserve(rl, dev, child, type, rid, start, end, | res = resource_list_reserve(rl, dev, child, type, rid, start, end, | ||||
count, flags & ~RF_ACTIVE); | count, flags & ~RF_ACTIVE); | ||||
if (res == NULL) { | if (res == NULL) { | ||||
resource_list_delete(rl, type, *rid); | resource_list_delete(rl, type, *rid); | ||||
device_printf(child, | device_printf(child, | ||||
"%#lx bytes of rid %#x res %d failed (%#lx, %#lx).\n", | "%#jx bytes of rid %#x res %d failed (%#jx, %#jx).\n", | ||||
count, *rid, type, start, end); | count, *rid, type, start, end); | ||||
goto out; | goto out; | ||||
} | } | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(child, | device_printf(child, | ||||
"Lazy allocation of %#lx bytes rid %#x type %d at %#lx\n", | "Lazy allocation of %#jx bytes rid %#x type %d at %#jx\n", | ||||
count, *rid, type, rman_get_start(res)); | count, *rid, type, rman_get_start(res)); | ||||
map = rman_get_start(res); | map = rman_get_start(res); | ||||
pci_write_bar(child, pm, map); | pci_write_bar(child, pm, map); | ||||
out: | out: | ||||
return (res); | return (res); | ||||
} | } | ||||
struct resource * | struct resource * | ||||
pci_alloc_multi_resource(device_t dev, device_t child, int type, int *rid, | pci_alloc_multi_resource(device_t dev, device_t child, int type, int *rid, | ||||
u_long start, u_long end, u_long count, u_long num, u_int flags) | rman_res_t start, rman_res_t end, rman_res_t count, u_long num, | ||||
u_int flags) | |||||
{ | { | ||||
struct pci_devinfo *dinfo; | struct pci_devinfo *dinfo; | ||||
struct resource_list *rl; | struct resource_list *rl; | ||||
struct resource_list_entry *rle; | struct resource_list_entry *rle; | ||||
struct resource *res; | struct resource *res; | ||||
pcicfgregs *cfg; | pcicfgregs *cfg; | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
} | } | ||||
return (resource_list_alloc(rl, dev, child, type, rid, | return (resource_list_alloc(rl, dev, child, type, rid, | ||||
start, end, count, flags)); | start, end, count, flags)); | ||||
} | } | ||||
struct resource * | struct resource * | ||||
pci_alloc_resource(device_t dev, device_t child, int type, int *rid, | pci_alloc_resource(device_t dev, device_t child, int type, int *rid, | ||||
u_long start, u_long end, u_long count, u_int flags) | rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) | ||||
{ | { | ||||
#ifdef PCI_IOV | #ifdef PCI_IOV | ||||
struct pci_devinfo *dinfo; | struct pci_devinfo *dinfo; | ||||
#endif | #endif | ||||
if (device_get_parent(child) != dev) | if (device_get_parent(child) != dev) | ||||
return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, | return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, | ||||
type, rid, start, end, count, flags)); | type, rid, start, end, count, flags)); | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
if (rle == NULL) | if (rle == NULL) | ||||
return; | return; | ||||
if (rle->res) { | if (rle->res) { | ||||
if (rman_get_flags(rle->res) & RF_ACTIVE || | if (rman_get_flags(rle->res) & RF_ACTIVE || | ||||
resource_list_busy(rl, type, rid)) { | resource_list_busy(rl, type, rid)) { | ||||
device_printf(dev, "delete_resource: " | device_printf(dev, "delete_resource: " | ||||
"Resource still owned by child, oops. " | "Resource still owned by child, oops. " | ||||
"(type=%d, rid=%d, addr=%lx)\n", | "(type=%d, rid=%d, addr=%jx)\n", | ||||
type, rid, rman_get_start(rle->res)); | type, rid, rman_get_start(rle->res)); | ||||
return; | return; | ||||
} | } | ||||
resource_list_unreserve(rl, dev, child, type, rid); | resource_list_unreserve(rl, dev, child, type, rid); | ||||
} | } | ||||
resource_list_delete(rl, type, rid); | resource_list_delete(rl, type, rid); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 42 Lines • Show Last 20 Lines |
I thought we had some sort of code somewhere to special case firmware-assigned BAR values that were "out of range", but I can't find it now. Ah, it is this code in pci_add_map():
This check can be removed.