Module Name: src
Committed By: cegger
Date: Sat Apr 18 06:27:17 UTC 2009
Modified Files:
src/sys/dev/usb: ohci.c
Log Message:
Initialize callout and lists before we check for errors.
This fixes crashes in ohci_detach() when ohci_init() failed.
To generate a diff of this commit:
cvs rdiff -u -r1.197 -r1.198 src/sys/dev/usb/ohci.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/usb/ohci.c
diff -u src/sys/dev/usb/ohci.c:1.197 src/sys/dev/usb/ohci.c:1.198
--- src/sys/dev/usb/ohci.c:1.197 Tue Dec 16 22:35:36 2008
+++ src/sys/dev/usb/ohci.c Sat Apr 18 06:27:17 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: ohci.c,v 1.197 2008/12/16 22:35:36 christos Exp $ */
+/* $NetBSD: ohci.c,v 1.198 2009/04/18 06:27:17 cegger Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.197 2008/12/16 22:35:36 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.198 2009/04/18 06:27:17 cegger Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -396,8 +396,10 @@
usb_uncallout(sc->sc_tmo_rhsc, ohci_rhsc_enable, sc);
usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
+ usb_callout_destroy(sc->sc_tmo_rhsc);
- usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
+ if (sc->sc_hcca != NULL)
+ usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
while((xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers)) != NULL) {
SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
free(xfer, M_USB);
@@ -691,6 +693,16 @@
#else
printf("%s:", device_xname(sc->sc_dev));
#endif
+ sc->sc_hcca = NULL;
+ usb_callout_init(sc->sc_tmo_rhsc);
+
+ for (i = 0; i < OHCI_HASH_SIZE; i++)
+ LIST_INIT(&sc->sc_hash_tds[i]);
+ for (i = 0; i < OHCI_HASH_SIZE; i++)
+ LIST_INIT(&sc->sc_hash_itds[i]);
+
+ SIMPLEQ_INIT(&sc->sc_free_xfers);
+
rev = OREAD4(sc, OHCI_REVISION);
printf(" OHCI version %d.%d%s\n", OHCI_REV_HI(rev), OHCI_REV_LO(rev),
OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
@@ -703,13 +715,6 @@
}
sc->sc_bus.usbrev = USBREV_1_0;
- for (i = 0; i < OHCI_HASH_SIZE; i++)
- LIST_INIT(&sc->sc_hash_tds[i]);
- for (i = 0; i < OHCI_HASH_SIZE; i++)
- LIST_INIT(&sc->sc_hash_itds[i]);
-
- SIMPLEQ_INIT(&sc->sc_free_xfers);
-
#ifdef __NetBSD__
usb_setup_reserve(sc->sc_dev, &sc->sc_dma_reserve, sc->sc_bus.dmatag,
USB_MEM_RESERVE);
@@ -719,8 +724,10 @@
/* Allocate the HCCA area. */
err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
OHCI_HCCA_ALIGN, &sc->sc_hccadma);
- if (err)
- return (err);
+ if (err) {
+ sc->sc_hcca = NULL;
+ return err;
+ }
sc->sc_hcca = KERNADDR(&sc->sc_hccadma, 0);
memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE);
@@ -927,8 +934,6 @@
sc->sc_control = sc->sc_intre = 0;
#endif
- usb_callout_init(sc->sc_tmo_rhsc);
-
/* Finally, turn on interrupts. */
DPRINTFN(1,("ohci_init: enabling\n"));
OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
@@ -946,6 +951,7 @@
ohci_free_sed(sc, sc->sc_ctrl_head);
bad1:
usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
+ sc->sc_hcca = NULL;
return (err);
}