| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ehci.c,v 1.234.2.38 2015/03/03 10:06:01 skrll Exp $ */ | | 1 | /* $NetBSD: ehci.c,v 1.234.2.39 2015/03/05 20:57:07 skrll Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2004-2012 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2004-2012 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), Jared D. McNeill | | 9 | * Jeremy Morse (jeremy.morse@gmail.com), Jared D. McNeill |
10 | * (jmcneill@invisible.ca) and Matthew R. Green (mrg@eterna.com.au). | | 10 | * (jmcneill@invisible.ca) and Matthew R. Green (mrg@eterna.com.au). |
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.234.2.38 2015/03/03 10:06:01 skrll Exp $"); | | 56 | __KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.234.2.39 2015/03/05 20:57:07 skrll 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 | | | 63 | |
64 | #include <sys/bus.h> | | 64 | #include <sys/bus.h> |
65 | #include <sys/cpu.h> | | 65 | #include <sys/cpu.h> |
66 | #include <sys/device.h> | | 66 | #include <sys/device.h> |
67 | #include <sys/kernel.h> | | 67 | #include <sys/kernel.h> |
68 | #include <sys/kmem.h> | | 68 | #include <sys/kmem.h> |
69 | #include <sys/mutex.h> | | 69 | #include <sys/mutex.h> |
| @@ -3095,28 +3095,28 @@ ehci_close_pipe(usbd_pipe_handle pipe, e | | | @@ -3095,28 +3095,28 @@ ehci_close_pipe(usbd_pipe_handle pipe, e |
3095 | * If this routine is called at splusb() it guarantees that the request | | 3095 | * If this routine is called at splusb() it guarantees that the request |
3096 | * will be removed from the hardware scheduling and that the callback | | 3096 | * will be removed from the hardware scheduling and that the callback |
3097 | * for it will be called with USBD_CANCELLED status. | | 3097 | * for it will be called with USBD_CANCELLED status. |
3098 | * It's impossible to guarantee that the requested transfer will not | | 3098 | * It's impossible to guarantee that the requested transfer will not |
3099 | * have happened since the hardware runs concurrently. | | 3099 | * have happened since the hardware runs concurrently. |
3100 | * If the transaction has already happened we rely on the ordinary | | 3100 | * If the transaction has already happened we rely on the ordinary |
3101 | * interrupt processing to process it. | | 3101 | * interrupt processing to process it. |
3102 | * XXX This is most probably wrong. | | 3102 | * XXX This is most probably wrong. |
3103 | * XXXMRG this doesn't make sense anymore. | | 3103 | * XXXMRG this doesn't make sense anymore. |
3104 | */ | | 3104 | */ |
3105 | Static void | | 3105 | Static void |
3106 | ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) | | 3106 | ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) |
3107 | { | | 3107 | { |
3108 | #define exfer EXFER(xfer) | | | |
3109 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; | | 3108 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; |
| | | 3109 | struct ehci_xfer *exfer = EXFER(xfer); |
3110 | ehci_softc_t *sc = epipe->pipe.up_dev->ud_bus->ub_hcpriv; | | 3110 | ehci_softc_t *sc = epipe->pipe.up_dev->ud_bus->ub_hcpriv; |
3111 | ehci_soft_qh_t *sqh = epipe->sqh; | | 3111 | ehci_soft_qh_t *sqh = epipe->sqh; |
3112 | ehci_soft_qtd_t *sqtd; | | 3112 | ehci_soft_qtd_t *sqtd; |
3113 | ehci_physaddr_t cur; | | 3113 | ehci_physaddr_t cur; |
3114 | uint32_t qhstatus; | | 3114 | uint32_t qhstatus; |
3115 | int hit; | | 3115 | int hit; |
3116 | int wake; | | 3116 | int wake; |
3117 | | | 3117 | |
3118 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); | | 3118 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); |
3119 | | | 3119 | |
3120 | USBHIST_LOG(ehcidebug, "xfer=%p pipe=%p", xfer, epipe, 0, 0); | | 3120 | USBHIST_LOG(ehcidebug, "xfer=%p pipe=%p", xfer, epipe, 0, 0); |
3121 | | | 3121 | |
3122 | KASSERT(mutex_owned(&sc->sc_lock)); | | 3122 | KASSERT(mutex_owned(&sc->sc_lock)); |
| @@ -3232,27 +3232,26 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u | | | @@ -3232,27 +3232,26 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u |
3232 | * Step 4: Execute callback. | | 3232 | * Step 4: Execute callback. |
3233 | */ | | 3233 | */ |
3234 | #ifdef DIAGNOSTIC | | 3234 | #ifdef DIAGNOSTIC |
3235 | exfer->ex_isdone = true; | | 3235 | exfer->ex_isdone = true; |
3236 | #endif | | 3236 | #endif |
3237 | wake = xfer->ux_hcflags & UXFER_ABORTWAIT; | | 3237 | wake = xfer->ux_hcflags & UXFER_ABORTWAIT; |
3238 | xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); | | 3238 | xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); |
3239 | usb_transfer_complete(xfer); | | 3239 | usb_transfer_complete(xfer); |
3240 | if (wake) { | | 3240 | if (wake) { |
3241 | cv_broadcast(&xfer->ux_hccv); | | 3241 | cv_broadcast(&xfer->ux_hccv); |
3242 | } | | 3242 | } |
3243 | | | 3243 | |
3244 | KASSERT(mutex_owned(&sc->sc_lock)); | | 3244 | KASSERT(mutex_owned(&sc->sc_lock)); |
3245 | #undef exfer | | | |
3246 | } | | 3245 | } |
3247 | | | 3246 | |
3248 | Static void | | 3247 | Static void |
3249 | ehci_abort_isoc_xfer(usbd_xfer_handle xfer, usbd_status status) | | 3248 | ehci_abort_isoc_xfer(usbd_xfer_handle xfer, usbd_status status) |
3250 | { | | 3249 | { |
3251 | ehci_isoc_trans_t trans_status; | | 3250 | ehci_isoc_trans_t trans_status; |
3252 | struct ehci_pipe *epipe; | | 3251 | struct ehci_pipe *epipe; |
3253 | struct ehci_xfer *exfer; | | 3252 | struct ehci_xfer *exfer; |
3254 | ehci_softc_t *sc; | | 3253 | ehci_softc_t *sc; |
3255 | struct ehci_soft_itd *itd; | | 3254 | struct ehci_soft_itd *itd; |
3256 | struct ehci_soft_sitd *sitd; | | 3255 | struct ehci_soft_sitd *sitd; |
3257 | int i, wake; | | 3256 | int i, wake; |
3258 | | | 3257 | |
| @@ -3485,28 +3484,28 @@ ehci_device_ctrl_close(usbd_pipe_handle | | | @@ -3485,28 +3484,28 @@ ehci_device_ctrl_close(usbd_pipe_handle |
3485 | | | 3484 | |
3486 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); | | 3485 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); |
3487 | | | 3486 | |
3488 | KASSERT(mutex_owned(&sc->sc_lock)); | | 3487 | KASSERT(mutex_owned(&sc->sc_lock)); |
3489 | | | 3488 | |
3490 | USBHIST_LOG(ehcidebug, "pipe=%p", pipe, 0, 0, 0); | | 3489 | USBHIST_LOG(ehcidebug, "pipe=%p", pipe, 0, 0, 0); |
3491 | | | 3490 | |
3492 | ehci_close_pipe(pipe, sc->sc_async_head); | | 3491 | ehci_close_pipe(pipe, sc->sc_async_head); |
3493 | } | | 3492 | } |
3494 | | | 3493 | |
3495 | Static usbd_status | | 3494 | Static usbd_status |
3496 | ehci_device_request(usbd_xfer_handle xfer) | | 3495 | ehci_device_request(usbd_xfer_handle xfer) |
3497 | { | | 3496 | { |
3498 | #define exfer EXFER(xfer) | | | |
3499 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; | | 3497 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; |
| | | 3498 | struct ehci_xfer *exfer = EXFER(xfer); |
3500 | usb_device_request_t *req = &xfer->ux_request; | | 3499 | usb_device_request_t *req = &xfer->ux_request; |
3501 | usbd_device_handle dev = epipe->pipe.up_dev; | | 3500 | usbd_device_handle dev = epipe->pipe.up_dev; |
3502 | ehci_softc_t *sc = dev->ud_bus->ub_hcpriv; | | 3501 | ehci_softc_t *sc = dev->ud_bus->ub_hcpriv; |
3503 | ehci_soft_qtd_t *setup, *stat, *next; | | 3502 | ehci_soft_qtd_t *setup, *stat, *next; |
3504 | ehci_soft_qh_t *sqh; | | 3503 | ehci_soft_qh_t *sqh; |
3505 | int isread; | | 3504 | int isread; |
3506 | int len; | | 3505 | int len; |
3507 | usbd_status err; | | 3506 | usbd_status err; |
3508 | | | 3507 | |
3509 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); | | 3508 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); |
3510 | | | 3509 | |
3511 | isread = req->bmRequestType & UT_READ; | | 3510 | isread = req->bmRequestType & UT_READ; |
3512 | len = UGETW(req->wLength); | | 3511 | len = UGETW(req->wLength); |
| @@ -3636,27 +3635,26 @@ ehci_device_request(usbd_xfer_handle xfe | | | @@ -3636,27 +3635,26 @@ ehci_device_request(usbd_xfer_handle xfe |
3636 | | | 3635 | |
3637 | bad3: | | 3636 | bad3: |
3638 | mutex_exit(&sc->sc_lock); | | 3637 | mutex_exit(&sc->sc_lock); |
3639 | ehci_free_sqtd(sc, stat); | | 3638 | ehci_free_sqtd(sc, stat); |
3640 | bad2: | | 3639 | bad2: |
3641 | ehci_free_sqtd(sc, setup); | | 3640 | ehci_free_sqtd(sc, setup); |
3642 | bad1: | | 3641 | bad1: |
3643 | USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); | | 3642 | USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); |
3644 | mutex_enter(&sc->sc_lock); | | 3643 | mutex_enter(&sc->sc_lock); |
3645 | xfer->ux_status = err; | | 3644 | xfer->ux_status = err; |
3646 | usb_transfer_complete(xfer); | | 3645 | usb_transfer_complete(xfer); |
3647 | mutex_exit(&sc->sc_lock); | | 3646 | mutex_exit(&sc->sc_lock); |
3648 | return err; | | 3647 | return err; |
3649 | #undef exfer | | | |
3650 | } | | 3648 | } |
3651 | | | 3649 | |
3652 | /* | | 3650 | /* |
3653 | * Some EHCI chips from VIA seem to trigger interrupts before writing back the | | 3651 | * Some EHCI chips from VIA seem to trigger interrupts before writing back the |
3654 | * qTD status, or miss signalling occasionally under heavy load. If the host | | 3652 | * qTD status, or miss signalling occasionally under heavy load. If the host |
3655 | * machine is too fast, we we can miss transaction completion - when we scan | | 3653 | * machine is too fast, we we can miss transaction completion - when we scan |
3656 | * the active list the transaction still seems to be active. This generally | | 3654 | * the active list the transaction still seems to be active. This generally |
3657 | * exhibits itself as a umass stall that never recovers. | | 3655 | * exhibits itself as a umass stall that never recovers. |
3658 | * | | 3656 | * |
3659 | * We work around this behaviour by setting up this callback after any softintr | | 3657 | * We work around this behaviour by setting up this callback after any softintr |
3660 | * that completes with transactions still pending, giving us another chance to | | 3658 | * that completes with transactions still pending, giving us another chance to |
3661 | * check for completion after the writeback has taken place. | | 3659 | * check for completion after the writeback has taken place. |
3662 | */ | | 3660 | */ |
| @@ -3682,28 +3680,28 @@ ehci_device_bulk_transfer(usbd_xfer_hand | | | @@ -3682,28 +3680,28 @@ ehci_device_bulk_transfer(usbd_xfer_hand |
3682 | mutex_enter(&sc->sc_lock); | | 3680 | mutex_enter(&sc->sc_lock); |
3683 | err = usb_insert_transfer(xfer); | | 3681 | err = usb_insert_transfer(xfer); |
3684 | mutex_exit(&sc->sc_lock); | | 3682 | mutex_exit(&sc->sc_lock); |
3685 | if (err) | | 3683 | if (err) |
3686 | return err; | | 3684 | return err; |
3687 | | | 3685 | |
3688 | /* Pipe isn't running, start first */ | | 3686 | /* Pipe isn't running, start first */ |
3689 | return ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); | | 3687 | return ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); |
3690 | } | | 3688 | } |
3691 | | | 3689 | |
3692 | Static usbd_status | | 3690 | Static usbd_status |
3693 | ehci_device_bulk_start(usbd_xfer_handle xfer) | | 3691 | ehci_device_bulk_start(usbd_xfer_handle xfer) |
3694 | { | | 3692 | { |
3695 | #define exfer EXFER(xfer) | | | |
3696 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; | | 3693 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; |
| | | 3694 | struct ehci_xfer *exfer = EXFER(xfer); |
3697 | usbd_device_handle dev = epipe->pipe.up_dev; | | 3695 | usbd_device_handle dev = epipe->pipe.up_dev; |
3698 | ehci_softc_t *sc = dev->ud_bus->ub_hcpriv; | | 3696 | ehci_softc_t *sc = dev->ud_bus->ub_hcpriv; |
3699 | ehci_soft_qtd_t *data, *dataend; | | 3697 | ehci_soft_qtd_t *data, *dataend; |
3700 | ehci_soft_qh_t *sqh; | | 3698 | ehci_soft_qh_t *sqh; |
3701 | usbd_status err; | | 3699 | usbd_status err; |
3702 | int len, isread, endpt; | | 3700 | int len, isread, endpt; |
3703 | | | 3701 | |
3704 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); | | 3702 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); |
3705 | | | 3703 | |
3706 | USBHIST_LOG(ehcidebug, "xfer=%p len=%d flags=%d", | | 3704 | USBHIST_LOG(ehcidebug, "xfer=%p len=%d flags=%d", |
3707 | xfer, xfer->ux_length, xfer->ux_flags, 0); | | 3705 | xfer, xfer->ux_length, xfer->ux_flags, 0); |
3708 | | | 3706 | |
3709 | if (sc->sc_dying) | | 3707 | if (sc->sc_dying) |
| @@ -3762,27 +3760,26 @@ ehci_device_bulk_start(usbd_xfer_handle | | | @@ -3762,27 +3760,26 @@ ehci_device_bulk_start(usbd_xfer_handle |
3762 | #if 0 | | 3760 | #if 0 |
3763 | printf("async_head:\n"); | | 3761 | printf("async_head:\n"); |
3764 | ehci_dump_sqh(sc->sc_async_head); | | 3762 | ehci_dump_sqh(sc->sc_async_head); |
3765 | #endif | | 3763 | #endif |
3766 | USBHIST_LOG(ehcidebug, "sqh:", 0, 0, 0, 0); | | 3764 | USBHIST_LOG(ehcidebug, "sqh:", 0, 0, 0, 0); |
3767 | ehci_dump_sqh(sqh); | | 3765 | ehci_dump_sqh(sqh); |
3768 | ehci_dump_sqtds(data); | | 3766 | ehci_dump_sqtds(data); |
3769 | #endif | | 3767 | #endif |
3770 | | | 3768 | |
3771 | if (sc->sc_bus.ub_usepolling) | | 3769 | if (sc->sc_bus.ub_usepolling) |
3772 | ehci_waitintr(sc, xfer); | | 3770 | ehci_waitintr(sc, xfer); |
3773 | | | 3771 | |
3774 | return USBD_IN_PROGRESS; | | 3772 | return USBD_IN_PROGRESS; |
3775 | #undef exfer | | | |
3776 | } | | 3773 | } |
3777 | | | 3774 | |
3778 | Static void | | 3775 | Static void |
3779 | ehci_device_bulk_abort(usbd_xfer_handle xfer) | | 3776 | ehci_device_bulk_abort(usbd_xfer_handle xfer) |
3780 | { | | 3777 | { |
3781 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); | | 3778 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); |
3782 | | | 3779 | |
3783 | USBHIST_LOG(ehcidebug, "xfer %p", xfer, 0, 0, 0); | | 3780 | USBHIST_LOG(ehcidebug, "xfer %p", xfer, 0, 0, 0); |
3784 | ehci_abort_xfer(xfer, USBD_CANCELLED); | | 3781 | ehci_abort_xfer(xfer, USBD_CANCELLED); |
3785 | } | | 3782 | } |
3786 | | | 3783 | |
3787 | /* | | 3784 | /* |
3788 | * Close a device bulk pipe. | | 3785 | * Close a device bulk pipe. |
| @@ -3868,28 +3865,28 @@ ehci_device_intr_transfer(usbd_xfer_hand | | | @@ -3868,28 +3865,28 @@ ehci_device_intr_transfer(usbd_xfer_hand |
3868 | if (err) | | 3865 | if (err) |
3869 | return err; | | 3866 | return err; |
3870 | | | 3867 | |
3871 | /* | | 3868 | /* |
3872 | * Pipe isn't running (otherwise err would be USBD_INPROG), | | 3869 | * Pipe isn't running (otherwise err would be USBD_INPROG), |
3873 | * so start it first. | | 3870 | * so start it first. |
3874 | */ | | 3871 | */ |
3875 | return ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); | | 3872 | return ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); |
3876 | } | | 3873 | } |
3877 | | | 3874 | |
3878 | Static usbd_status | | 3875 | Static usbd_status |
3879 | ehci_device_intr_start(usbd_xfer_handle xfer) | | 3876 | ehci_device_intr_start(usbd_xfer_handle xfer) |
3880 | { | | 3877 | { |
3881 | #define exfer EXFER(xfer) | | | |
3882 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; | | 3878 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; |
| | | 3879 | struct ehci_xfer *exfer = EXFER(xfer); |
3883 | usbd_device_handle dev = xfer->ux_pipe->up_dev; | | 3880 | usbd_device_handle dev = xfer->ux_pipe->up_dev; |
3884 | ehci_softc_t *sc = dev->ud_bus->ub_hcpriv; | | 3881 | ehci_softc_t *sc = dev->ud_bus->ub_hcpriv; |
3885 | ehci_soft_qtd_t *data, *dataend; | | 3882 | ehci_soft_qtd_t *data, *dataend; |
3886 | ehci_soft_qh_t *sqh; | | 3883 | ehci_soft_qh_t *sqh; |
3887 | usbd_status err; | | 3884 | usbd_status err; |
3888 | int len, isread, endpt; | | 3885 | int len, isread, endpt; |
3889 | | | 3886 | |
3890 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); | | 3887 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); |
3891 | | | 3888 | |
3892 | USBHIST_LOG(ehcidebug, "xfer=%p len=%d flags=%d", | | 3889 | USBHIST_LOG(ehcidebug, "xfer=%p len=%d flags=%d", |
3893 | xfer, xfer->ux_length, xfer->ux_flags, 0); | | 3890 | xfer, xfer->ux_length, xfer->ux_flags, 0); |
3894 | | | 3891 | |
3895 | if (sc->sc_dying) | | 3892 | if (sc->sc_dying) |
| @@ -3944,27 +3941,26 @@ ehci_device_intr_start(usbd_xfer_handle | | | @@ -3944,27 +3941,26 @@ ehci_device_intr_start(usbd_xfer_handle |
3944 | USBHIST_LOGN(ehcidebug, 5, "data(2)", 0, 0, 0, 0); | | 3941 | USBHIST_LOGN(ehcidebug, 5, "data(2)", 0, 0, 0, 0); |
3945 | // delay(10000); | | 3942 | // delay(10000); |
3946 | USBHIST_LOGN(ehcidebug, 5, "data(3)", 0, 0, 0, 0); | | 3943 | USBHIST_LOGN(ehcidebug, 5, "data(3)", 0, 0, 0, 0); |
3947 | ehci_dump_regs(sc); | | 3944 | ehci_dump_regs(sc); |
3948 | USBHIST_LOGN(ehcidebug, 5, "sqh:", 0, 0, 0, 0); | | 3945 | USBHIST_LOGN(ehcidebug, 5, "sqh:", 0, 0, 0, 0); |
3949 | ehci_dump_sqh(sqh); | | 3946 | ehci_dump_sqh(sqh); |
3950 | ehci_dump_sqtds(data); | | 3947 | ehci_dump_sqtds(data); |
3951 | #endif | | 3948 | #endif |
3952 | | | 3949 | |
3953 | if (sc->sc_bus.ub_usepolling) | | 3950 | if (sc->sc_bus.ub_usepolling) |
3954 | ehci_waitintr(sc, xfer); | | 3951 | ehci_waitintr(sc, xfer); |
3955 | | | 3952 | |
3956 | return USBD_IN_PROGRESS; | | 3953 | return USBD_IN_PROGRESS; |
3957 | #undef exfer | | | |
3958 | } | | 3954 | } |
3959 | | | 3955 | |
3960 | Static void | | 3956 | Static void |
3961 | ehci_device_intr_abort(usbd_xfer_handle xfer) | | 3957 | ehci_device_intr_abort(usbd_xfer_handle xfer) |
3962 | { | | 3958 | { |
3963 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); | | 3959 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); |
3964 | | | 3960 | |
3965 | USBHIST_LOG(ehcidebug, "xfer=%p", xfer, 0, 0, 0); | | 3961 | USBHIST_LOG(ehcidebug, "xfer=%p", xfer, 0, 0, 0); |
3966 | KASSERT(xfer->ux_pipe->up_intrxfer == xfer); | | 3962 | KASSERT(xfer->ux_pipe->up_intrxfer == xfer); |
3967 | | | 3963 | |
3968 | /* | | 3964 | /* |
3969 | * XXX - abort_xfer uses ehci_sync_hc, which syncs via the advance | | 3965 | * XXX - abort_xfer uses ehci_sync_hc, which syncs via the advance |
3970 | * async doorbell. That's dependent on the async list, wheras | | 3966 | * async doorbell. That's dependent on the async list, wheras |
| @@ -3979,44 +3975,43 @@ ehci_device_intr_close(usbd_pipe_handle | | | @@ -3979,44 +3975,43 @@ ehci_device_intr_close(usbd_pipe_handle |
3979 | ehci_softc_t *sc = pipe->up_dev->ud_bus->ub_hcpriv; | | 3975 | ehci_softc_t *sc = pipe->up_dev->ud_bus->ub_hcpriv; |
3980 | struct ehci_pipe *epipe = (struct ehci_pipe *)pipe; | | 3976 | struct ehci_pipe *epipe = (struct ehci_pipe *)pipe; |
3981 | struct ehci_soft_islot *isp; | | 3977 | struct ehci_soft_islot *isp; |
3982 | | | 3978 | |
3983 | KASSERT(mutex_owned(&sc->sc_lock)); | | 3979 | KASSERT(mutex_owned(&sc->sc_lock)); |
3984 | | | 3980 | |
3985 | isp = &sc->sc_islots[epipe->sqh->islot]; | | 3981 | isp = &sc->sc_islots[epipe->sqh->islot]; |
3986 | ehci_close_pipe(pipe, isp->sqh); | | 3982 | ehci_close_pipe(pipe, isp->sqh); |
3987 | } | | 3983 | } |
3988 | | | 3984 | |
3989 | Static void | | 3985 | Static void |
3990 | ehci_device_intr_done(usbd_xfer_handle xfer) | | 3986 | ehci_device_intr_done(usbd_xfer_handle xfer) |
3991 | { | | 3987 | { |
3992 | #define exfer EXFER(xfer) | | | |
3993 | struct ehci_xfer *ex = EXFER(xfer); | | | |
3994 | ehci_softc_t *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; | | 3988 | ehci_softc_t *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
3995 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; | | 3989 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; |
| | | 3990 | struct ehci_xfer *exfer = EXFER(xfer); |
3996 | ehci_soft_qtd_t *data, *dataend; | | 3991 | ehci_soft_qtd_t *data, *dataend; |
3997 | ehci_soft_qh_t *sqh; | | 3992 | ehci_soft_qh_t *sqh; |
3998 | usbd_status err; | | 3993 | usbd_status err; |
3999 | int len, isread, endpt; | | 3994 | int len, isread, endpt; |
4000 | | | 3995 | |
4001 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); | | 3996 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); |
4002 | | | 3997 | |
4003 | USBHIST_LOG(ehcidebug, "xfer=%p, actlen=%d", | | 3998 | USBHIST_LOG(ehcidebug, "xfer=%p, actlen=%d", |
4004 | xfer, xfer->ux_actlen, 0, 0); | | 3999 | xfer, xfer->ux_actlen, 0, 0); |
4005 | | | 4000 | |
4006 | KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); | | 4001 | KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); |
4007 | | | 4002 | |
4008 | if (xfer->ux_pipe->up_repeat) { | | 4003 | if (xfer->ux_pipe->up_repeat) { |
4009 | ehci_free_sqtd_chain(sc, ex->ex_sqtdstart, NULL); | | 4004 | ehci_free_sqtd_chain(sc, exfer->ex_sqtdstart, NULL); |
4010 | | | 4005 | |
4011 | len = epipe->u.intr.length; | | 4006 | len = epipe->u.intr.length; |
4012 | xfer->ux_length = len; | | 4007 | xfer->ux_length = len; |
4013 | endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; | | 4008 | endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; |
4014 | isread = UE_GET_DIR(endpt) == UE_DIR_IN; | | 4009 | isread = UE_GET_DIR(endpt) == UE_DIR_IN; |
4015 | usb_syncmem(&xfer->ux_dmabuf, 0, len, | | 4010 | usb_syncmem(&xfer->ux_dmabuf, 0, len, |
4016 | isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); | | 4011 | isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); |
4017 | sqh = epipe->sqh; | | 4012 | sqh = epipe->sqh; |
4018 | | | 4013 | |
4019 | err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, | | 4014 | err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, |
4020 | &data, &dataend); | | 4015 | &data, &dataend); |
4021 | if (err) { | | 4016 | if (err) { |
4022 | USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); | | 4017 | USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); |
| @@ -4029,35 +4024,34 @@ ehci_device_intr_done(usbd_xfer_handle x | | | @@ -4029,35 +4024,34 @@ ehci_device_intr_done(usbd_xfer_handle x |
4029 | exfer->ex_sqtdend = dataend; | | 4024 | exfer->ex_sqtdend = dataend; |
4030 | KASSERT(exfer->ex_isdone); | | 4025 | KASSERT(exfer->ex_isdone); |
4031 | #ifdef DIAGNOSTIC | | 4026 | #ifdef DIAGNOSTIC |
4032 | exfer->ex_isdone = false; | | 4027 | exfer->ex_isdone = false; |
4033 | #endif | | 4028 | #endif |
4034 | | | 4029 | |
4035 | ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ | | 4030 | ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ |
4036 | if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { | | 4031 | if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { |
4037 | callout_reset(&xfer->ux_callout, | | 4032 | callout_reset(&xfer->ux_callout, |
4038 | mstohz(xfer->ux_timeout), ehci_timeout, xfer); | | 4033 | mstohz(xfer->ux_timeout), ehci_timeout, xfer); |
4039 | } | | 4034 | } |
4040 | | | 4035 | |
4041 | xfer->ux_status = USBD_IN_PROGRESS; | | 4036 | xfer->ux_status = USBD_IN_PROGRESS; |
4042 | } else if (xfer->ux_status != USBD_NOMEM && ehci_active_intr_list(ex)) { | | 4037 | } else if (xfer->ux_status != USBD_NOMEM && ehci_active_intr_list(exfer)) { |
4043 | ehci_del_intr_list(sc, ex); /* remove from active list */ | | 4038 | ehci_del_intr_list(sc, exfer); /* remove from active list */ |
4044 | ehci_free_sqtd_chain(sc, ex->ex_sqtdstart, NULL); | | 4039 | ehci_free_sqtd_chain(sc, exfer->ex_sqtdstart, NULL); |
4045 | endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; | | 4040 | endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; |
4046 | isread = UE_GET_DIR(endpt) == UE_DIR_IN; | | 4041 | isread = UE_GET_DIR(endpt) == UE_DIR_IN; |
4047 | usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, | | 4042 | usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, |
4048 | isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); | | 4043 | isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); |
4049 | } | | 4044 | } |
4050 | #undef exfer | | | |
4051 | } | | 4045 | } |
4052 | | | 4046 | |
4053 | /************************/ | | 4047 | /************************/ |
4054 | | | 4048 | |
4055 | Static usbd_status | | 4049 | Static usbd_status |
4056 | ehci_device_fs_isoc_transfer(usbd_xfer_handle xfer) | | 4050 | ehci_device_fs_isoc_transfer(usbd_xfer_handle xfer) |
4057 | { | | 4051 | { |
4058 | usbd_status err; | | 4052 | usbd_status err; |
4059 | | | 4053 | |
4060 | err = usb_insert_transfer(xfer); | | 4054 | err = usb_insert_transfer(xfer); |
4061 | if (err && err != USBD_IN_PROGRESS) | | 4055 | if (err && err != USBD_IN_PROGRESS) |
4062 | return err; | | 4056 | return err; |
4063 | | | 4057 | |