Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/acpica/acpi_pcib_acpi.c
Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | static int acpi_pcib_alloc_msix(device_t pcib, device_t dev, | ||||
int *irq); | int *irq); | ||||
static struct resource *acpi_pcib_acpi_alloc_resource(device_t dev, | static struct resource *acpi_pcib_acpi_alloc_resource(device_t dev, | ||||
device_t child, int type, int *rid, | device_t child, int type, int *rid, | ||||
rman_res_t start, rman_res_t end, rman_res_t count, | rman_res_t start, rman_res_t end, rman_res_t count, | ||||
u_int flags); | u_int flags); | ||||
static int acpi_pcib_acpi_adjust_resource(device_t dev, | static int acpi_pcib_acpi_adjust_resource(device_t dev, | ||||
device_t child, int type, struct resource *r, | device_t child, int type, struct resource *r, | ||||
rman_res_t start, rman_res_t end); | rman_res_t start, rman_res_t end); | ||||
#ifdef PCI_RES_BUS | |||||
static int acpi_pcib_acpi_release_resource(device_t dev, | static int acpi_pcib_acpi_release_resource(device_t dev, | ||||
device_t child, int type, int rid, | device_t child, int type, int rid, | ||||
struct resource *r); | struct resource *r); | ||||
#endif | |||||
static int acpi_pcib_request_feature(device_t pcib, device_t dev, | static int acpi_pcib_request_feature(device_t pcib, device_t dev, | ||||
enum pci_feature feature); | enum pci_feature feature); | ||||
static bus_dma_tag_t acpi_pcib_get_dma_tag(device_t bus, device_t child); | static bus_dma_tag_t acpi_pcib_get_dma_tag(device_t bus, device_t child); | ||||
static device_method_t acpi_pcib_acpi_methods[] = { | static device_method_t acpi_pcib_acpi_methods[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
DEVMETHOD(device_probe, acpi_pcib_acpi_probe), | DEVMETHOD(device_probe, acpi_pcib_acpi_probe), | ||||
DEVMETHOD(device_attach, acpi_pcib_acpi_attach), | DEVMETHOD(device_attach, acpi_pcib_acpi_attach), | ||||
DEVMETHOD(device_shutdown, bus_generic_shutdown), | DEVMETHOD(device_shutdown, bus_generic_shutdown), | ||||
DEVMETHOD(device_suspend, bus_generic_suspend), | DEVMETHOD(device_suspend, bus_generic_suspend), | ||||
DEVMETHOD(device_resume, bus_generic_resume), | DEVMETHOD(device_resume, bus_generic_resume), | ||||
/* Bus interface */ | /* Bus interface */ | ||||
DEVMETHOD(bus_read_ivar, acpi_pcib_read_ivar), | DEVMETHOD(bus_read_ivar, acpi_pcib_read_ivar), | ||||
DEVMETHOD(bus_write_ivar, acpi_pcib_write_ivar), | DEVMETHOD(bus_write_ivar, acpi_pcib_write_ivar), | ||||
DEVMETHOD(bus_alloc_resource, acpi_pcib_acpi_alloc_resource), | DEVMETHOD(bus_alloc_resource, acpi_pcib_acpi_alloc_resource), | ||||
DEVMETHOD(bus_adjust_resource, acpi_pcib_acpi_adjust_resource), | DEVMETHOD(bus_adjust_resource, acpi_pcib_acpi_adjust_resource), | ||||
#if defined(PCI_RES_BUS) | |||||
DEVMETHOD(bus_release_resource, acpi_pcib_acpi_release_resource), | DEVMETHOD(bus_release_resource, acpi_pcib_acpi_release_resource), | ||||
#endif | |||||
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), | DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), | ||||
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), | DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), | ||||
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), | DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), | ||||
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), | DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), | ||||
DEVMETHOD(bus_get_cpus, acpi_pcib_get_cpus), | DEVMETHOD(bus_get_cpus, acpi_pcib_get_cpus), | ||||
DEVMETHOD(bus_get_dma_tag, acpi_pcib_get_dma_tag), | DEVMETHOD(bus_get_dma_tag, acpi_pcib_get_dma_tag), | ||||
/* pcib interface */ | /* pcib interface */ | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | case ACPI_MEMORY_RANGE: | ||||
* XXX: Parse prefetch flag out of | * XXX: Parse prefetch flag out of | ||||
* TypeSpecific. | * TypeSpecific. | ||||
*/ | */ | ||||
} | } | ||||
break; | break; | ||||
case ACPI_IO_RANGE: | case ACPI_IO_RANGE: | ||||
type = SYS_RES_IOPORT; | type = SYS_RES_IOPORT; | ||||
break; | break; | ||||
#ifdef PCI_RES_BUS | |||||
case ACPI_BUS_NUMBER_RANGE: | case ACPI_BUS_NUMBER_RANGE: | ||||
type = PCI_RES_BUS; | type = PCI_RES_BUS; | ||||
break; | break; | ||||
#endif | |||||
default: | default: | ||||
return (AE_OK); | return (AE_OK); | ||||
} | } | ||||
if (min + length - 1 != max) | if (min + length - 1 != max) | ||||
device_printf(sc->ap_dev, | device_printf(sc->ap_dev, | ||||
"Length mismatch for %d range: %jx vs %jx\n", type, | "Length mismatch for %d range: %jx vs %jx\n", type, | ||||
(uintmax_t)(max - min + 1), (uintmax_t)length); | (uintmax_t)(max - min + 1), (uintmax_t)length); | ||||
Show All 18 Lines | if (error) | ||||
type, (uintmax_t)min, (uintmax_t)max, error); | type, (uintmax_t)min, (uintmax_t)max, error); | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
return (AE_OK); | return (AE_OK); | ||||
} | } | ||||
#if defined(PCI_RES_BUS) | |||||
static int | static int | ||||
first_decoded_bus(struct acpi_hpcib_softc *sc, rman_res_t *startp) | first_decoded_bus(struct acpi_hpcib_softc *sc, rman_res_t *startp) | ||||
{ | { | ||||
struct resource_list_entry *rle; | struct resource_list_entry *rle; | ||||
rle = resource_list_find(&sc->ap_host_res.hr_rl, PCI_RES_BUS, 0); | rle = resource_list_find(&sc->ap_host_res.hr_rl, PCI_RES_BUS, 0); | ||||
if (rle == NULL) | if (rle == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
*startp = rle->start; | *startp = rle->start; | ||||
return (0); | return (0); | ||||
} | } | ||||
#endif | |||||
static int | static int | ||||
acpi_pcib_osc(struct acpi_hpcib_softc *sc, uint32_t osc_ctl) | acpi_pcib_osc(struct acpi_hpcib_softc *sc, uint32_t osc_ctl) | ||||
{ | { | ||||
ACPI_STATUS status; | ACPI_STATUS status; | ||||
uint32_t cap_set[3]; | uint32_t cap_set[3]; | ||||
static uint8_t pci_host_bridge_uuid[ACPI_UUID_LENGTH] = { | static uint8_t pci_host_bridge_uuid[ACPI_UUID_LENGTH] = { | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
acpi_pcib_acpi_attach(device_t dev) | acpi_pcib_acpi_attach(device_t dev) | ||||
{ | { | ||||
struct acpi_hpcib_softc *sc; | struct acpi_hpcib_softc *sc; | ||||
ACPI_STATUS status; | ACPI_STATUS status; | ||||
static int bus0_seen = 0; | static int bus0_seen = 0; | ||||
u_int slot, func, busok; | u_int slot, func, busok; | ||||
#if defined(PCI_RES_BUS) | |||||
struct resource *bus_res; | struct resource *bus_res; | ||||
rman_res_t start; | rman_res_t start; | ||||
int rid; | int rid; | ||||
#endif | |||||
int error, domain; | int error, domain; | ||||
uint8_t busno; | uint8_t busno; | ||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); | ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
sc->ap_dev = dev; | sc->ap_dev = dev; | ||||
sc->ap_handle = acpi_get_handle(dev); | sc->ap_handle = acpi_get_handle(dev); | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | if (sc->ap_addr != -1) { | ||||
device_printf(dev, "couldn't read bus number from cfg space\n"); | device_printf(dev, "couldn't read bus number from cfg space\n"); | ||||
else { | else { | ||||
sc->ap_bus = busno; | sc->ap_bus = busno; | ||||
busok = 1; | busok = 1; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
#if defined(PCI_RES_BUS) | |||||
/* | /* | ||||
* If nothing else worked, hope that ACPI at least lays out the | * If nothing else worked, hope that ACPI at least lays out the | ||||
* Host-PCI bridges in order and that as a result the next free | * Host-PCI bridges in order and that as a result the next free | ||||
* bus number is our bus number. | * bus number is our bus number. | ||||
*/ | */ | ||||
if (busok == 0) { | if (busok == 0) { | ||||
/* | /* | ||||
* If we have a region of bus numbers, use the first | * If we have a region of bus numbers, use the first | ||||
Show All 22 Lines | if (busok == 0) { | ||||
if (first_decoded_bus(sc, &start) == 0 && sc->ap_bus != start) { | if (first_decoded_bus(sc, &start) == 0 && sc->ap_bus != start) { | ||||
device_printf(dev, | device_printf(dev, | ||||
"bus number %d does not match start of decoded range %ju\n", | "bus number %d does not match start of decoded range %ju\n", | ||||
sc->ap_bus, (uintmax_t)start); | sc->ap_bus, (uintmax_t)start); | ||||
pcib_host_res_free(dev, &sc->ap_host_res); | pcib_host_res_free(dev, &sc->ap_host_res); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
} | } | ||||
#else | |||||
/* | |||||
* If nothing else worked, hope that ACPI at least lays out the | |||||
* host-PCI bridges in order and that as a result our unit number | |||||
* is actually our bus number. There are several reasons this | |||||
* might not be true. | |||||
*/ | |||||
if (busok == 0) { | |||||
sc->ap_bus = device_get_unit(dev); | |||||
device_printf(dev, "trying bus number %d\n", sc->ap_bus); | |||||
} | |||||
#endif | |||||
/* If this is bus 0 on segment 0, note that it has been seen already. */ | /* If this is bus 0 on segment 0, note that it has been seen already. */ | ||||
if (sc->ap_segment == 0 && sc->ap_bus == 0) | if (sc->ap_segment == 0 && sc->ap_bus == 0) | ||||
bus0_seen = 1; | bus0_seen = 1; | ||||
acpi_pcib_fetch_prt(dev, &sc->ap_prt); | acpi_pcib_fetch_prt(dev, &sc->ap_prt); | ||||
error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, | error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, | ||||
Show All 14 Lines | acpi_pcib_acpi_attach(device_t dev) | ||||
sc->ap_dma_tag = NULL; | sc->ap_dma_tag = NULL; | ||||
error = ENXIO; | error = ENXIO; | ||||
goto errout; | goto errout; | ||||
} | } | ||||
return (bus_generic_attach(dev)); | return (bus_generic_attach(dev)); | ||||
errout: | errout: | ||||
device_printf(device_get_parent(dev), "couldn't attach pci bus\n"); | device_printf(device_get_parent(dev), "couldn't attach pci bus\n"); | ||||
#if defined(PCI_RES_BUS) | |||||
pcib_host_res_free(dev, &sc->ap_host_res); | pcib_host_res_free(dev, &sc->ap_host_res); | ||||
#endif | |||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Support for standard PCI bridge ivars. | * Support for standard PCI bridge ivars. | ||||
*/ | */ | ||||
static int | static int | ||||
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) | acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | acpi_pcib_acpi_alloc_resource(device_t dev, device_t child, int type, int *rid, | ||||
struct acpi_hpcib_softc *sc; | struct acpi_hpcib_softc *sc; | ||||
struct resource *res; | struct resource *res; | ||||
#if defined(__i386__) || defined(__amd64__) | #if defined(__i386__) || defined(__amd64__) | ||||
start = hostb_alloc_start(type, start, end, count); | start = hostb_alloc_start(type, start, end, count); | ||||
#endif | #endif | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
#ifdef PCI_RES_BUS | |||||
if (type == PCI_RES_BUS) | if (type == PCI_RES_BUS) | ||||
return (pci_domain_alloc_bus(sc->ap_segment, child, rid, start, end, | return (pci_domain_alloc_bus(sc->ap_segment, child, rid, start, end, | ||||
count, flags)); | count, flags)); | ||||
#endif | |||||
res = pcib_host_res_alloc(&sc->ap_host_res, child, type, rid, start, end, | res = pcib_host_res_alloc(&sc->ap_host_res, child, type, rid, start, end, | ||||
count, flags); | count, flags); | ||||
/* | /* | ||||
* XXX: If this is a request for a specific range, assume it is | * XXX: If this is a request for a specific range, assume it is | ||||
* correct and pass it up to the parent. What we probably want to | * correct and pass it up to the parent. What we probably want to | ||||
* do long-term is explicitly trust any firmware-configured | * do long-term is explicitly trust any firmware-configured | ||||
* resources during the initial bus scan on boot and then disable | * resources during the initial bus scan on boot and then disable | ||||
* this after that. | * this after that. | ||||
*/ | */ | ||||
if (res == NULL && start + count - 1 == end) | if (res == NULL && start + count - 1 == end) | ||||
res = bus_generic_alloc_resource(dev, child, type, rid, start, end, | res = bus_generic_alloc_resource(dev, child, type, rid, start, end, | ||||
count, flags); | count, flags); | ||||
return (res); | return (res); | ||||
} | } | ||||
int | int | ||||
acpi_pcib_acpi_adjust_resource(device_t dev, device_t child, int type, | acpi_pcib_acpi_adjust_resource(device_t dev, device_t child, int type, | ||||
struct resource *r, rman_res_t start, rman_res_t end) | struct resource *r, rman_res_t start, rman_res_t end) | ||||
{ | { | ||||
struct acpi_hpcib_softc *sc; | struct acpi_hpcib_softc *sc; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
#ifdef PCI_RES_BUS | |||||
if (type == PCI_RES_BUS) | if (type == PCI_RES_BUS) | ||||
return (pci_domain_adjust_bus(sc->ap_segment, child, r, start, | return (pci_domain_adjust_bus(sc->ap_segment, child, r, start, | ||||
end)); | end)); | ||||
#endif | |||||
return (pcib_host_res_adjust(&sc->ap_host_res, child, type, r, start, | return (pcib_host_res_adjust(&sc->ap_host_res, child, type, r, start, | ||||
end)); | end)); | ||||
} | } | ||||
#ifdef PCI_RES_BUS | |||||
int | int | ||||
acpi_pcib_acpi_release_resource(device_t dev, device_t child, int type, int rid, | acpi_pcib_acpi_release_resource(device_t dev, device_t child, int type, int rid, | ||||
struct resource *r) | struct resource *r) | ||||
{ | { | ||||
struct acpi_hpcib_softc *sc; | struct acpi_hpcib_softc *sc; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
if (type == PCI_RES_BUS) | if (type == PCI_RES_BUS) | ||||
return (pci_domain_release_bus(sc->ap_segment, child, rid, r)); | return (pci_domain_release_bus(sc->ap_segment, child, rid, r)); | ||||
return (bus_generic_release_resource(dev, child, type, rid, r)); | return (bus_generic_release_resource(dev, child, type, rid, r)); | ||||
} | } | ||||
#endif | |||||
static int | static int | ||||
acpi_pcib_request_feature(device_t pcib, device_t dev, enum pci_feature feature) | acpi_pcib_request_feature(device_t pcib, device_t dev, enum pci_feature feature) | ||||
{ | { | ||||
uint32_t osc_ctl; | uint32_t osc_ctl; | ||||
struct acpi_hpcib_softc *sc; | struct acpi_hpcib_softc *sc; | ||||
sc = device_get_softc(pcib); | sc = device_get_softc(pcib); | ||||
Show All 24 Lines |