This patch is made by Masanori Kanaoka.  Slightly cleaned up by me.

Index: arch/i386/acpi/vald_acpi.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/acpi/vald_acpi.c,v
retrieving revision 1.5
diff -u -r1.5 vald_acpi.c
--- arch/i386/acpi/vald_acpi.c	2002/10/02 05:47:11	1.5
+++ arch/i386/acpi/vald_acpi.c	2003/03/30 09:59:44
@@ -447,9 +447,17 @@
 			}
 		}
 		if (sc->sc_ac_status == 1) /* AC adaptor on when attach */
+#ifndef LIBRETTO
 			sc->lcd_index = sc->lcd_num -1; /* MAX Brightness */
+#else
+			sc->lcd_index = 3; /* MAX Brightness */
+#endif
 		else
+#ifndef LIBRETTO
 			sc->lcd_index = 3;
+#else
+			sc->lcd_index = 2;
+#endif
 
 #ifdef ACPI_DEBUG
 		pi = sc->lcd_level;
Index: arch/i386/i386/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/autoconf.c,v
retrieving revision 1.68
diff -u -r1.68 autoconf.c
--- arch/i386/i386/autoconf.c	2003/03/22 13:05:26	1.68
+++ arch/i386/i386/autoconf.c	2003/03/30 09:59:45
@@ -99,12 +99,14 @@
 #include <machine/bios32.h>
 #endif
 
+#ifndef LIBRETTO
 #include "opt_pcibios.h"
 #ifdef PCIBIOS
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 #include <i386/pci/pcibios.h>
 #endif
+#endif /* LIBRETTO */
 
 #include "opt_kvm86.h"
 #ifdef KVM86
@@ -126,9 +128,11 @@
 #if NBIOS32 > 0
 	bios32_init();
 #endif
+#ifndef LIBRETTO
 #ifdef PCIBIOS
 	pcibios_init();
 #endif
+#endif /* LIBRETTO */
 
 	/* kvm86 needs a TSS */
 	i386_proc0_tss_ldt_init();
Index: arch/i386/i386/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.517
diff -u -r1.517 machdep.c
--- arch/i386/i386/machdep.c	2003/03/25 19:37:16	1.517
+++ arch/i386/i386/machdep.c	2003/03/30 09:59:48
@@ -1641,6 +1641,13 @@
 		}
 	}
 #endif /* ! REALBASEMEM && ! REALEXTMEM */
+
+#ifdef LIBRETTO
+#ifdef DEBUG_MEMLOAD
+	printf("mem_cluster_count: %d\n", mem_cluster_cnt);
+#endif
+#endif
+
 	/*
 	 * If the loop above didn't find any valid segment, fall back to
 	 * former code.
Index: arch/i386/i386/mainbus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/mainbus.c,v
retrieving revision 1.50
diff -u -r1.50 mainbus.c
--- arch/i386/i386/mainbus.c	2003/03/04 01:06:38	1.50
+++ arch/i386/i386/mainbus.c	2003/03/30 09:59:48
@@ -55,6 +55,15 @@
 #include "acpi.h"
 #include "vesabios.h"
 
+#ifdef LIBRETTO
+#include "opt_pcibios.h"
+#ifdef PCIBIOS
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <i386/pci/pcibios.h>
+#endif
+#endif /* LIBRETTO */
+
 #include "opt_mpacpi.h"
 #include "opt_mpbios.h"
 
@@ -278,6 +287,12 @@
 		config_found(self, &mba.mba_paa, mainbus_print);
 	}
 #endif
+
+#ifdef LIBRETTO
+#ifdef PCIBIOS
+	pcibios_init();
+#endif
+#endif /* LIBRETTO */
 
 	/*
 	 * XXX Note also that the presence of a PCI bus should
Index: arch/i386/pci/pci_intr_fixup.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/pci/pci_intr_fixup.c,v
retrieving revision 1.23
diff -u -r1.23 pci_intr_fixup.c
--- arch/i386/pci/pci_intr_fixup.c	2003/02/26 22:23:08	1.23
+++ arch/i386/pci/pci_intr_fixup.c	2003/03/30 09:59:49
@@ -571,10 +571,20 @@
 {
 	int i, bit;
 
+#ifdef LIBRETTO
+	/* XXX: Force set Level for some irq (such as ACPI SCI) */
+	*pciirq |= pcibios_force_level_bitmap;
+#endif /* LIBRETTO */
+
 	for (i = 0, bit = 1; i < 16; i++, bit <<= 1) {
 		if ((*pciirq & bit) == 0)
 			(void) pciintr_icu_set_trigger(pciintr_icu_tag,
 			    pciintr_icu_handle, i, IST_EDGE);
+#ifdef LIBRETTO
+		else if (pcibios_force_level_bitmap & bit)
+			(void) pciintr_icu_set_trigger(pciintr_icu_tag,
+			    pciintr_icu_handle, i, IST_LEVEL);
+#endif /* LIBRETTO */
 	}
 
 	return (0);
Index: arch/i386/pci/pcibios.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/pci/pcibios.c,v
retrieving revision 1.11
diff -u -r1.11 pcibios.c
--- arch/i386/pci/pcibios.c	2003/02/26 22:23:09	1.11
+++ arch/i386/pci/pcibios.c	2003/03/30 09:59:49
@@ -83,6 +83,10 @@
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcidevs.h>
 
+#ifdef LIBRETTO
+#include <dev/acpi/acpivar.h>
+#endif /* LIBRETTO */
+
 #include <i386/pci/pcibios.h>
 #ifdef PCIBIOS_INTR_FIXUP
 #include <i386/pci/pci_intr_fixup.h>
@@ -126,6 +130,19 @@
 #define	PCI_IRQ_TABLE_START	0xf0000
 #define	PCI_IRQ_TABLE_END	0xfffff
 
+#ifdef LIBRETTO
+/* for Libretto L2/L3 hack */
+void   pcibios_fixup_pir_table __P((void));
+void   pcibios_fixup_pir_table_mask __P((struct pcibios_linkmap *));
+
+struct pcibios_linkmap pir_mask[] = {
+	{ 2,    0x0040 },
+	{ 7,    0x0080 },
+	{ 8,    0x0020 },
+	{ 0,    0x0000 }
+};
+#endif /* LIBRETTO */
+
 static void pci_bridge_hook(pci_chipset_tag_t, pcitag_t, void *);
 struct pci_bridge_hook_arg {
 	void (*func)(pci_chipset_tag_t, pcitag_t, void *);
@@ -237,7 +254,62 @@
 	u_int16_t tablesize;
 	u_int8_t rev_maj, rev_min;
 	int i;
+#ifdef LIBRETTO
+	struct pcibios_intr_routing *pir;
+	struct acpi_intr *ai;
+#endif /* LIBRETTO */
+
+#ifdef LIBRETTO
+	/*
+	 * XXXlibretto
+	 * For Libretto L series, we firstly try using ACPI PRT.
+	 * This is done when the ACPI_PIR_GET option is set.
+	 */
+	pcibios_force_level_bitmap = 0;
+	if (acpi_pir_info != NULL && acpi_pir_info->api_nentries != 0) {
+		pcibios_pir_table = malloc(acpi_pir_info->api_nentries * 16, 
+		    M_DEVBUF, M_NOWAIT);
+		if (pcibios_pir_table == NULL) {
+			printf("pcibios_pir_init: no memory for $PIR\n");
+			return;
+		}
+		for (ai = acpi_pir_info->api_intr, pir = pcibios_pir_table;
+		     ai;
+		     ai = ai->ai_next, pir++) {
+			pir->bus = ai->ai_bus;
+			pir->device = (ai->ai_dev & 0x1f) << 3;
+			for (i = 0; i < 4; i++) {
+				if (i == ai->ai_pin) {
+					pir->linkmap[i].link = ai->ai_link;
+					pir->linkmap[i].bitmap = ai->ai_bitmap;
+				} else {
+					pir->linkmap[i].link = 0;
+					pir->linkmap[i].bitmap = 0;
+				}
+			}
+			pir->slot = 0;
+			pir->reserved = 0;
+		}
+		pcibios_pir_table_nentries = acpi_pir_info->api_nentries;
+		pcibios_force_level_bitmap = (1 << acpi_pir_info->api_sci_irq);
+		printf("\nUsing ACPI PRT information.\n");
+
+		/*
+		 * XXXlibretto
+		 * For Libretto L2/L3.
+		 */
+		pcibios_fixup_pir_table();
+#ifdef PCIINTR_DEBUG
+		pcibios_print_pir_table();
+#endif
+		return;
+	}
 
+	/*
+	 * XXXlibretto
+	 * If no ACPI PRT is found, try using $PIR table. 
+	 */
+#endif /* LIBRETTO */
 	for (pa = PCI_IRQ_TABLE_START; pa < PCI_IRQ_TABLE_END; pa += 16) {
 		p = (caddr_t)ISA_HOLE_VADDR(pa);
 		if (*(int *)p != BIOS32_MAKESIG('$', 'P', 'I', 'R')) {
@@ -301,6 +373,10 @@
 		}
 		printf("\n");
 		pcibios_print_exclirq();
+#ifdef LIBRETTO
+		/* for Libretto L2/L3 hack */
+		pcibios_fixup_pir_table();
+#endif /* LIBRETTO */
 #ifdef PCIINTR_DEBUG
 		pcibios_print_pir_table();
 #endif
@@ -333,6 +409,10 @@
 	printf("PCI BIOS has %d Interrupt Routing table entries\n",
 	    pcibios_pir_table_nentries);
 	pcibios_print_exclirq();
+#ifdef LIBRETTO
+	/* for Libretto L2/L3 hack */
+	pcibios_fixup_pir_table();
+#endif
 #ifdef PCIINTR_DEBUG
 	pcibios_print_pir_table();
 #endif
@@ -477,6 +557,35 @@
 		printf("\n");
 	}
 }
+
+#ifdef LIBRETTO
+/* for Libretto L2/L3 hack */
+void 
+pcibios_fixup_pir_table()
+{
+	struct pcibios_linkmap *m;
+
+	for (m = pir_mask; m->link != 0; m++)
+		pcibios_fixup_pir_table_mask(m);
+}
+
+void 
+pcibios_fixup_pir_table_mask(mask)
+	struct pcibios_linkmap *mask;
+{
+	int i, j;
+
+	for (i = 0; i < pcibios_pir_table_nentries; i++) {
+		for (j = 0; j < 4; j++) {
+			if (pcibios_pir_table[i].linkmap[j].link ==
+			     mask->link) {
+				pcibios_pir_table[i].linkmap[j].bitmap
+				    &= mask->bitmap; 
+			}
+		}
+	}
+}
+#endif /* LIBRETTO */
 
 #ifdef PCIINTR_DEBUG
 void
Index: arch/i386/pci/pcibios.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/pci/pcibios.h,v
retrieving revision 1.5
diff -u -r1.5 pcibios.h
--- arch/i386/pci/pcibios.h	2002/01/22 15:07:27	1.5
+++ arch/i386/pci/pcibios.h	2003/03/30 09:59:49
@@ -100,6 +100,10 @@
 void pci_bridge_foreach(pci_chipset_tag_t, int, int,
     void (*) (pci_chipset_tag_t, pcitag_t, void *), void *);
 
+#ifdef LIBRETTO
+u_int16_t pcibios_force_level_bitmap;
+#endif
+
 #ifdef PCIBIOSVERBOSE
 extern int pcibiosverbose;
 
Index: dev/acpi/acpi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.33
diff -u -r1.33 acpi.c
--- dev/acpi/acpi.c	2003/03/05 23:00:56	1.33
+++ dev/acpi/acpi.c	2003/03/30 09:59:52
@@ -60,18 +60,32 @@
 #include <dev/acpi/acpidevs_data.h>
 #endif
 
+#ifndef LIBRETTO
 #ifndef ACPI_PCI_FIXUP
 #define ACPI_PCI_FIXUP 1
 #endif
+#else /* LIBRETTO */
+#ifndef ACPI_PCI_GET
+#define ACPI_PCI_GET 1
+#endif
+#endif /* LIBRETTO */
 
 #ifndef ACPI_ACTIVATE_DEV
 #define ACPI_ACTIVATE_DEV 0
 #endif
 
+#ifndef LIBRETTO
 #if ACPI_PCI_FIXUP
 #include <dev/acpi/acpica/Subsystem/acnamesp.h> /* AcpiNsGetNodeByPath() */
 #include <dev/pci/pcidevs.h>
 #endif
+#else
+#if ACPI_PCI_GET
+#include <dev/acpi/acpica/Subsystem/acresrc.h>
+#include <dev/acpi/acpica/Subsystem/acnamesp.h> /* AcpiNsGetNodeByPath() */
+#include <dev/pci/pcidevs.h>
+#endif
+#endif /* LIBRETTO */
 
 MALLOC_DECLARE(M_ACPI);
 
@@ -125,12 +139,18 @@
 ACPI_STATUS	acpi_make_devnode(ACPI_HANDLE, UINT32, void *, void **);
 
 void		acpi_enable_fixed_events(struct acpi_softc *);
+#ifndef LIBRETTO
 #if ACPI_PCI_FIXUP
 void		acpi_pci_fixup(struct acpi_softc *);
 #endif
 #if ACPI_PCI_FIXUP || ACPI_ACTIVATE_DEV
 ACPI_STATUS	acpi_allocate_resources(ACPI_HANDLE handle);
 #endif
+#else /* LIBRETTO */
+#if ACPI_PCI_GET
+void		acpi_pir_get(struct acpi_softc *);
+#endif
+#endif /* LIBRETTO */
 
 /*
  * acpi_probe:
@@ -311,12 +331,19 @@
 	 */
 	acpi_enable_fixed_events(sc);
 
+#ifndef LIBRETTO
 	/*
 	 * Fix up PCI devices.
 	 */
 #if ACPI_PCI_FIXUP
 	acpi_pci_fixup(sc);
 #endif
+#else /* LIBRETTO */
+#if ACPI_PIR_GET
+	/* Get PCI IRQ ROUTING table. */
+	acpi_pir_get(sc);
+#endif /* ACPI_PIR_GET */
+#endif /* LIBRETTO */
  
 	/*
 	 * Scan the namespace and build our device tree.
@@ -810,6 +837,15 @@
 	bufp->Length = ACPI_ALLOCATE_BUFFER;
 
 	rv = AcpiEvaluateObject(handle, path, NULL, bufp);
+#ifdef MY
+	/* XXXuebayasi */
+	if (rv == AE_BUFFER_OVERFLOW) {
+		bufp->Pointer = AcpiOsAllocate(bufp->Length);
+		if (bufp->Pointer == NULL)
+			return (AE_NO_MEMORY);
+		rv = AcpiEvaluateObject(handle, path, NULL, bufp);
+	}
+#endif /* MY */
 
 	return (rv);
 }
@@ -986,6 +1022,7 @@
 	return (ret);
 }
 
+#ifdef LIBRETTO
 #if ACPI_PCI_FIXUP
 ACPI_STATUS acpi_pci_fixup_bus(ACPI_HANDLE, UINT32, void *, void **);
 /*
@@ -1010,7 +1047,36 @@
 	AcpiWalkNamespace(ACPI_TYPE_DEVICE, parent, 100,
 	    acpi_pci_fixup_bus, sc, NULL);
 }
+#endif /* ACPI_PCI_FIXUP */
+#else /* LIBRETTO */
+#if ACPI_PIR_GET
+ACPI_STATUS acpi_pir_get_bus(ACPI_HANDLE, UINT32, void *, void **);
+/*
+ * XXXlibretto
+ * acpi_pir_get:
+ *
+ *	Get the _PTR (PCI Routing Table), and create an ACPI PIR table 
+ *	which PCIBIOS_INTR_FIXUP will use later.
+ */
+void
+acpi_pir_get(struct acpi_softc *sc)
+{
+	ACPI_HANDLE parent;
+
+#ifdef ACPI_DEBUG
+	printf("acpi_pir_get starts:\n");
+#endif
+	if (AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &parent) != AE_OK)
+		return;
+	sc->sc_pci_bus = 0;
+	AcpiWalkNamespace(ACPI_TYPE_DEVICE, parent, 100,
+	    acpi_pir_get_bus, sc, NULL);
+}
+#endif /* ACPI_PIR_GET */
+#endif /* LIBRETTO */
 
+#ifndef LIBRETTO
+#if ACPI_PCI_FIXUP
 static ACPI_HANDLE
 acpi_get_node(char *name)
 {
@@ -1152,7 +1218,7 @@
 	    sc->sc_pci_bus, level);
 #endif
 
-        for (Buffer = buf.Pointer; ; Buffer += PrtElement->Length) {
+        for (Buffer = buf.Pointer;; Buffer += PrtElement->Length) {
 		PrtElement = (ACPI_PCI_ROUTING_TABLE *)Buffer;
 		if (PrtElement->Length == 0)
 			break;
@@ -1192,7 +1258,121 @@
 	return (AE_OK);
 }
 #endif /* ACPI_PCI_FIXUP */
+#else /* LIBRETTO */
+#if ACPI_PIR_GET
+static UINT16
+acpi_get_bitmap(ACPI_HANDLE handle)
+{
+	ACPI_BUFFER bufp, bufc;
+	ACPI_STATUS rv;
+	ACPI_RESOURCE *resp, *resc;
+	ACPI_RESOURCE_IRQ *irq;
+	UINT16 i, bitmap = 0;
+
+	rv = acpi_get(handle, &bufp, AcpiGetPossibleResources);
+	if (ACPI_FAILURE(rv))
+		goto out;
+	rv = acpi_get(handle, &bufc, AcpiGetCurrentResources);
+	if (ACPI_FAILURE(rv))
+		goto out1;
+
+	resp = bufp.Pointer;
+	resc = bufc.Pointer;
+
+	/*
+	 * If current NumberOfInterrupt is 1, we use it.
+	 * Else we use possible.
+	 */
+	irq = (ACPI_RESOURCE_IRQ *)&resc->Data;
+	if (irq->NumberOfInterrupts != 1)
+		irq = (ACPI_RESOURCE_IRQ *)&resp->Data;
+
+	for (i = 0; i < irq->NumberOfInterrupts; i++)
+		bitmap |= (1 << irq->Interrupts[i]);
+
+	free(bufc.Pointer, M_DEVBUF);
+out1:
+	free(bufp.Pointer, M_DEVBUF);
+out:
+	return (bitmap);
+}
+
+ACPI_STATUS
+acpi_pir_get_bus(ACPI_HANDLE handle, UINT32 level, void *context,
+		   void **status)
+{
+	struct acpi_softc *sc = context;
+	ACPI_STATUS rv;
+	ACPI_BUFFER buf;
+	UINT8 *Buffer;
+	ACPI_PCI_ROUTING_TABLE *PrtElement;
+	ACPI_HANDLE link;
+	char LastChar;
+	UINT16 bitmap;
+	struct acpi_intr *ai;
+
+	rv = acpi_get(handle, &buf, AcpiGetIrqRoutingTable);
+	if (ACPI_FAILURE(rv))
+		return (AE_OK);
+
+	acpi_pir_info = malloc(sizeof(struct acpi_pir), M_DEVBUF, M_NOWAIT);
+	if (acpi_pir_info == NULL) {
+		printf("No memory for acpi_pir_info\n");
+		return (AE_OK);
+	}
+	acpi_pir_info->api_intr = NULL;
+	acpi_pir_info->api_nentries = 0;
+	acpi_pir_info->api_sci_irq = AcpiGbl_FADT->SciInt;
+
+        for (Buffer = buf.Pointer;; Buffer += PrtElement->Length) {
+		PrtElement = (ACPI_PCI_ROUTING_TABLE *)Buffer;
+		if (PrtElement->Length == 0)
+			break;
+		if (PrtElement->Source == NULL)
+			continue;
+
+		link = acpi_get_node(PrtElement->Source);
+		if (link == NULL)
+			continue;
+		bitmap = acpi_get_bitmap(link);
+
+		LastChar = PrtElement->Source[strlen(PrtElement->Source) - 1];
+		if (LastChar >= 'A' && LastChar <= 'Z')
+			LastChar -= '@';
+		else if (LastChar >= '0' && LastChar <= '9')
+			LastChar -= '0';
+
+#ifdef ACPI_DEBUG
+		printf("\tBus: %d Device: %d\n ", sc->sc_pci_bus,
+		    (unsigned)PrtElement->Address >> 16);
+		printf("\t\tINT%c: link 0x%02x bitmap 0x%04x\n",
+		    PrtElement->Pin + 1 + '@', LastChar, bitmap);
+#endif
+		/* XXX: make pcibios Interface. */
+		ai = malloc(sizeof(*ai), M_DEVBUF, M_NOWAIT);
+		if (ai == NULL) {
+			printf("No memory for ai\n");
+			return (AE_OK);
+		}
+		ai->ai_next = acpi_pir_info->api_intr;
+		ai->ai_bus = sc->sc_pci_bus;
+		ai->ai_dev = (unsigned)PrtElement->Address >> 16;
+		ai->ai_pin = PrtElement->Pin;
+		ai->ai_link = LastChar;
+		ai->ai_bitmap = bitmap;
+		acpi_pir_info->api_intr = ai;
+		acpi_pir_info->api_nentries++;
+	}
+
+	sc->sc_pci_bus++;
+
+	free(buf.Pointer, M_DEVBUF);
+	return (AE_OK);
+}
+#endif /* ACPI_PIR_GET */
+#endif /* LIBRETTO */
 
+#ifndef LIBRETTO
 #if ACPI_PCI_FIXUP || ACPI_ACTIVATE_DEV
 /* XXX This very incomplete */
 ACPI_STATUS
@@ -1279,3 +1459,4 @@
 	return rv;
 }
 #endif /* ACPI_PCI_FIXUP || ACPI_ACTIVATE_DEV */
+#endif /* LIBRETTO */
Index: dev/acpi/acpivar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.9
diff -u -r1.9 acpivar.h
--- dev/acpi/acpivar.h	2003/02/14 11:05:40	1.9
+++ dev/acpi/acpivar.h	2003/03/30 09:59:52
@@ -268,6 +268,25 @@
 struct acpi_irq		*acpi_res_irq(struct acpi_resources *, int);
 struct acpi_drq		*acpi_res_drq(struct acpi_resources *, int);
 
+#ifdef LIBRETTO
+struct acpi_intr {
+	struct acpi_intr *ai_next;
+	u_int8_t	ai_bus;
+	u_int8_t	ai_dev;
+	u_int8_t	ai_pin;
+	u_int8_t	ai_link;
+	u_int16_t	ai_bitmap;
+};
+
+struct acpi_pir {
+	struct acpi_intr *api_intr;
+	int api_nentries;
+	int api_sci_irq;
+};
+
+struct acpi_pir *acpi_pir_info;
+#endif /* LIBRETTO */
+
 /*
  * power state transition
  */
Index: dev/ic/ac97.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ac97.c,v
retrieving revision 1.41
diff -u -r1.41 ac97.c
--- dev/ic/ac97.c	2003/03/03 02:14:12	1.41
+++ dev/ic/ac97.c	2003/03/30 09:59:54
@@ -658,6 +658,10 @@
 #define DPRINTFN(n,x)
 #endif
 
+#ifdef LIBRETTO
+static int	ac97_waitthrough;
+#endif
+
 void
 ac97_read(as, reg, val)
 	struct ac97_softc *as;
@@ -665,9 +669,15 @@
 	u_int16_t *val;
 {
 
+#ifndef LIBRETTO
 	if (as->host_flags & AC97_HOST_DONT_READ &&
 	    (reg != AC97_REG_VENDOR_ID1 && reg != AC97_REG_VENDOR_ID2 &&
 	     reg != AC97_REG_RESET)) {
+#else
+	if (reg != AC97_REG_VENDOR_ID1 &&
+	    reg != AC97_REG_VENDOR_ID2 &&
+	    reg != AC97_REG_RESET) {
+#endif /* LIBRETTO */
 		*val = as->shadow_reg[reg >> 1];
 		return;
 	}
@@ -684,6 +694,11 @@
 	u_int16_t val;
 {
 
+#ifdef LIBRETTO
+	if (ac97_waitthrough == 0 && as->shadow_reg[reg >> 1] == val)
+		return (0);
+#endif
+
 	as->shadow_reg[reg >> 1] = val;
 
 	return (as->host_if->write(as->host_if->arg, reg, val));
@@ -697,11 +712,17 @@
 	const struct ac97_source_info *si;
 
 	memset(as->shadow_reg, 0, sizeof(as->shadow_reg));
+#ifdef LIBRETTO
+	ac97_waitthrough = 1;
+#endif
 
 	for (idx = 0; idx < SOURCE_INFO_SIZE; idx++) {
 		si = &source_info[idx];
 		ac97_write(as, si->reg, si->default_value);
 	}
+#ifdef LIBRETTO
+	ac97_waitthrough = 0;
+#endif
 }
 
 void
@@ -712,10 +733,16 @@
 	int idx;
 	const struct ac97_source_info *si;
 
+#ifdef LIBRETTO
+	ac97_waitthrough = 1;
+#endif
 	for (idx = 0; idx < SOURCE_INFO_SIZE; idx++) {
 		si = &source_info[idx];
 		ac97_write(as, si->reg, as->shadow_reg[si->reg >> 1]);
 	}
+#ifdef LIBRETTO
+	ac97_waitthrough = 0;
+#endif
 }
 
 int
