Be paranoid about disabling interrupts and acknowledging any pending
interrupts while attaching uhci. Fixes recent problems with uvm_fault during uhci attach, which appear to be caused by a pending interrupt left over from the device while it was operating in legacy support mode under the control of the BIOS. Patch by joerg@ because his was better than mine.
This commit is contained in:
parent
b79e2bcb32
commit
33bf6486d0
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: uhci_pci.c,v 1.37 2007/10/19 12:00:56 ad Exp $ */
|
||||
/* $NetBSD: uhci_pci.c,v 1.38 2007/11/24 02:13:49 gavan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -38,7 +38,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uhci_pci.c,v 1.37 2007/10/19 12:00:56 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uhci_pci.c,v 1.38 2007/11/24 02:13:49 gavan Exp $");
|
||||
|
||||
#include "ehci.h"
|
||||
|
||||
@ -105,6 +105,7 @@ uhci_pci_attach(struct device *parent, struct device *self, void *aux)
|
||||
const char *devname = sc->sc.sc_bus.bdev.dv_xname;
|
||||
char devinfo[256];
|
||||
usbd_status r;
|
||||
int s;
|
||||
|
||||
aprint_naive("\n");
|
||||
|
||||
@ -119,8 +120,13 @@ uhci_pci_attach(struct device *parent, struct device *self, void *aux)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable interrupts, so we don't get any spurious ones. */
|
||||
/*
|
||||
* Disable interrupts, so we don't get any spurious ones.
|
||||
* Acknolewdge all pending interrupts.
|
||||
*/
|
||||
bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
|
||||
bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_STS,
|
||||
bus_space_read_2(sc->sc.iot, sc->sc.ioh, UHCI_STS));
|
||||
|
||||
sc->sc_pc = pc;
|
||||
sc->sc_tag = tag;
|
||||
@ -147,8 +153,17 @@ uhci_pci_attach(struct device *parent, struct device *self, void *aux)
|
||||
}
|
||||
aprint_normal("%s: interrupting at %s\n", devname, intrstr);
|
||||
|
||||
/* Set LEGSUP register to its default value. */
|
||||
/*
|
||||
* Set LEGSUP register to its default value.
|
||||
* This can reenable or trigger interrupts, so protect against them
|
||||
* and explicitly disable and ACK them afterwards.
|
||||
*/
|
||||
s = splhardusb();
|
||||
pci_conf_write(pc, tag, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN);
|
||||
bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0);
|
||||
bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_STS,
|
||||
bus_space_read_2(sc->sc.iot, sc->sc.ioh, UHCI_STS));
|
||||
splx(s);
|
||||
|
||||
switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) {
|
||||
case PCI_USBREV_PRE_1_0:
|
||||
|
Loading…
Reference in New Issue
Block a user