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

175 lines
5.0 KiB
C
Raw Normal View History

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
/*-
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
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 "opt_acpi.h"
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
2004-05-30 20:08:47 +00:00
#include <sys/module.h>
Reimplement how PCI-PCI bridges manage their I/O windows. Previously the driver would verify that requests for child devices were confined to any existing I/O windows, but the driver relied on the firmware to initialize the windows and would never grow the windows for new requests. Now the driver actively manages the I/O windows. This is implemented by allocating a bus resource for each I/O window from the parent PCI bus and suballocating that resource to child devices. The suballocations are managed by creating an rman for each I/O window. The suballocated resources are mapped by passing the bus_activate_resource() call up to the parent PCI bus. Windows are grown when needed by using bus_adjust_resource() to adjust the resource allocated from the parent PCI bus. If the adjust request succeeds, the window is adjusted and the suballocation request for the child device is retried. When growing a window, the rman_first_free_region() and rman_last_free_region() routines are used to determine if the front or end of the existing I/O window is free. From using that, the smallest ranges that need to be added to either the front or back of the window are computed. The driver will first try to grow the window in whichever direction requires the smallest growth first followed by the other direction if that fails. Subtractive bridges will first attempt to satisfy requests for child resources from I/O windows (including attempts to grow the windows). If that fails, the request is passed up to the parent PCI bus directly however. The PCI-PCI bridge driver will try to use firmware-assigned ranges for child BARs first and only allocate a "fresh" range if that specific range cannot be accommodated in the I/O window. This allows systems where the firmware assigns resources during boot but later wipes the I/O windows (some ACPI BIOSen are known to do this) to "rediscover" the original I/O window ranges. The ACPI Host-PCI bridge driver has been adjusted to correctly honor hw.acpi.host_mem_start and the I/O port equivalent when a PCI-PCI bridge makes a wildcard request for an I/O window range. The new PCI-PCI bridge driver is only enabled if the NEW_PCIB kernel option is enabled. This is a transition aide to allow platforms that do not yet support bus_activate_resource() and bus_adjust_resource() in their Host-PCI bridge drivers (and possibly other drivers as needed) to use the old driver for now. Once all platforms support the new driver, the kernel option and old driver will be removed. PR: kern/143874 kern/149306 Tested by: mav
2011-05-03 17:37:24 +00:00
#include <sys/rman.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
2009-06-05 18:44:36 +00:00
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.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/acpivar.h>
#include <dev/acpica/acpi_pcibvar.h>
#include <machine/pci_cfgreg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcib_private.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 "pcib_if.h"
/* Hooks for the ACPI CA debugging infrastructure. */
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
#define _COMPONENT ACPI_BUS
ACPI_MODULE_NAME("PCI_PCI")
struct acpi_pcib_softc {
struct pcib_softc ap_pcibsc;
ACPI_HANDLE ap_handle;
ACPI_BUFFER ap_prt; /* interrupt routing table */
};
2004-12-27 05:36:47 +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_pcib_lookup_info {
UINT32 address;
ACPI_HANDLE 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
};
2004-12-27 05:36:47 +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
static int acpi_pcib_pci_probe(device_t bus);
static int acpi_pcib_pci_attach(device_t bus);
Implement a proper detach method for the PCI-PCI bridge driver. - Add a pcib_detach() function for the PCI-PCI bridge driver. It tears down the NEW_PCIB and hotplug state including destroying resource managers, deleting child devices, and disabling hotplug events. - Add a detach method to the ACPI PCI-PCI bridge driver which calls pcib_detach() and then frees the copy of the _PRT interrupt routing table. - Add a detach method to the PCI-Cardbus bridge driver which frees the PCI bus resources in addition to calling cbb_detach(). - Explicitly clear any pending hotplug events during attach to ensure future events will generate an interrupt. - If a the Command Completed bit is set in the slot status register when the command completion timeout fires, treat it as if the command completed and the completion interrupt was just lost rather than forcing a detach. - Don't wait for a Command Completed notification if Command Completion interrupts are disabled. The spec explicitly says no interrupt is enabled when clearing CCIE, and on my T400 no interrupt is generated when CCIE is changed from cleared to set, either. In addition, the T400 doesn't appear to set the Command Completed bit in the cases where it doesn't generate an interrupt, so don't schedule the timer either. (If the CC bit were always set, one could always set the timer and rely on the logic of treating CC set as a missed interrupt.) Reviewed by: imp (older version) Differential Revision: https://reviews.freebsd.org/D6424
2016-05-20 00:03:22 +00:00
static int acpi_pcib_pci_detach(device_t bus);
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
static int acpi_pcib_pci_route_interrupt(device_t pcib,
device_t dev, int pin);
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_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, acpi_pcib_pci_probe),
DEVMETHOD(device_attach, acpi_pcib_pci_attach),
Implement a proper detach method for the PCI-PCI bridge driver. - Add a pcib_detach() function for the PCI-PCI bridge driver. It tears down the NEW_PCIB and hotplug state including destroying resource managers, deleting child devices, and disabling hotplug events. - Add a detach method to the ACPI PCI-PCI bridge driver which calls pcib_detach() and then frees the copy of the _PRT interrupt routing table. - Add a detach method to the PCI-Cardbus bridge driver which frees the PCI bus resources in addition to calling cbb_detach(). - Explicitly clear any pending hotplug events during attach to ensure future events will generate an interrupt. - If a the Command Completed bit is set in the slot status register when the command completion timeout fires, treat it as if the command completed and the completion interrupt was just lost rather than forcing a detach. - Don't wait for a Command Completed notification if Command Completion interrupts are disabled. The spec explicitly says no interrupt is enabled when clearing CCIE, and on my T400 no interrupt is generated when CCIE is changed from cleared to set, either. In addition, the T400 doesn't appear to set the Command Completed bit in the cases where it doesn't generate an interrupt, so don't schedule the timer either. (If the CC bit were always set, one could always set the timer and rely on the logic of treating CC set as a missed interrupt.) Reviewed by: imp (older version) Differential Revision: https://reviews.freebsd.org/D6424
2016-05-20 00:03:22 +00:00
DEVMETHOD(device_detach, acpi_pcib_pci_detach),
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
/* Bus interface */
DEVMETHOD(bus_read_ivar, acpi_pcib_read_ivar),
Add a new bus method to fetch device-specific CPU sets. bus_get_cpus() returns a specified set of CPUs for a device. It accepts an enum for the second parameter that indicates the type of cpuset to request. Currently two valus are supported: - LOCAL_CPUS (on x86 this returns all the CPUs in the package closest to the device when DEVICE_NUMA is enabled) - INTR_CPUS (like LOCAL_CPUS but only returns 1 SMT thread for each core) For systems that do not support NUMA (or if it is not enabled in the kernel config), LOCAL_CPUS fails with EINVAL. INTR_CPUS is mapped to 'all_cpus' by default. The idea is that INTR_CPUS should always return a valid set. Device drivers which want to use per-CPU interrupts should start using INTR_CPUS instead of simply assigning interrupts to all available CPUs. In the future we may wish to add tunables to control the policy of INTR_CPUS (e.g. should it be local-only or global, should it ignore SMT threads or not). The x86 nexus driver exposes the internal set of interrupt CPUs from the the x86 interrupt code via INTR_CPUS. The ACPI bus driver and PCI bridge drivers use _PXM to return a suitable LOCAL_CPUS set when _PXM exists and DEVICE_NUMA is enabled. They also and the global INTR_CPUS set from the nexus driver with the per-domain set from _PXM to generate a local INTR_CPUS set for child devices. Compared to the r298933, this version uses 'struct _cpuset' in <sys/bus.h> instead of 'cpuset_t' to avoid requiring <sys/param.h> (<sys/_cpuset.h> still requires <sys/param.h> for MAXCPU even though <sys/_bitset.h> does not after recent changes).
2016-05-09 20:50:21 +00:00
DEVMETHOD(bus_get_cpus, acpi_pcib_get_cpus),
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
/* pcib interface */
DEVMETHOD(pcib_route_interrupt, acpi_pcib_pci_route_interrupt),
DEVMETHOD(pcib_power_for_sleep, acpi_pcib_power_for_sleep),
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_END
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 devclass_t pcib_devclass;
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
DEFINE_CLASS_1(pcib, acpi_pcib_pci_driver, acpi_pcib_pci_methods,
sizeof(struct acpi_pcib_softc), pcib_driver);
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, pci, acpi_pcib_pci_driver, pcib_devclass, 0, 0);
MODULE_DEPEND(acpi_pcib, acpi, 1, 1, 1);
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_pci_probe(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_PCI ||
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_disabled("pci"))
return (ENXIO);
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
if (pci_cfgregopen() == 0)
return (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
device_set_desc(dev, "ACPI PCI-PCI bridge");
return (-1000);
}
static int
acpi_pcib_pci_attach(device_t dev)
{
struct acpi_pcib_softc *sc;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
pcib_attach_common(dev);
sc = device_get_softc(dev);
sc->ap_handle = acpi_get_handle(dev);
acpi_pcib_fetch_prt(dev, &sc->ap_prt);
return (pcib_attach_child(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
}
Implement a proper detach method for the PCI-PCI bridge driver. - Add a pcib_detach() function for the PCI-PCI bridge driver. It tears down the NEW_PCIB and hotplug state including destroying resource managers, deleting child devices, and disabling hotplug events. - Add a detach method to the ACPI PCI-PCI bridge driver which calls pcib_detach() and then frees the copy of the _PRT interrupt routing table. - Add a detach method to the PCI-Cardbus bridge driver which frees the PCI bus resources in addition to calling cbb_detach(). - Explicitly clear any pending hotplug events during attach to ensure future events will generate an interrupt. - If a the Command Completed bit is set in the slot status register when the command completion timeout fires, treat it as if the command completed and the completion interrupt was just lost rather than forcing a detach. - Don't wait for a Command Completed notification if Command Completion interrupts are disabled. The spec explicitly says no interrupt is enabled when clearing CCIE, and on my T400 no interrupt is generated when CCIE is changed from cleared to set, either. In addition, the T400 doesn't appear to set the Command Completed bit in the cases where it doesn't generate an interrupt, so don't schedule the timer either. (If the CC bit were always set, one could always set the timer and rely on the logic of treating CC set as a missed interrupt.) Reviewed by: imp (older version) Differential Revision: https://reviews.freebsd.org/D6424
2016-05-20 00:03:22 +00:00
static int
acpi_pcib_pci_detach(device_t dev)
{
struct acpi_pcib_softc *sc;
int error;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
sc = device_get_softc(dev);
error = pcib_detach(dev);
if (error == 0)
AcpiOsFree(sc->ap_prt.Pointer);
return (error);
}
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_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct acpi_pcib_softc *sc = device_get_softc(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
switch (which) {
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;
return (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 (pcib_read_ivar(dev, child, which, 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
}
static int
acpi_pcib_pci_route_interrupt(device_t pcib, device_t dev, int pin)
{
struct acpi_pcib_softc *sc;
sc = device_get_softc(pcib);
/*
* If we don't have a _PRT, fall back to the swizzle method
* for routing interrupts.
*/
if (sc->ap_prt.Pointer == NULL)
return (pcib_route_interrupt(pcib, dev, pin));
else
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));
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
}