need to ensure kpreempt_disable() for softint_schedule(). fix the locking in ohci_timeout_task(), ohci_device_isoc_start(), ohci_device_isoc_abort() and ohci_device_isoc_close(). uaudio(4) can still play with these, but mixerctl -a against it will hang the writer. however, mixerctl continues to run in a tight loop and the system isn't soft-locked up at this point, an advance from how it is in -current.diff -r1.181.6.2 -r1.181.6.3 src/sys/dev/usb/ehci.c
(mrg)
--- src/sys/dev/usb/ehci.c 2011/12/04 19:22:56 1.181.6.2
+++ src/sys/dev/usb/ehci.c 2011/12/06 02:10:01 1.181.6.3
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ehci.c,v 1.181.6.2 2011/12/04 19:22:56 jmcneill Exp $ */ | 1 | /* $NetBSD: ehci.c,v 1.181.6.3 2011/12/06 02:10:01 mrg Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2004-2011 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2004-2011 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Lennart Augustsson (lennart@augustsson.net), Charles M. Hannum, | 8 | * by Lennart Augustsson (lennart@augustsson.net), Charles M. Hannum, | |
9 | * Jeremy Morse (jeremy.morse@gmail.com), and Jared D. McNeill | 9 | * Jeremy Morse (jeremy.morse@gmail.com), and Jared D. McNeill | |
10 | * (jmcneill@invisible.ca). | 10 | * (jmcneill@invisible.ca). | |
11 | * | 11 | * | |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without | |
13 | * modification, are permitted provided that the following conditions | 13 | * modification, are permitted provided that the following conditions | |
14 | * are met: | 14 | * are met: | |
@@ -43,27 +43,27 @@ | @@ -43,27 +43,27 @@ | |||
43 | 43 | |||
44 | /* | 44 | /* | |
45 | * TODO: | 45 | * TODO: | |
46 | * 1) hold off explorations by companion controllers until ehci has started. | 46 | * 1) hold off explorations by companion controllers until ehci has started. | |
47 | * | 47 | * | |
48 | * 2) The hub driver needs to handle and schedule the transaction translator, | 48 | * 2) The hub driver needs to handle and schedule the transaction translator, | |
49 | * to assign place in frame where different devices get to go. See chapter | 49 | * to assign place in frame where different devices get to go. See chapter | |
50 | * on hubs in USB 2.0 for details. | 50 | * on hubs in USB 2.0 for details. | |
51 | * | 51 | * | |
52 | * 3) Command failures are not recovered correctly. | 52 | * 3) Command failures are not recovered correctly. | |
53 | */ | 53 | */ | |
54 | 54 | |||
55 | #include <sys/cdefs.h> | 55 | #include <sys/cdefs.h> | |
56 | __KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.2 2011/12/04 19:22:56 jmcneill Exp $"); | 56 | __KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.3 2011/12/06 02:10:01 mrg Exp $"); | |
57 | 57 | |||
58 | #include "ohci.h" | 58 | #include "ohci.h" | |
59 | #include "uhci.h" | 59 | #include "uhci.h" | |
60 | #include "opt_usb.h" | 60 | #include "opt_usb.h" | |
61 | 61 | |||
62 | #include <sys/param.h> | 62 | #include <sys/param.h> | |
63 | #include <sys/systm.h> | 63 | #include <sys/systm.h> | |
64 | #include <sys/kernel.h> | 64 | #include <sys/kernel.h> | |
65 | #include <sys/kmem.h> | 65 | #include <sys/kmem.h> | |
66 | #include <sys/device.h> | 66 | #include <sys/device.h> | |
67 | #include <sys/select.h> | 67 | #include <sys/select.h> | |
68 | #include <sys/proc.h> | 68 | #include <sys/proc.h> | |
69 | #include <sys/queue.h> | 69 | #include <sys/queue.h> | |
@@ -642,43 +642,47 @@ ehci_intr1(ehci_softc_t *sc) | @@ -642,43 +642,47 @@ ehci_intr1(ehci_softc_t *sc) | |||
642 | 642 | |||
643 | eintrs = intrs & sc->sc_eintrs; | 643 | eintrs = intrs & sc->sc_eintrs; | |
644 | DPRINTFN(7, ("ehci_intr1: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n", | 644 | DPRINTFN(7, ("ehci_intr1: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n", | |
645 | sc, (u_int)intrs, EOREAD4(sc, EHCI_USBSTS), | 645 | sc, (u_int)intrs, EOREAD4(sc, EHCI_USBSTS), | |
646 | (u_int)eintrs)); | 646 | (u_int)eintrs)); | |
647 | if (!eintrs) | 647 | if (!eintrs) | |
648 | return (0); | 648 | return (0); | |
649 | 649 | |||
650 | EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */ | 650 | EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */ | |
651 | sc->sc_bus.intr_context++; | 651 | sc->sc_bus.intr_context++; | |
652 | sc->sc_bus.no_intrs++; | 652 | sc->sc_bus.no_intrs++; | |
653 | if (eintrs & EHCI_STS_IAA) { | 653 | if (eintrs & EHCI_STS_IAA) { | |
654 | DPRINTF(("ehci_intr1: door bell\n")); | 654 | DPRINTF(("ehci_intr1: door bell\n")); | |
655 | kpreempt_disable(); | |||
655 | softint_schedule(sc->sc_doorbell_si); | 656 | softint_schedule(sc->sc_doorbell_si); | |
657 | kpreempt_enable(); | |||
656 | eintrs &= ~EHCI_STS_IAA; | 658 | eintrs &= ~EHCI_STS_IAA; | |
657 | } | 659 | } | |
658 | if (eintrs & (EHCI_STS_INT | EHCI_STS_ERRINT)) { | 660 | if (eintrs & (EHCI_STS_INT | EHCI_STS_ERRINT)) { | |
659 | DPRINTFN(5,("ehci_intr1: %s %s\n", | 661 | DPRINTFN(5,("ehci_intr1: %s %s\n", | |
660 | eintrs & EHCI_STS_INT ? "INT" : "", | 662 | eintrs & EHCI_STS_INT ? "INT" : "", | |
661 | eintrs & EHCI_STS_ERRINT ? "ERRINT" : "")); | 663 | eintrs & EHCI_STS_ERRINT ? "ERRINT" : "")); | |
662 | usb_schedsoftintr(&sc->sc_bus); | 664 | usb_schedsoftintr(&sc->sc_bus); | |
663 | eintrs &= ~(EHCI_STS_INT | EHCI_STS_ERRINT); | 665 | eintrs &= ~(EHCI_STS_INT | EHCI_STS_ERRINT); | |
664 | } | 666 | } | |
665 | if (eintrs & EHCI_STS_HSE) { | 667 | if (eintrs & EHCI_STS_HSE) { | |
666 | printf("%s: unrecoverable error, controller halted\n", | 668 | printf("%s: unrecoverable error, controller halted\n", | |
667 | device_xname(sc->sc_dev)); | 669 | device_xname(sc->sc_dev)); | |
668 | /* XXX what else */ | 670 | /* XXX what else */ | |
669 | } | 671 | } | |
670 | if (eintrs & EHCI_STS_PCD) { | 672 | if (eintrs & EHCI_STS_PCD) { | |
673 | kpreempt_disable(); | |||
671 | softint_schedule(sc->sc_pcd_si); | 674 | softint_schedule(sc->sc_pcd_si); | |
675 | kpreempt_enable(); | |||
672 | eintrs &= ~EHCI_STS_PCD; | 676 | eintrs &= ~EHCI_STS_PCD; | |
673 | } | 677 | } | |
674 | 678 | |||
675 | sc->sc_bus.intr_context--; | 679 | sc->sc_bus.intr_context--; | |
676 | 680 | |||
677 | if (eintrs != 0) { | 681 | if (eintrs != 0) { | |
678 | /* Block unprocessed interrupts. */ | 682 | /* Block unprocessed interrupts. */ | |
679 | sc->sc_eintrs &= ~eintrs; | 683 | sc->sc_eintrs &= ~eintrs; | |
680 | EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); | 684 | EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); | |
681 | printf("%s: blocking intrs 0x%x\n", | 685 | printf("%s: blocking intrs 0x%x\n", | |
682 | device_xname(sc->sc_dev), eintrs); | 686 | device_xname(sc->sc_dev), eintrs); | |
683 | } | 687 | } | |
684 | 688 |
--- src/sys/dev/usb/ohci.c 2011/12/04 21:02:27 1.218.6.2
+++ src/sys/dev/usb/ohci.c 2011/12/06 02:10:01 1.218.6.3
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ohci.c,v 1.218.6.2 2011/12/04 21:02:27 jmcneill Exp $ */ | 1 | /* $NetBSD: ohci.c,v 1.218.6.3 2011/12/06 02:10:01 mrg Exp $ */ | |
2 | /* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ | 2 | /* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 1998, 2004, 2005, 2011 The NetBSD Foundation, Inc. | 5 | * Copyright (c) 1998, 2004, 2005, 2011 The NetBSD Foundation, Inc. | |
6 | * All rights reserved. | 6 | * All rights reserved. | |
7 | * | 7 | * | |
8 | * This code is derived from software contributed to The NetBSD Foundation | 8 | * This code is derived from software contributed to The NetBSD Foundation | |
9 | * by Lennart Augustsson (lennart@augustsson.net) at | 9 | * by Lennart Augustsson (lennart@augustsson.net) at | |
10 | * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca) | 10 | * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca) | |
11 | * and Matthew R. Green. | 11 | * and Matthew R. Green. | |
12 | * This code is derived from software contributed to The NetBSD Foundation | 12 | * This code is derived from software contributed to The NetBSD Foundation | |
13 | * by Charles M. Hannum. | 13 | * by Charles M. Hannum. | |
14 | * | 14 | * | |
@@ -32,27 +32,27 @@ | @@ -32,27 +32,27 @@ | |||
32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
34 | * POSSIBILITY OF SUCH DAMAGE. | 34 | * POSSIBILITY OF SUCH DAMAGE. | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | /* | 37 | /* | |
38 | * USB Open Host Controller driver. | 38 | * USB Open Host Controller driver. | |
39 | * | 39 | * | |
40 | * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html | 40 | * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html | |
41 | * USB spec: http://www.usb.org/developers/docs/ | 41 | * USB spec: http://www.usb.org/developers/docs/ | |
42 | */ | 42 | */ | |
43 | 43 | |||
44 | #include <sys/cdefs.h> | 44 | #include <sys/cdefs.h> | |
45 | __KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.2 2011/12/04 21:02:27 jmcneill Exp $"); | 45 | __KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.3 2011/12/06 02:10:01 mrg Exp $"); | |
46 | 46 | |||
47 | #include "opt_usb.h" | 47 | #include "opt_usb.h" | |
48 | 48 | |||
49 | #include <sys/param.h> | 49 | #include <sys/param.h> | |
50 | #include <sys/systm.h> | 50 | #include <sys/systm.h> | |
51 | #include <sys/kmem.h> | 51 | #include <sys/kmem.h> | |
52 | #include <sys/kernel.h> | 52 | #include <sys/kernel.h> | |
53 | #include <sys/device.h> | 53 | #include <sys/device.h> | |
54 | #include <sys/select.h> | 54 | #include <sys/select.h> | |
55 | #include <sys/proc.h> | 55 | #include <sys/proc.h> | |
56 | #include <sys/queue.h> | 56 | #include <sys/queue.h> | |
57 | 57 | |||
58 | #include <sys/bus.h> | 58 | #include <sys/bus.h> | |
@@ -2010,34 +2010,30 @@ ohci_timeout(void *addr) | @@ -2010,34 +2010,30 @@ ohci_timeout(void *addr) | |||
2010 | return; | 2010 | return; | |
2011 | } | 2011 | } | |
2012 | 2012 | |||
2013 | /* Execute the abort in a process context. */ | 2013 | /* Execute the abort in a process context. */ | |
2014 | usb_init_task(&oxfer->abort_task, ohci_timeout_task, addr); | 2014 | usb_init_task(&oxfer->abort_task, ohci_timeout_task, addr); | |
2015 | usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task, | 2015 | usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task, | |
2016 | USB_TASKQ_HC); | 2016 | USB_TASKQ_HC); | |
2017 | } | 2017 | } | |
2018 | 2018 | |||
2019 | void | 2019 | void | |
2020 | ohci_timeout_task(void *addr) | 2020 | ohci_timeout_task(void *addr) | |
2021 | { | 2021 | { | |
2022 | usbd_xfer_handle xfer = addr; | 2022 | usbd_xfer_handle xfer = addr; | |
2023 | ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; | |||
2024 | 2023 | |||
2025 | DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer)); | 2024 | DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer)); | |
2026 | 2025 | |||
2027 | KASSERT(mutex_owned(&sc->sc_lock)); | |||
2028 | //mutex_enter(&sc->sc_lock); | |||
2029 | ohci_abort_xfer(xfer, USBD_TIMEOUT); | 2026 | ohci_abort_xfer(xfer, USBD_TIMEOUT); | |
2030 | //mutex_exit(&sc->sc_lock); | |||
2031 | } | 2027 | } | |
2032 | 2028 | |||
2033 | #ifdef OHCI_DEBUG | 2029 | #ifdef OHCI_DEBUG | |
2034 | void | 2030 | void | |
2035 | ohci_dump_tds(ohci_softc_t *sc, ohci_soft_td_t *std) | 2031 | ohci_dump_tds(ohci_softc_t *sc, ohci_soft_td_t *std) | |
2036 | { | 2032 | { | |
2037 | for (; std; std = std->nexttd) | 2033 | for (; std; std = std->nexttd) | |
2038 | ohci_dump_td(sc, std); | 2034 | ohci_dump_td(sc, std); | |
2039 | } | 2035 | } | |
2040 | 2036 | |||
2041 | void | 2037 | void | |
2042 | ohci_dump_td(ohci_softc_t *sc, ohci_soft_td_t *std) | 2038 | ohci_dump_td(ohci_softc_t *sc, ohci_soft_td_t *std) | |
2043 | { | 2039 | { | |
@@ -3530,40 +3526,42 @@ ohci_device_isoc_start(usbd_xfer_handle | @@ -3530,40 +3526,42 @@ ohci_device_isoc_start(usbd_xfer_handle | |||
3530 | 3526 | |||
3531 | if (sc->sc_dying) { | 3527 | if (sc->sc_dying) { | |
3532 | mutex_exit(&sc->sc_lock); | 3528 | mutex_exit(&sc->sc_lock); | |
3533 | return (USBD_IOERROR); | 3529 | return (USBD_IOERROR); | |
3534 | } | 3530 | } | |
3535 | 3531 | |||
3536 | #ifdef DIAGNOSTIC | 3532 | #ifdef DIAGNOSTIC | |
3537 | if (xfer->status != USBD_IN_PROGRESS) | 3533 | if (xfer->status != USBD_IN_PROGRESS) | |
3538 | printf("ohci_device_isoc_start: not in progress %p\n", xfer); | 3534 | printf("ohci_device_isoc_start: not in progress %p\n", xfer); | |
3539 | #endif | 3535 | #endif | |
3540 | 3536 | |||
3541 | /* XXX anything to do? */ | 3537 | /* XXX anything to do? */ | |
3542 | 3538 | |||
3539 | mutex_exit(&sc->sc_lock); | |||
3540 | ||||
3543 | return (USBD_IN_PROGRESS); | 3541 | return (USBD_IN_PROGRESS); | |
3544 | } | 3542 | } | |
3545 | 3543 | |||
3546 | void | 3544 | void | |
3547 | ohci_device_isoc_abort(usbd_xfer_handle xfer) | 3545 | ohci_device_isoc_abort(usbd_xfer_handle xfer) | |
3548 | { | 3546 | { | |
3549 | struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; | 3547 | struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; | |
3550 | ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; | 3548 | ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; | |
3551 | ohci_soft_ed_t *sed; | 3549 | ohci_soft_ed_t *sed; | |
3552 | ohci_soft_itd_t *sitd; | 3550 | ohci_soft_itd_t *sitd; | |
3553 | 3551 | |||
3554 | DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer)); | 3552 | DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p lock=%p\n", xfer, &sc->sc_lock)); | |
3555 | 3553 | |||
3556 | KASSERT(mutex_owned(&sc->sc_lock)); | 3554 | mutex_enter(&sc->sc_lock); | |
3557 | 3555 | |||
3558 | /* Transfer is already done. */ | 3556 | /* Transfer is already done. */ | |
3559 | if (xfer->status != USBD_NOT_STARTED && | 3557 | if (xfer->status != USBD_NOT_STARTED && | |
3560 | xfer->status != USBD_IN_PROGRESS) { | 3558 | xfer->status != USBD_IN_PROGRESS) { | |
3561 | printf("ohci_device_isoc_abort: early return\n"); | 3559 | printf("ohci_device_isoc_abort: early return\n"); | |
3562 | goto done; | 3560 | goto done; | |
3563 | } | 3561 | } | |
3564 | 3562 | |||
3565 | /* Give xfer the requested abort code. */ | 3563 | /* Give xfer the requested abort code. */ | |
3566 | xfer->status = USBD_CANCELLED; | 3564 | xfer->status = USBD_CANCELLED; | |
3567 | 3565 | |||
3568 | sed = opipe->sed; | 3566 | sed = opipe->sed; | |
3569 | usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), | 3567 | usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), | |
@@ -3625,19 +3623,21 @@ ohci_setup_isoc(usbd_pipe_handle pipe) | @@ -3625,19 +3623,21 @@ ohci_setup_isoc(usbd_pipe_handle pipe) | |||
3625 | ohci_add_ed(sc, opipe->sed, sc->sc_isoc_head); | 3623 | ohci_add_ed(sc, opipe->sed, sc->sc_isoc_head); | |
3626 | mutex_exit(&sc->sc_lock); | 3624 | mutex_exit(&sc->sc_lock); | |
3627 | 3625 | |||
3628 | return (USBD_NORMAL_COMPLETION); | 3626 | return (USBD_NORMAL_COMPLETION); | |
3629 | } | 3627 | } | |
3630 | 3628 | |||
3631 | void | 3629 | void | |
3632 | ohci_device_isoc_close(usbd_pipe_handle pipe) | 3630 | ohci_device_isoc_close(usbd_pipe_handle pipe) | |
3633 | { | 3631 | { | |
3634 | struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; | 3632 | struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; | |
3635 | ohci_softc_t *sc = pipe->device->bus->hci_private; | 3633 | ohci_softc_t *sc = pipe->device->bus->hci_private; | |
3636 | 3634 | |||
3637 | DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe)); | 3635 | DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe)); | |
3636 | mutex_enter(&sc->sc_lock); | |||
3638 | ohci_close_pipe(pipe, sc->sc_isoc_head); | 3637 | ohci_close_pipe(pipe, sc->sc_isoc_head); | |
3639 | #ifdef DIAGNOSTIC | 3638 | #ifdef DIAGNOSTIC | |
3640 | opipe->tail.itd->isdone = 1; | 3639 | opipe->tail.itd->isdone = 1; | |
3641 | #endif | 3640 | #endif | |
3641 | mutex_exit(&sc->sc_lock); | |||
3642 | ohci_free_sitd(sc, opipe->tail.itd); | 3642 | ohci_free_sitd(sc, opipe->tail.itd); | |
3643 | } | 3643 | } |
--- src/sys/dev/usb/usb.c 2011/12/04 13:23:17 1.125.6.1
+++ src/sys/dev/usb/usb.c 2011/12/06 02:10:01 1.125.6.2
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: usb.c,v 1.125.6.1 2011/12/04 13:23:17 jmcneill Exp $ */ | 1 | /* $NetBSD: usb.c,v 1.125.6.2 2011/12/06 02:10:01 mrg Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1998, 2002, 2008 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1998, 2002, 2008 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Lennart Augustsson (lennart@augustsson.net) at | 8 | * by Lennart Augustsson (lennart@augustsson.net) at | |
9 | * Carlstedt Research & Technology. | 9 | * Carlstedt Research & Technology. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
@@ -27,27 +27,27 @@ | @@ -27,27 +27,27 @@ | |||
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
30 | * POSSIBILITY OF SUCH DAMAGE. | 30 | * POSSIBILITY OF SUCH DAMAGE. | |
31 | */ | 31 | */ | |
32 | 32 | |||
33 | /* | 33 | /* | |
34 | * USB specifications and other documentation can be found at | 34 | * USB specifications and other documentation can be found at | |
35 | * http://www.usb.org/developers/docs/ and | 35 | * http://www.usb.org/developers/docs/ and | |
36 | * http://www.usb.org/developers/devclass_docs/ | 36 | * http://www.usb.org/developers/devclass_docs/ | |
37 | */ | 37 | */ | |
38 | 38 | |||
39 | #include <sys/cdefs.h> | 39 | #include <sys/cdefs.h> | |
40 | __KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.1 2011/12/04 13:23:17 jmcneill Exp $"); | 40 | __KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.2 2011/12/06 02:10:01 mrg Exp $"); | |
41 | 41 | |||
42 | #include "opt_compat_netbsd.h" | 42 | #include "opt_compat_netbsd.h" | |
43 | #include "opt_usb.h" | 43 | #include "opt_usb.h" | |
44 | 44 | |||
45 | #include <sys/param.h> | 45 | #include <sys/param.h> | |
46 | #include <sys/systm.h> | 46 | #include <sys/systm.h> | |
47 | #include <sys/kernel.h> | 47 | #include <sys/kernel.h> | |
48 | #include <sys/malloc.h> | 48 | #include <sys/malloc.h> | |
49 | #include <sys/device.h> | 49 | #include <sys/device.h> | |
50 | #include <sys/kthread.h> | 50 | #include <sys/kthread.h> | |
51 | #include <sys/proc.h> | 51 | #include <sys/proc.h> | |
52 | #include <sys/conf.h> | 52 | #include <sys/conf.h> | |
53 | #include <sys/fcntl.h> | 53 | #include <sys/fcntl.h> | |
@@ -880,50 +880,54 @@ usb_add_event(int type, struct usb_event | @@ -880,50 +880,54 @@ usb_add_event(int type, struct usb_event | |||
880 | ueq->ue.ue_type = type; | 880 | ueq->ue.ue_type = type; | |
881 | TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time); | 881 | TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time); | |
882 | 882 | |||
883 | s = splusb(); | 883 | s = splusb(); | |
884 | if (++usb_nevents >= USB_MAX_EVENTS) { | 884 | if (++usb_nevents >= USB_MAX_EVENTS) { | |
885 | /* Too many queued events, drop an old one. */ | 885 | /* Too many queued events, drop an old one. */ | |
886 | DPRINTFN(-1,("usb: event dropped\n")); | 886 | DPRINTFN(-1,("usb: event dropped\n")); | |
887 | (void)usb_get_next_event(0); | 887 | (void)usb_get_next_event(0); | |
888 | } | 888 | } | |
889 | SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next); | 889 | SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next); | |
890 | wakeup(&usb_events); | 890 | wakeup(&usb_events); | |
891 | selnotify(&usb_selevent, 0, 0); | 891 | selnotify(&usb_selevent, 0, 0); | |
892 | if (usb_async_proc != NULL) { | 892 | if (usb_async_proc != NULL) { | |
893 | kpreempt_disable(); | |||
893 | softint_schedule(usb_async_sih); | 894 | softint_schedule(usb_async_sih); | |
895 | kpreempt_enable(); | |||
894 | } | 896 | } | |
895 | splx(s); | 897 | splx(s); | |
896 | } | 898 | } | |
897 | 899 | |||
898 | Static void | 900 | Static void | |
899 | usb_async_intr(void *cookie) | 901 | usb_async_intr(void *cookie) | |
900 | { | 902 | { | |
901 | proc_t *proc; | 903 | proc_t *proc; | |
902 | 904 | |||
903 | mutex_enter(proc_lock); | 905 | mutex_enter(proc_lock); | |
904 | if ((proc = usb_async_proc) != NULL) | 906 | if ((proc = usb_async_proc) != NULL) | |
905 | psignal(proc, SIGIO); | 907 | psignal(proc, SIGIO); | |
906 | mutex_exit(proc_lock); | 908 | mutex_exit(proc_lock); | |
907 | } | 909 | } | |
908 | 910 | |||
909 | void | 911 | void | |
910 | usb_schedsoftintr(usbd_bus_handle bus) | 912 | usb_schedsoftintr(usbd_bus_handle bus) | |
911 | { | 913 | { | |
912 | DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling)); | 914 | DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling)); | |
913 | if (bus->use_polling) { | 915 | if (bus->use_polling) { | |
914 | bus->methods->soft_intr(bus); | 916 | bus->methods->soft_intr(bus); | |
915 | } else { | 917 | } else { | |
918 | kpreempt_disable(); | |||
916 | softint_schedule(bus->soft); | 919 | softint_schedule(bus->soft); | |
920 | kpreempt_enable(); | |||
917 | } | 921 | } | |
918 | } | 922 | } | |
919 | 923 | |||
920 | int | 924 | int | |
921 | usb_activate(device_t self, enum devact act) | 925 | usb_activate(device_t self, enum devact act) | |
922 | { | 926 | { | |
923 | struct usb_softc *sc = device_private(self); | 927 | struct usb_softc *sc = device_private(self); | |
924 | 928 | |||
925 | switch (act) { | 929 | switch (act) { | |
926 | case DVACT_DEACTIVATE: | 930 | case DVACT_DEACTIVATE: | |
927 | sc->sc_dying = 1; | 931 | sc->sc_dying = 1; | |
928 | return 0; | 932 | return 0; | |
929 | default: | 933 | default: |