PERFORCE change 65745 for review
John Baldwin
jhb at FreeBSD.org
Tue Nov 23 23:10:50 GMT 2004
http://perforce.freebsd.org/chv.cgi?CH=65745
Change 65745 by jhb at jhb_slimer on 2004/11/23 23:10:26
IFC @65733.
Affected files ...
.. //depot/projects/smpng/sys/alpha/alpha/interrupt.c#31 integrate
.. //depot/projects/smpng/sys/arm/arm/intr.c#5 integrate
.. //depot/projects/smpng/sys/arm/xscale/i80321/uart_bus_i80321.c#2 integrate
.. //depot/projects/smpng/sys/arm/xscale/i80321/uart_cpu_i80321.c#2 integrate
.. //depot/projects/smpng/sys/boot/Makefile#17 integrate
.. //depot/projects/smpng/sys/boot/efi/Makefile#2 integrate
.. //depot/projects/smpng/sys/boot/efi/libefi/arch/ia64/ldscript.ia64#7 delete
.. //depot/projects/smpng/sys/boot/efi/libefi/arch/ia64/start.S#7 delete
.. //depot/projects/smpng/sys/boot/efi/loader/Makefile#12 delete
.. //depot/projects/smpng/sys/boot/efi/loader/conf.c#9 delete
.. //depot/projects/smpng/sys/boot/efi/loader/main.c#15 delete
.. //depot/projects/smpng/sys/boot/efi/loader/version#5 delete
.. //depot/projects/smpng/sys/boot/ia64/Makefile#4 integrate
.. //depot/projects/smpng/sys/boot/ia64/efi/Makefile#1 branch
.. //depot/projects/smpng/sys/boot/ia64/efi/conf.c#1 branch
.. //depot/projects/smpng/sys/boot/ia64/efi/ldscript.ia64#1 branch
.. //depot/projects/smpng/sys/boot/ia64/efi/main.c#1 branch
.. //depot/projects/smpng/sys/boot/ia64/efi/start.S#1 branch
.. //depot/projects/smpng/sys/boot/ia64/efi/version#1 branch
.. //depot/projects/smpng/sys/conf/files.alpha#32 integrate
.. //depot/projects/smpng/sys/conf/files.amd64#24 integrate
.. //depot/projects/smpng/sys/conf/files.arm#3 integrate
.. //depot/projects/smpng/sys/conf/files.i386#71 integrate
.. //depot/projects/smpng/sys/conf/files.ia64#46 integrate
.. //depot/projects/smpng/sys/conf/files.pc98#65 integrate
.. //depot/projects/smpng/sys/dev/acpica/acpi_pci_link.c#23 integrate
.. //depot/projects/smpng/sys/dev/acpica/acpi_pcib.c#27 integrate
.. //depot/projects/smpng/sys/dev/acpica/acpi_pcib_acpi.c#17 integrate
.. //depot/projects/smpng/sys/dev/acpica/acpi_pcib_pci.c#8 integrate
.. //depot/projects/smpng/sys/dev/acpica/acpi_pcibvar.h#4 integrate
.. //depot/projects/smpng/sys/geom/gate/g_gate.c#8 integrate
.. //depot/projects/smpng/sys/kern/sys_pipe.c#49 integrate
.. //depot/projects/smpng/sys/netgraph/ng_cisco.c#10 integrate
.. //depot/projects/smpng/sys/netgraph/ng_iface.c#16 integrate
.. //depot/projects/smpng/sys/netgraph/ng_one2many.c#11 integrate
.. //depot/projects/smpng/sys/netgraph/ng_one2many.h#4 integrate
.. //depot/projects/smpng/sys/netinet/tcp_input.c#63 integrate
.. //depot/projects/smpng/sys/netinet/tcp_subr.c#59 integrate
.. //depot/projects/smpng/sys/netinet/tcp_timer.c#20 integrate
Differences ...
==== //depot/projects/smpng/sys/alpha/alpha/interrupt.c#31 (text+ko) ====
@@ -33,7 +33,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
/* __KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.23 1998/02/24 07:38:01 thorpej Exp $");*/
-__FBSDID("$FreeBSD: src/sys/alpha/alpha/interrupt.c,v 1.82 2004/07/20 06:32:32 alc Exp $");
+__FBSDID("$FreeBSD: src/sys/alpha/alpha/interrupt.c,v 1.83 2004/11/23 22:11:53 jhb Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -474,7 +474,7 @@
/*
* Only one processor drives the actual timer.
*/
- if (PCPU_GET(cpuid) == boot_cpu_id) {
+ if (PCPU_GET(cpuid) == 0) {
#endif
(*platform.clockintr)(framep);
/* divide hz (1024) by 8 to get stathz (128) */
==== //depot/projects/smpng/sys/arm/arm/intr.c#5 (text+ko) ====
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/arm/arm/intr.c,v 1.4 2004/11/12 21:49:05 cognet Exp $");
+__FBSDID("$FreeBSD: src/sys/arm/arm/intr.c,v 1.5 2004/11/23 16:31:16 cognet Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syslog.h>
@@ -139,17 +139,16 @@
continue;
ih = TAILQ_FIRST(&ithd->it_handlers);
if (ih && ih->ih_flags & IH_FAST) {
+ oldirqstate = disable_interrupts(I32_bit);
TAILQ_FOREACH(ih, &ithd->it_handlers,
ih_next) {
ih->ih_handler(ih->ih_argument ?
ih->ih_argument : frame);
}
+ restore_interrupts(oldirqstate);
arm_unmask_irqs(1 << i);
- } else if (ih) {
- oldirqstate = enable_interrupts(I32_bit);
+ } else if (ih)
ithread_schedule(ithd);
- restore_interrupts(oldirqstate);
- }
irqnb |= arm_get_irqnb(frame);
}
td->td_intr_nesting_level--;
==== //depot/projects/smpng/sys/arm/xscale/i80321/uart_bus_i80321.c#2 (text+ko) ====
@@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/arm/xscale/i80321/uart_bus_i80321.c,v 1.1 2004/09/23 22:45:36 cognet Exp $");
+__FBSDID("$FreeBSD: src/sys/arm/xscale/i80321/uart_bus_i80321.c,v 1.2 2004/11/23 16:30:50 cognet Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -59,7 +59,6 @@
sizeof(struct uart_softc),
};
-extern struct uart_class uart_i8251_class;
extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
static int
uart_i80321_probe(device_t dev)
@@ -68,7 +67,7 @@
sc = device_get_softc(dev);
sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
- sc->sc_class = &uart_i8251_class;
+ sc->sc_class = &uart_ns8250_class;
bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
return(uart_bus_probe(dev, 0, 0, 0, 0));
}
==== //depot/projects/smpng/sys/arm/xscale/i80321/uart_cpu_i80321.c#2 (text+ko) ====
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/arm/xscale/i80321/uart_cpu_i80321.c,v 1.1 2004/09/23 22:45:36 cognet Exp $");
+__FBSDID("$FreeBSD: src/sys/arm/xscale/i80321/uart_cpu_i80321.c,v 1.2 2004/11/23 16:30:50 cognet Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -55,7 +55,7 @@
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
- di->ops = uart_i8251_ops;
+ di->ops = uart_ns8250_ops;
di->bas.chan = 0;
di->bas.bst = &obio_bs_tag;
di->bas.regshft = 0;
==== //depot/projects/smpng/sys/boot/Makefile#17 (text+ko) ====
@@ -1,10 +1,15 @@
-# $FreeBSD: src/sys/boot/Makefile,v 1.24 2004/08/16 15:45:24 marius Exp $
+# $FreeBSD: src/sys/boot/Makefile,v 1.25 2004/11/23 05:52:00 marcel Exp $
.if !defined(NOFORTH)
# Build the add-in FORTH interpreter.
SUBDIR+= ficl
.endif
+# Build EFI library.
+.if ${MACHINE_ARCH} == "ia64"
+SUBDIR+= efi
+.endif
+
# Build Open Firmware library.
.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "sparc64"
SUBDIR+= ofw
@@ -19,9 +24,4 @@
#SUBDIR+= arc
#.endif
-# Build EFI executable on ia64.
-.if ${MACHINE_ARCH} == "ia64"
-SUBDIR+= efi
-.endif
-
.include <bsd.subdir.mk>
==== //depot/projects/smpng/sys/boot/efi/Makefile#2 (text+ko) ====
@@ -1,5 +1,5 @@
-# $FreeBSD: src/sys/boot/efi/Makefile,v 1.1 2001/06/09 16:49:48 dfr Exp $
+# $FreeBSD: src/sys/boot/efi/Makefile,v 1.2 2004/11/23 06:04:51 marcel Exp $
-SUBDIR= libefi loader
+SUBDIR= libefi
.include <bsd.subdir.mk>
==== //depot/projects/smpng/sys/boot/ia64/Makefile#4 (text+ko) ====
@@ -1,5 +1,5 @@
-# $FreeBSD: src/sys/boot/ia64/Makefile,v 1.3 2004/09/24 04:21:14 marcel Exp $
+# $FreeBSD: src/sys/boot/ia64/Makefile,v 1.4 2004/11/23 06:03:03 marcel Exp $
-SUBDIR= ski
+SUBDIR= efi ski
.include <bsd.subdir.mk>
==== //depot/projects/smpng/sys/conf/files.alpha#32 (text+ko) ====
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $FreeBSD: src/sys/conf/files.alpha,v 1.114 2004/08/01 11:40:51 markm Exp $
+# $FreeBSD: src/sys/conf/files.alpha,v 1.115 2004/11/23 00:00:43 imp Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -179,7 +179,6 @@
dev/kbd/atkbd.c optional atkbd
dev/kbd/atkbdc.c optional atkbdc
dev/kbd/kbd.c optional atkbd
-dev/kbd/kbd.c optional kbd
dev/kbd/kbd.c optional sc
dev/kbd/kbd.c optional ukbd
dev/ppc/ppc.c optional ppc
==== //depot/projects/smpng/sys/conf/files.amd64#24 (text+ko) ====
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $FreeBSD: src/sys/conf/files.amd64,v 1.50 2004/09/28 07:29:54 markm Exp $
+# $FreeBSD: src/sys/conf/files.amd64,v 1.51 2004/11/23 00:00:43 imp Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -123,7 +123,6 @@
dev/kbd/atkbd.c optional atkbd
dev/kbd/atkbdc.c optional atkbdc
dev/kbd/kbd.c optional atkbd
-dev/kbd/kbd.c optional kbd
dev/kbd/kbd.c optional sc
dev/kbd/kbd.c optional ukbd
dev/mem/memutil.c optional mem
==== //depot/projects/smpng/sys/conf/files.arm#3 (text+ko) ====
@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/files.arm,v 1.3 2004/05/14 23:42:54 cognet Exp $
+# $FreeBSD: src/sys/conf/files.arm,v 1.4 2004/11/22 22:20:50 cognet Exp $
arm/arm/autoconf.c standard
arm/arm/bcopy_page.S standard
arm/arm/bcopyinout.S standard
@@ -29,6 +29,7 @@
arm/arm/intr.c standard
arm/arm/locore.S standard no-obj
arm/arm/machdep.c standard
+arm/arm/mem.c optional mem
arm/arm/nexus.c optional nexus
arm/arm/nexus_io.c optional nexus
arm/arm/nexus_io_asm.S optional nexus
==== //depot/projects/smpng/sys/conf/files.i386#71 (text+ko) ====
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $FreeBSD: src/sys/conf/files.i386,v 1.508 2004/11/15 05:54:14 imp Exp $
+# $FreeBSD: src/sys/conf/files.i386,v 1.509 2004/11/23 00:00:43 imp Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -157,7 +157,6 @@
dev/kbd/atkbd.c optional atkbd
dev/kbd/atkbdc.c optional atkbdc
dev/kbd/kbd.c optional atkbd
-dev/kbd/kbd.c optional kbd
dev/kbd/kbd.c optional sc
dev/kbd/kbd.c optional ukbd
dev/kbd/kbd.c optional vt
==== //depot/projects/smpng/sys/conf/files.ia64#46 (text+ko) ====
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $FreeBSD: src/sys/conf/files.ia64,v 1.73 2004/09/25 04:27:44 marcel Exp $
+# $FreeBSD: src/sys/conf/files.ia64,v 1.74 2004/11/23 00:00:43 imp Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -55,7 +55,6 @@
dev/kbd/atkbd.c optional atkbd
dev/kbd/atkbdc.c optional atkbdc
dev/kbd/kbd.c optional atkbd
-dev/kbd/kbd.c optional kbd
dev/kbd/kbd.c optional sc
dev/kbd/kbd.c optional ukbd
dev/ppc/ppc.c optional ppc isa
==== //depot/projects/smpng/sys/conf/files.pc98#65 (text+ko) ====
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $FreeBSD: src/sys/conf/files.pc98,v 1.306 2004/08/30 23:03:56 peter Exp $
+# $FreeBSD: src/sys/conf/files.pc98,v 1.307 2004/11/23 00:00:43 imp Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -105,7 +105,6 @@
dev/fb/fb.c optional gdc
dev/fb/splash.c optional splash
dev/fe/if_fe_cbus.c optional fe isa
-dev/kbd/kbd.c optional kbd
dev/kbd/kbd.c optional sc
dev/kbd/kbd.c optional ukbd
dev/kbd/kbd.c optional pckbd
==== //depot/projects/smpng/sys/dev/acpica/acpi_pci_link.c#23 (text+ko) ====
@@ -25,17 +25,22 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_pci_link.c,v 1.33 2004/09/25 06:15:56 njl Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_pci_link.c,v 1.34 2004/11/23 22:26:44 jhb Exp $");
#include "opt_acpi.h"
#include <sys/param.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
-#include <sys/bus.h>
+#include <sys/limits.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
#include "acpi.h"
#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpi_pcibvar.h>
+#include <machine/pci_cfgreg.h>
+#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include "pcib_if.h"
@@ -43,1119 +48,714 @@
#define _COMPONENT ACPI_BUS
ACPI_MODULE_NAME("PCI_LINK")
-TAILQ_HEAD(acpi_pci_link_entries, acpi_pci_link_entry);
-static struct acpi_pci_link_entries acpi_pci_link_entries;
ACPI_SERIAL_DECL(pci_link, "ACPI PCI link");
-TAILQ_HEAD(acpi_prt_entries, acpi_prt_entry);
-static struct acpi_prt_entries acpi_prt_entries;
+#define NUM_ISA_INTERRUPTS 16
+#define NUM_ACPI_INTERRUPTS 256
+
+/*
+ * An ACPI PCI link device may contain multiple links. Each link has its
+ * own ACPI resource. _PRT entries specify which link is being used via
+ * the Source Index.
+ */
+
+struct link;
+
+struct acpi_pci_link_softc {
+ int pl_num_links;
+ struct link *pl_links;
+};
+
+struct link {
+ struct acpi_pci_link_softc *l_sc;
+ uint8_t l_bios_irq;
+ uint8_t l_irq;
+ uint8_t l_initial_irq;
+ int l_res_index;
+ int l_num_irqs;
+ int *l_irqs;
+ int l_references;
+ int l_routed:1;
+ int l_isa_irq:1;
+ ACPI_RESOURCE l_prs_template;
+};
+
+struct link_res_request {
+ struct acpi_pci_link_softc *sc;
+ int count;
+};
+
+MALLOC_DEFINE(M_PCI_LINK, "PCI Link", "ACPI PCI Link structures");
-static int irq_penalty[MAX_ACPI_INTERRUPTS];
+static int pci_link_interrupt_weights[NUM_ACPI_INTERRUPTS];
+static int pci_link_bios_isa_irqs;
-static int acpi_pci_link_is_valid_irq(struct acpi_pci_link_entry *link,
- UINT8 irq);
-static void acpi_pci_link_update_irq_penalty(device_t dev, int busno);
-static void acpi_pci_link_set_bootdisabled_priority(void);
-static void acpi_pci_link_fixup_bootdisabled_link(void);
+static char *pci_link_ids[] = { "PNP0C0F", NULL };
/*
- * PCI link object management
+ * Fetch the short name associated with an ACPI handle and save it in the
+ * passed in buffer.
*/
-
-static void
-acpi_pci_link_dump_polarity(UINT32 ActiveHighLow)
+static ACPI_STATUS
+acpi_short_name(ACPI_HANDLE handle, char *buffer, size_t buflen)
{
+ ACPI_BUFFER buf;
- switch (ActiveHighLow) {
- case ACPI_ACTIVE_HIGH:
- printf("high,");
- break;
- case ACPI_ACTIVE_LOW:
- printf("low,");
- break;
- default:
- printf("unknown,");
- break;
- }
+ buf.Length = buflen;
+ buf.Pointer = buffer;
+ return (AcpiGetName(handle, ACPI_SINGLE_NAME, &buf));
}
-static void
-acpi_pci_link_dump_trigger(UINT32 EdgeLevel)
+static int
+acpi_pci_link_probe(device_t dev)
{
+ char descr[64], name[10];
- switch (EdgeLevel) {
- case ACPI_EDGE_SENSITIVE:
- printf("edge,");
- break;
- case ACPI_LEVEL_SENSITIVE:
- printf("level,");
- break;
- default:
- printf("unknown,");
- break;
+ /*
+ * We explicitly do not check _STA since not all systems set it to
+ * sensible values.
+ */
+ if (!acpi_disabled("pci_link") &&
+ ACPI_ID_PROBE(device_get_parent(dev), dev, pci_link_ids) != NULL) {
+ if (ACPI_FAILURE(acpi_short_name(acpi_get_handle(dev), name,
+ sizeof(name))))
+ device_set_desc(dev, "ACPI PCI Link");
+ else {
+ snprintf(descr, sizeof(descr), "ACPI PCI Link %s",
+ name);
+ device_set_desc_copy(dev, descr);
+ }
+ return (0);
}
+ return (ENXIO);
}
-static void
-acpi_pci_link_dump_sharemode(UINT32 SharedExclusive)
+static ACPI_STATUS
+acpi_count_resources(ACPI_RESOURCE *res, void *context)
{
+ int *count;
- switch (SharedExclusive) {
- case ACPI_EXCLUSIVE:
- printf("exclusive");
- break;
- case ACPI_SHARED:
- printf("sharable");
- break;
- default:
- printf("unknown");
- break;
- }
+ count = (int *)context;
+ (*count)++;
+ return (AE_OK);
}
-static void
-acpi_pci_link_entry_dump(struct acpi_prt_entry *entry)
+static ACPI_STATUS
+link_add_crs(ACPI_RESOURCE *res, void *context)
{
- UINT8 i;
- ACPI_RESOURCE_IRQ *Irq;
- ACPI_RESOURCE_EXT_IRQ *ExtIrq;
- struct acpi_pci_link_entry *link;
+ struct link_res_request *req;
+ struct link *link;
- if (entry == NULL || entry->pci_link == NULL)
- return;
- link = entry->pci_link;
-
- printf("%s irq%c%2d: ", acpi_name(link->handle),
- (link->flags & ACPI_LINK_ROUTED) ? '*' : ' ', link->current_irq);
-
- printf("[");
- if (link->number_of_interrupts)
- printf("%2d", link->interrupts[0]);
- for (i = 1; i < link->number_of_interrupts; i++)
- printf("%3d", link->interrupts[i]);
- printf("] %2d+ ", link->initial_irq);
-
- switch (link->possible_resources.Id) {
+ ACPI_SERIAL_ASSERT(pci_link);
+ req = (struct link_res_request *)context;
+ link = &req->sc->pl_links[req->count];
+ req->count++;
+ switch (res->Id) {
case ACPI_RSTYPE_IRQ:
- Irq = &link->possible_resources.Data.Irq;
- acpi_pci_link_dump_polarity(Irq->ActiveHighLow);
- acpi_pci_link_dump_trigger(Irq->EdgeLevel);
- acpi_pci_link_dump_sharemode(Irq->SharedExclusive);
- break;
case ACPI_RSTYPE_EXT_IRQ:
- ExtIrq = &link->possible_resources.Data.ExtendedIrq;
- acpi_pci_link_dump_polarity(ExtIrq->ActiveHighLow);
- acpi_pci_link_dump_trigger(ExtIrq->EdgeLevel);
- acpi_pci_link_dump_sharemode(ExtIrq->SharedExclusive);
+ if (res->Id == ACPI_RSTYPE_IRQ) {
+ if (res->Data.Irq.NumberOfInterrupts > 0) {
+ KASSERT(res->Data.Irq.NumberOfInterrupts == 1,
+ ("%s: too many interrupts", __func__));
+ link->l_irq = res->Data.Irq.Interrupts[0];
+ }
+ } else if (res->Data.ExtendedIrq.NumberOfInterrupts > 0) {
+ KASSERT(res->Data.ExtendedIrq.NumberOfInterrupts == 1,
+ ("%s: too many interrupts", __func__));
+ link->l_irq = res->Data.ExtendedIrq.Interrupts[0];
+ }
+
+ /*
+ * An IRQ of zero means that the link isn't routed.
+ */
+ if (link->l_irq == 0)
+ link->l_irq = PCI_INVALID_IRQ;
break;
}
-
- printf(" %d.%d.%d\n", entry->busno,
- (int)(ACPI_ADR_PCI_SLOT(entry->prt.Address)),
- (int)entry->prt.Pin);
+ return (AE_OK);
}
+/*
+ * Populate the set of possible IRQs for each device.
+ */
static ACPI_STATUS
-acpi_pci_link_get_object_status(ACPI_HANDLE handle, UINT32 *sta)
+link_add_prs(ACPI_RESOURCE *res, void *context)
{
- ACPI_DEVICE_INFO *devinfo;
- ACPI_BUFFER buf;
- ACPI_STATUS error;
+ struct link_res_request *req;
+ struct link *link;
+ UINT32 *irqs;
+ int i;
- ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
-
- if (handle == NULL || sta == NULL) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "invalid argument\n"));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- buf.Pointer = NULL;
- buf.Length = ACPI_ALLOCATE_BUFFER;
- error = AcpiGetObjectInfo(handle, &buf);
- if (ACPI_FAILURE(error)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "couldn't get object info %s - %s\n",
- acpi_name(handle), AcpiFormatException(error)));
- return_ACPI_STATUS (error);
- }
-
- devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
- if ((devinfo->Valid & ACPI_VALID_HID) == 0 ||
- strcmp(devinfo->HardwareId.Value, "PNP0C0F") != 0) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "invalid hardware ID - %s\n",
- acpi_name(handle)));
- AcpiOsFree(buf.Pointer);
- return_ACPI_STATUS (AE_TYPE);
- }
-
- if ((devinfo->Valid & ACPI_VALID_STA) != 0) {
- *sta = devinfo->CurrentStatus;
- } else {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "invalid status - %s\n",
- acpi_name(handle)));
- *sta = 0;
- }
-
- AcpiOsFree(buf.Pointer);
- return_ACPI_STATUS (AE_OK);
-}
-
-static ACPI_STATUS
-acpi_pci_link_get_irq_resources(ACPI_RESOURCE *resources,
- UINT8 *number_of_interrupts, UINT8 interrupts[])
-{
- UINT8 count;
- UINT8 i;
- UINT32 NumberOfInterrupts;
- UINT32 *Interrupts;
-
- ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
-
- if (resources == NULL || number_of_interrupts == NULL) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "invalid argument\n"));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- *number_of_interrupts = 0;
- NumberOfInterrupts = 0;
- Interrupts = NULL;
-
- if (resources->Id == ACPI_RSTYPE_START_DPF)
- resources = ACPI_NEXT_RESOURCE(resources);
-
- if (resources->Id != ACPI_RSTYPE_IRQ &&
- resources->Id != ACPI_RSTYPE_EXT_IRQ) {
- printf("acpi link get: resource %d is not an IRQ\n",
- resources->Id);
- return_ACPI_STATUS (AE_TYPE);
- }
-
- switch (resources->Id) {
+ ACPI_SERIAL_ASSERT(pci_link);
+ req = (struct link_res_request *)context;
+ link = &req->sc->pl_links[req->count];
+ req->count++;
+ switch (res->Id) {
case ACPI_RSTYPE_IRQ:
- NumberOfInterrupts = resources->Data.Irq.NumberOfInterrupts;
- Interrupts = resources->Data.Irq.Interrupts;
- break;
case ACPI_RSTYPE_EXT_IRQ:
- NumberOfInterrupts =
- resources->Data.ExtendedIrq.NumberOfInterrupts;
- Interrupts = resources->Data.ExtendedIrq.Interrupts;
- break;
- }
- if (NumberOfInterrupts == 0)
- return_ACPI_STATUS (AE_NULL_ENTRY);
+ /*
+ * Stash a copy of the resource for later use when doing
+ * _SRS.
+ */
+ bcopy(res, &link->l_prs_template, sizeof(ACPI_RESOURCE));
+ if (res->Id == ACPI_RSTYPE_IRQ) {
+ link->l_num_irqs = res->Data.Irq.NumberOfInterrupts;
+ irqs = res->Data.Irq.Interrupts;
+ } else {
+ link->l_num_irqs =
+ res->Data.ExtendedIrq.NumberOfInterrupts;
+ irqs = res->Data.ExtendedIrq.Interrupts;
+ }
+ if (link->l_num_irqs == 0)
+ break;
- count = 0;
- for (i = 0; i < NumberOfInterrupts; i++) {
- if (i >= MAX_POSSIBLE_INTERRUPTS) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "too many IRQs (%d)\n",
- i));
- break;
+ /*
+ * Save a list of the valid IRQs. Also, if all of the
+ * valid IRQs are ISA IRQs, then mark this link as
+ * routed via an ISA interrupt.
+ */
+ link->l_isa_irq = 1;
+ link->l_irqs = malloc(sizeof(int) * link->l_num_irqs,
+ M_PCI_LINK, M_WAITOK | M_ZERO);
+ for (i = 0; i < link->l_num_irqs; i++) {
+ link->l_irqs[i] = irqs[i];
+ if (irqs[1] >= NUM_ISA_INTERRUPTS)
+ link->l_isa_irq = 0;
}
- if (Interrupts[i] == 0) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN, "invalid IRQ %d\n",
- Interrupts[i]));
- continue;
- }
- interrupts[count] = Interrupts[i];
- count++;
+ break;
}
- *number_of_interrupts = count;
-
- return_ACPI_STATUS (AE_OK);
+ return (AE_OK);
}
-static ACPI_STATUS
-acpi_pci_link_get_current_irq(struct acpi_pci_link_entry *link, UINT8 *irq)
+static int
+link_valid_irq(struct link *link, int irq)
{
- ACPI_STATUS error;
- ACPI_BUFFER buf;
- ACPI_RESOURCE *resources;
- UINT8 number_of_interrupts;
- UINT8 interrupts[MAX_POSSIBLE_INTERRUPTS];;
+ int i;
- ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+ ACPI_SERIAL_ASSERT(pci_link);
- if (link == NULL || irq == NULL) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "invalid argument\n"));
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
+ /* Invalid interrupts are never valid. */
+ if (!PCI_INTERRUPT_VALID(irq))
+ return (0);
- *irq = 0;
- buf.Pointer = NULL;
- buf.Length = ACPI_ALLOCATE_BUFFER;
- error = AcpiGetCurrentResources(link->handle, &buf);
- if (ACPI_FAILURE(error)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "couldn't get PCI interrupt link device _CRS %s - %s\n",
- acpi_name(link->handle), AcpiFormatException(error)));
- return_ACPI_STATUS (error);
- }
- if (buf.Pointer == NULL) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "couldn't allocate memory - %s\n",
- acpi_name(link->handle)));
- return_ACPI_STATUS (AE_NO_MEMORY);
- }
+ /* Any interrupt in the list of possible interrupts is valid. */
+ for (i = 0; i < link->l_num_irqs; i++)
+ if (link->l_irqs[i] == irq)
+ return (1);
- resources = (ACPI_RESOURCE *) buf.Pointer;
- number_of_interrupts = 0;
- bzero(interrupts, sizeof(interrupts));
- error = acpi_pci_link_get_irq_resources(resources,
- &number_of_interrupts, interrupts);
- AcpiOsFree(buf.Pointer);
+ /*
+ * For links routed via an ISA interrupt, if the SCI is routed via
+ * an ISA interrupt, the SCI is always treated as a valid IRQ.
+ */
+ if (link->l_isa_irq && AcpiGbl_FADT->SciInt == irq &&
+ irq < NUM_ISA_INTERRUPTS)
+ return (1);
- if (ACPI_FAILURE(error)) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "couldn't get current IRQ from interrupt link %s - %s\n",
- acpi_name(link->handle), AcpiFormatException(error)));
- return_ACPI_STATUS (error);
- }
-
- if (number_of_interrupts == 0) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "PCI interrupt link device _CRS data is corrupted - %s\n",
- acpi_name(link->handle)));
- return_ACPI_STATUS (AE_NULL_ENTRY);
- }
-
- *irq = interrupts[0];
-
- return_ACPI_STATUS (AE_OK);
+ /* If the interrupt wasn't found in the list it is not valid. */
+ return (0);
}
-static ACPI_STATUS
-acpi_pci_link_add_link(ACPI_HANDLE handle, struct acpi_prt_entry *entry)
+static void
+acpi_pci_link_dump(struct acpi_pci_link_softc *sc)
{
- ACPI_STATUS error;
- ACPI_BUFFER buf;
- ACPI_RESOURCE *resources;
- struct acpi_pci_link_entry *link;
+ struct link *link;
+ int i, j;
- ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
ACPI_SERIAL_ASSERT(pci_link);
-
- entry->pci_link = NULL;
- TAILQ_FOREACH(link, &acpi_pci_link_entries, links) {
- if (link->handle == handle) {
- entry->pci_link = link;
- link->references++;
- return_ACPI_STATUS (AE_OK);
- }
+ printf("Index IRQ Rtd Ref IRQs\n");
+ for (i = 0; i < sc->pl_num_links; i++) {
+ link = &sc->pl_links[i];
+ printf("%5d %3d %c %3d ", i, link->l_irq,
+ link->l_routed ? 'Y' : 'N', link->l_references);
+ if (link->l_num_irqs == 0)
+ printf(" none");
+ else for (j = 0; j < link->l_num_irqs; j++)
+ printf(" %d", link->l_irqs[j]);
+ printf("\n");
}
+}
- link = AcpiOsAllocate(sizeof(struct acpi_pci_link_entry));
- if (link == NULL) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "couldn't allocate memory - %s\n", acpi_name(handle)));
- return_ACPI_STATUS (AE_NO_MEMORY);
- }
+static int
+acpi_pci_link_attach(device_t dev)
+{
+ struct acpi_pci_link_softc *sc;
+ struct link_res_request req;
+ ACPI_STATUS status;
+ int i;
- buf.Pointer = NULL;
- buf.Length = ACPI_ALLOCATE_BUFFER;
-
- bzero(link, sizeof(struct acpi_pci_link_entry));
- link->handle = handle;
+ sc = device_get_softc(dev);
+ ACPI_SERIAL_BEGIN(pci_link);
/*
- * Get the IRQ configured at boot-time. If successful, set this
- * as the initial IRQ.
+ * Count the number of current resources so we know how big of
+ * a link array to allocate.
*/
- error = acpi_pci_link_get_current_irq(link, &link->current_irq);
- if (ACPI_SUCCESS(error)) {
- link->initial_irq = link->current_irq;
- } else {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "couldn't get current IRQ from interrupt link %s - %s\n",
- acpi_name(handle), AcpiFormatException(error)));
- link->initial_irq = 0;
- }
+ status = AcpiWalkResources(acpi_get_handle(dev), "_CRS",
+ acpi_count_resources, &sc->pl_num_links);
+ if (ACPI_FAILURE(status))
+ return (ENXIO);
+ if (sc->pl_num_links == 0)
+ return (0);
+ sc->pl_links = malloc(sizeof(struct link) * sc->pl_num_links,
+ M_PCI_LINK, M_WAITOK | M_ZERO);
- error = AcpiGetPossibleResources(handle, &buf);
- if (ACPI_FAILURE(error)) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "couldn't get interrupt link device _PRS data %s - %s\n",
- acpi_name(handle), AcpiFormatException(error)));
- goto out;
+ /* Initialize the child links. */
+ for (i = 0; i < sc->pl_num_links; i++) {
+ sc->pl_links[i].l_irq = PCI_INVALID_IRQ;
+ sc->pl_links[i].l_bios_irq = PCI_INVALID_IRQ;
+ sc->pl_links[i].l_res_index = i;
+ sc->pl_links[i].l_sc = sc;
+ sc->pl_links[i].l_isa_irq = 0;
}
- if (buf.Pointer == NULL) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "_PRS buffer is empty - %s\n", acpi_name(handle)));
- error = AE_NO_MEMORY;
- goto out;
+ req.count = 0;
+ req.sc = sc;
+ status = AcpiWalkResources(acpi_get_handle(dev), "_CRS",
+ link_add_crs, &req);
+ if (ACPI_FAILURE(status))
+ goto fail;
+ req.count = 0;
+ status = AcpiWalkResources(acpi_get_handle(dev), "_PRS",
+ link_add_prs, &req);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+ goto fail;
+ if (bootverbose) {
+ device_printf(dev, "Links after initial probe:\n");
+ acpi_pci_link_dump(sc);
}
- /* Skip any DPF descriptors. XXX We should centralize this code. */
- resources = (ACPI_RESOURCE *) buf.Pointer;
- if (resources->Id == ACPI_RSTYPE_START_DPF)
- resources = ACPI_NEXT_RESOURCE(resources);
-
- /* XXX This only handles one resource, ignoring SourceIndex. */
- bcopy(resources, &link->possible_resources,
- sizeof(link->possible_resources));
-
- error = acpi_pci_link_get_irq_resources(resources,
- &link->number_of_interrupts, link->interrupts);
- if (ACPI_FAILURE(error)) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "couldn't get possible IRQs from interrupt link %s - %s\n",
- acpi_name(handle), AcpiFormatException(error)));
- goto out;
+ /* Verify initial IRQs if we have _PRS. */
+ if (status != AE_NOT_FOUND)
+ for (i = 0; i < sc->pl_num_links; i++)
+ if (!link_valid_irq(&sc->pl_links[i],
+ sc->pl_links[i].l_irq))
+ sc->pl_links[i].l_irq = PCI_INVALID_IRQ;
+ if (bootverbose) {
+ device_printf(dev, "Links after initial validation:\n");
+ acpi_pci_link_dump(sc);
}
- if (link->number_of_interrupts == 0) {
- ACPI_DEBUG_PRINT((ACPI_DB_WARN,
- "interrupt link device _PRS data is corrupted - %s\n",
- acpi_name(handle)));
- error = AE_NULL_ENTRY;
- goto out;
- }
+ /* Save initial IRQs. */
+ for (i = 0; i < sc->pl_num_links; i++)
+ sc->pl_links[i].l_initial_irq = sc->pl_links[i].l_irq;
/*
* Try to disable this link. If successful, set the current IRQ to
* zero and flags to indicate this link is not routed. If we can't
* run _DIS (i.e., the method doesn't exist), assume the initial
* IRQ was routed by the BIOS.
- *
- * XXX Since we detect link devices via _PRT entries but run long
- * after APIC mode has been enabled, we don't get a chance to
- * disable links that will be unused (especially in APIC mode).
- * Leaving them enabled can cause duplicate interrupts for some
- * devices. The right fix is to probe links via their PNPID, so we
- * see them no matter what the _PRT says.
*/
- if (ACPI_SUCCESS(AcpiEvaluateObject(handle, "_DIS", NULL, NULL))) {
- link->current_irq = 0;
- link->flags = ACPI_LINK_NONE;
- } else
- link->flags = ACPI_LINK_ROUTED;
-
- /*
- * If the initial IRQ is invalid (not in _PRS), set it to 0 and
- * mark this link as not routed. We won't use it as the preferred
- * interrupt later when we route.
- */
- if (!acpi_pci_link_is_valid_irq(link, link->initial_irq) &&
- link->initial_irq != 0) {
- printf("ACPI link %s has invalid initial irq %d, ignoring\n",
- acpi_name(handle), link->initial_irq);
- link->initial_irq = 0;
- link->flags = ACPI_LINK_NONE;
+ if (ACPI_SUCCESS(AcpiEvaluateObject(acpi_get_handle(dev), "_DIS", NULL,
+ NULL)))
+ for (i = 0; i < sc->pl_num_links; i++)
+ sc->pl_links[i].l_irq = PCI_INVALID_IRQ;
+ else
+ for (i = 0; i < sc->pl_num_links; i++)
+ if (PCI_INTERRUPT_VALID(sc->pl_links[i].l_irq))
+ sc->pl_links[i].l_routed = 1;
+ if (bootverbose) {
+ device_printf(dev, "Links after disable:\n");
+ acpi_pci_link_dump(sc);
}
+ ACPI_SERIAL_END(pci_link);
+ return (0);
+fail:
+ ACPI_SERIAL_END(pci_link);
+ for (i = 0; i < sc->pl_num_links; i++)
+ if (sc->pl_links[i].l_irqs != NULL)
+ free(sc->pl_links[i].l_irqs, M_PCI_LINK);
+ free(sc->pl_links, M_PCI_LINK);
+ return (ENXIO);
+}
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list