Skip to content

Commit

Permalink
acpi/pcib: If bus does not present, give other bus drivers chance
Browse files Browse the repository at this point in the history
- Call acpi_DeviceIsPresent() during probing, so that if bus does not
  present other bus drivers could have chance to take over the bus.
- In acpi_pcib_attach(), assert that bus is present, since the presence
  of the bus is checked during probing.

Reported-by: swildner@
  • Loading branch information
Sepherosa Ziehau committed Apr 17, 2011
1 parent ad65f96 commit 2c61a93
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 16 deletions.
31 changes: 23 additions & 8 deletions sys/dev/acpica5/acpi_pcib.c
Expand Up @@ -40,6 +40,7 @@

#include <bus/pci/pcivar.h>
#include <bus/pci/pcireg.h>
#include <bus/pci/pci_cfgreg.h>
#include "pcib_if.h"

/* Hooks for the ACPI CA debugging infrastructure. */
Expand Down Expand Up @@ -133,14 +134,10 @@ acpi_pcib_attach(device_t dev, ACPI_BUFFER *prt, int busno)

ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

/*
* Don't attach if we're not really there.
*
* XXX: This isn't entirely correct since we may be a PCI bus
* on a hot-plug docking station, etc.
*/
if (!acpi_DeviceIsPresent(dev))
return_VALUE(ENXIO);
if (!acpi_DeviceIsPresent(dev)) {
/* Caller should already have checked it */
panic("%s device is not present\n", __func__);
}

ACPI_SERIAL_INIT(pcib);

Expand Down Expand Up @@ -287,3 +284,21 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,

return_VALUE (interrupt);
}

int
acpi_pcib_probe(device_t dev)
{
/*
* Don't attach if we're not really there.
*
* XXX: This isn't entirely correct since we may be a PCI bus
* on a hot-plug docking station, etc.
*/
if (!acpi_DeviceIsPresent(dev))
return ENXIO;

if (pci_cfgregopen() == 0)
return ENXIO;

return 0;
}
10 changes: 7 additions & 3 deletions sys/dev/acpica5/acpi_pcib_acpi.c
Expand Up @@ -38,7 +38,7 @@
#include "acpi.h"
#include <dev/acpica5/acpivar.h>

#include <bus/pci/i386/pci_cfgreg.h>
#include <bus/pci/pci_cfgreg.h>
#include <bus/pci/pcivar.h>
#include <bus/pci/pcib_private.h>
#include "pcib_if.h"
Expand Down Expand Up @@ -130,14 +130,18 @@ MODULE_DEPEND(acpi_pcib, acpi, 1, 1, 1);
static int
acpi_pcib_acpi_probe(device_t dev)
{
int error;

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);
error = acpi_pcib_probe(dev);
if (error)
return (error);

device_set_desc(dev, "ACPI Host-PCI bridge");
return (0);
}
Expand Down
11 changes: 6 additions & 5 deletions sys/dev/acpica5/acpi_pcib_pci.c
Expand Up @@ -39,7 +39,6 @@
#include <dev/acpica5/acpivar.h>
#include <dev/acpica5/acpi_pcibvar.h>

#include <bus/pci/i386/pci_cfgreg.h>
#include <bus/pci/pcivar.h>
#include <bus/pci/pcireg.h>
#include <bus/pci/pcib_private.h>
Expand Down Expand Up @@ -111,14 +110,16 @@ MODULE_DEPEND(acpi_pcib, acpi, 1, 1, 1);
static int
acpi_pcib_pci_probe(device_t dev)
{
int error;

if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_PCI ||
acpi_disabled("pci"))
return (ENXIO);
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
if (pci_cfgregopen() == 0)
return (ENXIO);

error = acpi_pcib_probe(dev);
if (error)
return (error);

device_set_desc(dev, "ACPI PCI-PCI bridge");
return (-100);
Expand Down
1 change: 1 addition & 0 deletions sys/dev/acpica5/acpi_pcibvar.h
Expand Up @@ -34,6 +34,7 @@
void acpi_pci_link_add_reference(device_t dev, int index, device_t pcib,
int slot, int pin);
int acpi_pci_link_route_interrupt(device_t dev, int index);
int acpi_pcib_probe(device_t bus);
int acpi_pcib_attach(device_t bus, ACPI_BUFFER *prt, int busno);
int acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
ACPI_BUFFER *prtbuf);
Expand Down

0 comments on commit 2c61a93

Please sign in to comment.