freebsd-dev/sys/dev/acpica/acpi_pcib_acpi.c

328 lines
10 KiB
C
Raw Normal View History

/*-
* Copyright (c) 2000 Michael Smith
* Copyright (c) 2000 BSDi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
2005-03-02 09:22:34 +00:00
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
2004-05-28 16:38:37 +00:00
#include <sys/malloc.h>
2004-05-30 20:08:47 +00:00
#include <sys/module.h>
#include <sys/sysctl.h>
2005-09-11 18:39:03 +00:00
#include <contrib/dev/acpica/acpi.h>
#include <dev/acpica/acpivar.h>
#include <machine/pci_cfgreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcib_private.h>
#include "pcib_if.h"
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
#include <dev/acpica/acpi_pcibvar.h>
2004-05-28 16:38:37 +00:00
/* Hooks for the ACPI CA debugging infrastructure. */
#define _COMPONENT ACPI_BUS
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
ACPI_MODULE_NAME("PCI_ACPI")
- Convert a lot of homebrew debugging output to use the ACPI CA debugging infrastructure. It's not perfect, but it's a lot better than what we've been using so far. The following rules apply to this: o BSD component names should be capitalised o Layer names should be taken from the non-CA set for now. We may elect to add some new BSD-specific layers later. - Make it possible to turn off selective debugging flags or layers by listing them in debug.acpi.layer or debug.acpi.level prefixed with !. - Fully implement support for avoiding nodes in the ACPI namespace. Nodes may be listed in the debug.acpi.avoid environment variable; these nodes and all their children will be ignored (although still scanned over) by ACPI functions which scan the namespace. Multiple nodes can be specified, separated by whitespace. - Implement support for selectively disabling ACPI subsystem components via the debug.acpi.disable environment variable. The following components can be disabled: o bus creation/scanning of the ACPI 'bus' o children attachment of children to the ACPI 'bus' o button the acpi_button control-method button driver o ec the acpi_ec embedded-controller driver o isa acpi replacement of PnP BIOS for ISA device discovery o lid the control-method lid switch driver o pci pci root-bus discovery o processor CPU power/speed management o thermal system temperature detection and control o timer ACPI timecounter Multiple components may be disabled by specifying their name(s) separated by whitespace. - Add support for ioctl registration. ACPI subsystem components may register ioctl handlers with the /dev/acpi generic ioctl handler, allowing us to avoid the need for a multitude of /dev/acpi* control devices, etc.
2000-12-08 09:16:20 +00:00
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
struct acpi_hpcib_softc {
device_t ap_dev;
ACPI_HANDLE ap_handle;
int ap_flags;
int ap_segment; /* analagous to Alpha 'hose' */
int ap_bus; /* bios-assigned bus number */
ACPI_BUFFER ap_prt; /* interrupt routing table */
};
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
static int acpi_pcib_acpi_probe(device_t bus);
static int acpi_pcib_acpi_attach(device_t bus);
static int acpi_pcib_acpi_resume(device_t bus);
2004-05-28 16:38:37 +00:00
static int acpi_pcib_read_ivar(device_t dev, device_t child,
int which, uintptr_t *result);
static int acpi_pcib_write_ivar(device_t dev, device_t child,
int which, uintptr_t value);
static uint32_t acpi_pcib_read_config(device_t dev, int bus, int slot,
int func, int reg, int bytes);
static void acpi_pcib_write_config(device_t dev, int bus, int slot,
int func, int reg, uint32_t data, int bytes);
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
static int acpi_pcib_acpi_route_interrupt(device_t pcib,
2004-05-28 16:38:37 +00:00
device_t dev, int pin);
static struct resource *acpi_pcib_acpi_alloc_resource(device_t dev,
2004-10-31 15:02:53 +00:00
device_t child, int type, int *rid,
u_long start, u_long end, u_long count,
u_int flags);
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
static device_method_t acpi_pcib_acpi_methods[] = {
/* Device interface */
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
DEVMETHOD(device_probe, acpi_pcib_acpi_probe),
DEVMETHOD(device_attach, acpi_pcib_acpi_attach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, acpi_pcib_acpi_resume),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_read_ivar, acpi_pcib_read_ivar),
DEVMETHOD(bus_write_ivar, acpi_pcib_write_ivar),
DEVMETHOD(bus_alloc_resource, acpi_pcib_acpi_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
2004-10-31 15:02:53 +00:00
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
/* pcib interface */
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
DEVMETHOD(pcib_maxslots, pcib_maxslots),
DEVMETHOD(pcib_read_config, acpi_pcib_read_config),
DEVMETHOD(pcib_write_config, acpi_pcib_write_config),
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
DEVMETHOD(pcib_route_interrupt, acpi_pcib_acpi_route_interrupt),
{0, 0}
};
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
static driver_t acpi_pcib_acpi_driver = {
"pcib",
acpi_pcib_acpi_methods,
sizeof(struct acpi_hpcib_softc),
};
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
DRIVER_MODULE(acpi_pcib, acpi, acpi_pcib_acpi_driver, pcib_devclass, 0, 0);
MODULE_DEPEND(acpi_pcib, acpi, 1, 1, 1);
static int
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
acpi_pcib_acpi_probe(device_t dev)
{
static char *pcib_ids[] = { "PNP0A03", NULL };
if (acpi_disabled("pcib") ||
ACPI_ID_PROBE(device_get_parent(dev), dev, pcib_ids) == NULL)
return (ENXIO);
if (pci_cfgregopen() == 0)
return (ENXIO);
device_set_desc(dev, "ACPI Host-PCI bridge");
return (0);
}
static int
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
acpi_pcib_acpi_attach(device_t dev)
{
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
struct acpi_hpcib_softc *sc;
ACPI_STATUS status;
u_int addr, slot, func, busok;
uint8_t busno;
- Convert a lot of homebrew debugging output to use the ACPI CA debugging infrastructure. It's not perfect, but it's a lot better than what we've been using so far. The following rules apply to this: o BSD component names should be capitalised o Layer names should be taken from the non-CA set for now. We may elect to add some new BSD-specific layers later. - Make it possible to turn off selective debugging flags or layers by listing them in debug.acpi.layer or debug.acpi.level prefixed with !. - Fully implement support for avoiding nodes in the ACPI namespace. Nodes may be listed in the debug.acpi.avoid environment variable; these nodes and all their children will be ignored (although still scanned over) by ACPI functions which scan the namespace. Multiple nodes can be specified, separated by whitespace. - Implement support for selectively disabling ACPI subsystem components via the debug.acpi.disable environment variable. The following components can be disabled: o bus creation/scanning of the ACPI 'bus' o children attachment of children to the ACPI 'bus' o button the acpi_button control-method button driver o ec the acpi_ec embedded-controller driver o isa acpi replacement of PnP BIOS for ISA device discovery o lid the control-method lid switch driver o pci pci root-bus discovery o processor CPU power/speed management o thermal system temperature detection and control o timer ACPI timecounter Multiple components may be disabled by specifying their name(s) separated by whitespace. - Add support for ioctl registration. ACPI subsystem components may register ioctl handlers with the /dev/acpi generic ioctl handler, allowing us to avoid the need for a multitude of /dev/acpi* control devices, etc.
2000-12-08 09:16:20 +00:00
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
sc = device_get_softc(dev);
sc->ap_dev = dev;
sc->ap_handle = acpi_get_handle(dev);
/*
* Get our base bus number by evaluating _BBN.
* If this doesn't work, we assume we're bus number 0.
*
2004-10-31 15:02:53 +00:00
* XXX note that it may also not exist in the case where we are
* meant to use a private configuration space mechanism for this bus,
* so we should dig out our resources and check to see if we have
* anything like that. How do we do this?
* XXX If we have the requisite information, and if we don't think the
* default PCI configuration space handlers can deal with this bus,
* we should attach our own handler.
* XXX invoke _REG on this for the PCI config space address space?
* XXX It seems many BIOS's with multiple Host-PCI bridges do not set
* _BBN correctly. They set _BBN to zero for all bridges. Thus,
* if _BBN is zero and pcib0 already exists, we try to read our
* bus number from the configuration registers at address _ADR.
*/
status = acpi_GetInteger(sc->ap_handle, "_BBN", &sc->ap_bus);
if (ACPI_FAILURE(status)) {
if (status != AE_NOT_FOUND) {
device_printf(dev, "could not evaluate _BBN - %s\n",
AcpiFormatException(status));
2004-05-28 16:38:37 +00:00
return_VALUE (ENXIO);
} else {
2004-05-28 16:38:37 +00:00
/* If it's not found, assume 0. */
sc->ap_bus = 0;
}
}
/*
* If the bus is zero and pcib0 already exists, read the bus number
* via PCI config space.
*/
busok = 1;
if (sc->ap_bus == 0 && devclass_get_device(pcib_devclass, 0) != dev) {
busok = 0;
status = acpi_GetInteger(sc->ap_handle, "_ADR", &addr);
if (ACPI_FAILURE(status)) {
if (status != AE_NOT_FOUND) {
device_printf(dev, "could not evaluate _ADR - %s\n",
AcpiFormatException(status));
2004-05-28 16:38:37 +00:00
return_VALUE (ENXIO);
} else
2004-05-28 16:38:37 +00:00
device_printf(dev, "couldn't find _ADR\n");
} else {
/* XXX: We assume bus 0. */
slot = ACPI_ADR_PCI_SLOT(addr);
func = ACPI_ADR_PCI_FUNC(addr);
if (bootverbose)
device_printf(dev, "reading config registers from 0:%d:%d\n",
slot, func);
if (host_pcib_get_busno(pci_cfgregread, 0, slot, func, &busno) == 0)
2004-05-28 16:38:37 +00:00
device_printf(dev, "couldn't read bus number from cfg space\n");
else {
sc->ap_bus = busno;
busok = 1;
}
}
}
/*
* 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);
}
/*
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
* Get our segment number by evaluating _SEG
* It's OK for this to not exist.
*/
2004-05-28 16:38:37 +00:00
status = acpi_GetInteger(sc->ap_handle, "_SEG", &sc->ap_segment);
if (ACPI_FAILURE(status)) {
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
if (status != AE_NOT_FOUND) {
2004-05-28 16:38:37 +00:00
device_printf(dev, "could not evaluate _SEG - %s\n",
AcpiFormatException(status));
return_VALUE (ENXIO);
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
}
2004-05-28 16:38:37 +00:00
/* If it's not found, assume 0. */
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
sc->ap_segment = 0;
}
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
return (acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_bus));
}
static int
acpi_pcib_acpi_resume(device_t dev)
{
return (acpi_pcib_resume(dev));
}
/*
* Support for standard PCI bridge ivars.
*/
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
struct acpi_hpcib_softc *sc = device_get_softc(dev);
switch (which) {
2004-05-28 16:38:37 +00:00
case PCIB_IVAR_BUS:
*result = sc->ap_bus;
2004-05-28 16:38:37 +00:00
return (0);
case ACPI_IVAR_HANDLE:
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
*result = (uintptr_t)sc->ap_handle;
2004-05-28 16:38:37 +00:00
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)sc->ap_flags;
return (0);
}
2004-05-28 16:38:37 +00:00
return (ENOENT);
}
static int
acpi_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
{
2004-10-31 15:02:53 +00:00
struct acpi_hpcib_softc *sc = device_get_softc(dev);
switch (which) {
2004-05-28 16:38:37 +00:00
case PCIB_IVAR_BUS:
sc->ap_bus = value;
2004-05-28 16:38:37 +00:00
return (0);
case ACPI_IVAR_HANDLE:
sc->ap_handle = (ACPI_HANDLE)value;
return (0);
case ACPI_IVAR_FLAGS:
sc->ap_flags = (int)value;
return (0);
}
2004-05-28 16:38:37 +00:00
return (ENOENT);
}
2004-05-28 16:38:37 +00:00
static uint32_t
acpi_pcib_read_config(device_t dev, int bus, int slot, int func, int reg,
int bytes)
{
2004-05-28 16:38:37 +00:00
return (pci_cfgregread(bus, slot, func, reg, bytes));
}
static void
2004-05-28 16:38:37 +00:00
acpi_pcib_write_config(device_t dev, int bus, int slot, int func, int reg,
uint32_t data, int bytes)
{
pci_cfgregwrite(bus, slot, func, reg, data, bytes);
}
static int
Overhaul the ACPI PCI bridge driver a bit: - Add an ACPI PCI-PCI bridge driver (the previous driver just handled Host-PCI bridges) that is a PCI driver that is a subclass of the generic PCI-PCI bridge driver. It overrides probe, attach, read_ivar, and pci_route_interrupt. - The probe routine only succeeds if our parent is an ACPI PCI bus which we test for by seeing if we can read our ACPI_HANDLE as an ivar. - The attach routine saves a copy of our handle and calls the new acpi_pcib_attach_common() function described below. - The read_ivar routine handles normal PCI-PCI bridge ivars and adds an ivar to return the ACPI_HANDLE of the bus this bridge represents. - The route_interrupt routine fetches the _PRT (PCI Interrupt Routing Table) from the bridge device's softc and passes it off to acpi_pcib_route_interrupt() to route the interrupt. - Split the old ACPI Host-PCI bridge driver into two pieces. Part of the attach routine and most of the route_interrupt routine remain in acpi_pcib.c and are shared by both ACPI PCI bridge drivers. - The attach routine verifies the PCI bridge is present, reads in the _PRT for the bridge, and attaches the child PCI bus. - The route_interrupt routine uses the passed in _PRT to route a PCI interrupt. The rest of the driver is the ACPI Host-PCI bridge specific bits that live in acpi_pcib_acpi.c. - We no longer duplicate pcib_maxslots but use it directly. - The driver now uses the pcib devclass instead of its own devclass. This means that PCI busses are now only children of pcib devices. - Allow the ACPI_HANDLE for the child PCI bus to be read as an ivar of the child bus. - Fetch the _PRT for routing PCI interrupts directly from our softc instead of walking the devclass to find ourself and then fetch our own softc. With this change and the new ACPI PCI bus driver, ACPI can now properly route interrupts for devices behind PCI-PCI bridges. That is, the Itanium2 with like 10 PCI busses can now boot ok and route all the PCI interrupts. Hopefully this will also fix problems people are having with CardBus bridges behind PCI-PCI bridges not properly routing interrupts when ACPI is used. Tested on: i386, ia64
2002-08-26 18:30:27 +00:00
acpi_pcib_acpi_route_interrupt(device_t pcib, device_t dev, int pin)
{
Rework the ACPI PCI link code. - Use a new-bus device driver for the ACPI PCI link devices. The devices are called pci_linkX. The driver includes suspend/resume support so that the ACPI bridge drivers no longer have to poke the links to get them to handle suspend/resume. Also, the code to handle which IRQs a link is routed to and choosing an IRQ when a link is not already routed is all contained in the link driver. The PCI bridge drivers now ask the link driver which IRQ to use once they determine that a _PRT entry does not use a hardwired interrupt number. - The new link driver includes support for multiple IRQ resources per link device as well as preserving any non-IRQ resources when adjusting the IRQ that a link is routed to. - The entire approach to routing when using a link device is now link-centric rather than pci bus/device/pin specific. Thus, when using a tunable to override the default IRQ settings, one now uses a single tunable to route an entire link rather than routing a single device that uses the link (which has great foot-shooting potential if the user tries to route the same link to two different IRQs using two different pci bus/device/pin hints). For example, to adjust the IRQ that \_SB_.LNKA uses, one would set 'hw.pci.link.LNKA.irq=10' from the loader. - As a side effect of having the link driver, unused link devices will now be disabled when they are probed. - The algorithm for choosing an IRQ for a link that doesn't already have an IRQ assigned is now much closer to the one used in $PIR routing. When a link is routed via an ISA IRQ, only known-good IRQs that the BIOS has already used are used for routing instead of using probabilities to guess at which IRQs are probably not used by an ISA device. One change from $PIR is that the SCI is always considered a viable ISA IRQ, so that if the BIOS does not setup any IRQs the kernel will degenerate to routing all interrupts over the SCI. For non ISA IRQs, interrupts are picked from the possible pool using a simplistic weighting algorithm. Tested by: ru, scottl, others on acpi@ Reviewed by: njl
2004-11-23 22:26:44 +00:00
struct acpi_hpcib_softc *sc = device_get_softc(pcib);
Rework the ACPI PCI link code. - Use a new-bus device driver for the ACPI PCI link devices. The devices are called pci_linkX. The driver includes suspend/resume support so that the ACPI bridge drivers no longer have to poke the links to get them to handle suspend/resume. Also, the code to handle which IRQs a link is routed to and choosing an IRQ when a link is not already routed is all contained in the link driver. The PCI bridge drivers now ask the link driver which IRQ to use once they determine that a _PRT entry does not use a hardwired interrupt number. - The new link driver includes support for multiple IRQ resources per link device as well as preserving any non-IRQ resources when adjusting the IRQ that a link is routed to. - The entire approach to routing when using a link device is now link-centric rather than pci bus/device/pin specific. Thus, when using a tunable to override the default IRQ settings, one now uses a single tunable to route an entire link rather than routing a single device that uses the link (which has great foot-shooting potential if the user tries to route the same link to two different IRQs using two different pci bus/device/pin hints). For example, to adjust the IRQ that \_SB_.LNKA uses, one would set 'hw.pci.link.LNKA.irq=10' from the loader. - As a side effect of having the link driver, unused link devices will now be disabled when they are probed. - The algorithm for choosing an IRQ for a link that doesn't already have an IRQ assigned is now much closer to the one used in $PIR routing. When a link is routed via an ISA IRQ, only known-good IRQs that the BIOS has already used are used for routing instead of using probabilities to guess at which IRQs are probably not used by an ISA device. One change from $PIR is that the SCI is always considered a viable ISA IRQ, so that if the BIOS does not setup any IRQs the kernel will degenerate to routing all interrupts over the SCI. For non ISA IRQs, interrupts are picked from the possible pool using a simplistic weighting algorithm. Tested by: ru, scottl, others on acpi@ Reviewed by: njl
2004-11-23 22:26:44 +00:00
return (acpi_pcib_route_interrupt(pcib, dev, pin, &sc->ap_prt));
}
2004-11-09 07:02:33 +00:00
static u_long acpi_host_mem_start = 0x80000000;
TUNABLE_ULONG("hw.acpi.host_mem_start", &acpi_host_mem_start);
struct resource *
acpi_pcib_acpi_alloc_resource(device_t dev, device_t child, int type, int *rid,
2004-05-28 16:38:37 +00:00
u_long start, u_long end, u_long count, u_int flags)
{
2004-05-28 16:38:37 +00:00
/*
* If no memory preference is given, use upper 32MB slot most
2004-05-28 16:38:37 +00:00
* bioses use for their memory window. Typically other bridges
* before us get in the way to assert their preferences on memory.
* Hardcoding like this sucks, so a more MD/MI way needs to be
* found to do it. This is typically only used on older laptops
* that don't have pci busses behind pci bridge, so assuming > 32MB
* is liekly OK.
2004-05-28 16:38:37 +00:00
*/
if (type == SYS_RES_MEMORY && start == 0UL && end == ~0UL)
start = acpi_host_mem_start;
2004-05-28 16:38:37 +00:00
return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
count, flags));
}