| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ehci.c,v 1.234.2.34 2015/03/01 08:26:55 skrll Exp $ */ | | 1 | /* $NetBSD: ehci.c,v 1.234.2.35 2015/03/02 21:52:02 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.34 2015/03/01 08:26:55 skrll Exp $"); | | 56 | __KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.234.2.35 2015/03/02 21:52:02 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> |
| @@ -1008,36 +1008,35 @@ ehci_idone(struct ehci_xfer *ex) | | | @@ -1008,36 +1008,35 @@ ehci_idone(struct ehci_xfer *ex) |
1008 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; | | 1008 | struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->ux_pipe; |
1009 | struct ehci_softc *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; | | 1009 | struct ehci_softc *sc = xfer->ux_pipe->up_dev->ud_bus->ub_hcpriv; |
1010 | ehci_soft_qtd_t *sqtd, *lsqtd; | | 1010 | ehci_soft_qtd_t *sqtd, *lsqtd; |
1011 | uint32_t status = 0, nstatus = 0; | | 1011 | uint32_t status = 0, nstatus = 0; |
1012 | int actlen; | | 1012 | int actlen; |
1013 | | | 1013 | |
1014 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); | | 1014 | USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); |
1015 | | | 1015 | |
1016 | KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); | | 1016 | KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); |
1017 | | | 1017 | |
1018 | USBHIST_LOG(ehcidebug, "ex=%p", ex, 0, 0, 0); | | 1018 | USBHIST_LOG(ehcidebug, "ex=%p", ex, 0, 0, 0); |
1019 | | | 1019 | |
1020 | #ifdef DIAGNOSTIC | | 1020 | #ifdef DIAGNOSTIC |
1021 | if (ex->ex_isdone) { | | | |
1022 | printf("ehci_idone: ex=%p is done!\n", ex); | | | |
1023 | #ifdef EHCI_DEBUG | | 1021 | #ifdef EHCI_DEBUG |
| | | 1022 | if (ex->ex_isdone) { |
1024 | USBHIST_LOGN(ehcidebug, 5, "--- dump start ---", 0, 0, 0, 0); | | 1023 | USBHIST_LOGN(ehcidebug, 5, "--- dump start ---", 0, 0, 0, 0); |
1025 | ehci_dump_exfer(ex); | | 1024 | ehci_dump_exfer(ex); |
1026 | USBHIST_LOGN(ehcidebug, 5, "--- dump end ---", 0, 0, 0, 0); | | 1025 | USBHIST_LOGN(ehcidebug, 5, "--- dump end ---", 0, 0, 0, 0); |
1027 | #endif | | | |
1028 | return; | | | |
1029 | } | | 1026 | } |
1030 | ex->ex_isdone = 1; | | 1027 | #endif |
| | | 1028 | KASSERT(!ex->ex_isdone); |
| | | 1029 | ex->ex_isdone = true; |
1031 | #endif | | 1030 | #endif |
1032 | | | 1031 | |
1033 | if (xfer->ux_status == USBD_CANCELLED || | | 1032 | if (xfer->ux_status == USBD_CANCELLED || |
1034 | xfer->ux_status == USBD_TIMEOUT) { | | 1033 | xfer->ux_status == USBD_TIMEOUT) { |
1035 | USBHIST_LOG(ehcidebug, "aborted xfer=%p", xfer, 0, 0, 0); | | 1034 | USBHIST_LOG(ehcidebug, "aborted xfer=%p", xfer, 0, 0, 0); |
1036 | return; | | 1035 | return; |
1037 | } | | 1036 | } |
1038 | | | 1037 | |
1039 | USBHIST_LOG(ehcidebug, "xfer=%p, pipe=%p ready", xfer, epipe, 0, 0); | | 1038 | USBHIST_LOG(ehcidebug, "xfer=%p, pipe=%p ready", xfer, epipe, 0, 0); |
1040 | #ifdef EHCI_DEBUG | | 1039 | #ifdef EHCI_DEBUG |
1041 | USBHIST_LOGN(ehcidebug, 5, "--- dump start ---", 0, 0, 0, 0); | | 1040 | USBHIST_LOGN(ehcidebug, 5, "--- dump start ---", 0, 0, 0, 0); |
1042 | ehci_dump_sqtds(ex->ex_sqtdstart); | | 1041 | ehci_dump_sqtds(ex->ex_sqtdstart); |
1043 | USBHIST_LOGN(ehcidebug, 5, "--- dump end ---", 0, 0, 0, 0); | | 1042 | USBHIST_LOGN(ehcidebug, 5, "--- dump end ---", 0, 0, 0, 0); |
| @@ -1509,47 +1508,42 @@ ehci_shutdown(device_t self, int flags) | | | @@ -1509,47 +1508,42 @@ ehci_shutdown(device_t self, int flags) |
1509 | return true; | | 1508 | return true; |
1510 | } | | 1509 | } |
1511 | | | 1510 | |
1512 | Static usbd_xfer_handle | | 1511 | Static usbd_xfer_handle |
1513 | ehci_allocx(struct usbd_bus *bus) | | 1512 | ehci_allocx(struct usbd_bus *bus) |
1514 | { | | 1513 | { |
1515 | struct ehci_softc *sc = bus->ub_hcpriv; | | 1514 | struct ehci_softc *sc = bus->ub_hcpriv; |
1516 | usbd_xfer_handle xfer; | | 1515 | usbd_xfer_handle xfer; |
1517 | | | 1516 | |
1518 | xfer = pool_cache_get(sc->sc_xferpool, PR_NOWAIT); | | 1517 | xfer = pool_cache_get(sc->sc_xferpool, PR_NOWAIT); |
1519 | if (xfer != NULL) { | | 1518 | if (xfer != NULL) { |
1520 | memset(xfer, 0, sizeof(struct ehci_xfer)); | | 1519 | memset(xfer, 0, sizeof(struct ehci_xfer)); |
1521 | #ifdef DIAGNOSTIC | | 1520 | #ifdef DIAGNOSTIC |
1522 | EXFER(xfer)->ex_isdone = 1; | | 1521 | EXFER(xfer)->ex_isdone = true; |
1523 | xfer->ux_state = XFER_BUSY; | | 1522 | xfer->ux_state = XFER_BUSY; |
1524 | #endif | | 1523 | #endif |
1525 | } | | 1524 | } |
1526 | return xfer; | | 1525 | return xfer; |
1527 | } | | 1526 | } |
1528 | | | 1527 | |
1529 | Static void | | 1528 | Static void |
1530 | ehci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) | | 1529 | ehci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) |
1531 | { | | 1530 | { |
1532 | struct ehci_softc *sc = bus->ub_hcpriv; | | 1531 | struct ehci_softc *sc = bus->ub_hcpriv; |
1533 | | | 1532 | |
| | | 1533 | KASSERT(xfer->ux_state == XFER_BUSY); |
| | | 1534 | KASSERT(EXFER(xfer)->ex_isdone); |
1534 | #ifdef DIAGNOSTIC | | 1535 | #ifdef DIAGNOSTIC |
1535 | if (xfer->ux_state != XFER_BUSY) { | | | |
1536 | printf("ehci_freex: xfer=%p not busy, 0x%08x\n", xfer, | | | |
1537 | xfer->ux_state); | | | |
1538 | } | | | |
1539 | xfer->ux_state = XFER_FREE; | | 1536 | xfer->ux_state = XFER_FREE; |
1540 | if (!EXFER(xfer)->ex_isdone) { | | | |
1541 | printf("ehci_freex: !isdone\n"); | | | |
1542 | } | | | |
1543 | #endif | | 1537 | #endif |
1544 | pool_cache_put(sc->sc_xferpool, xfer); | | 1538 | pool_cache_put(sc->sc_xferpool, xfer); |
1545 | } | | 1539 | } |
1546 | | | 1540 | |
1547 | Static void | | 1541 | Static void |
1548 | ehci_get_lock(struct usbd_bus *bus, kmutex_t **lock) | | 1542 | ehci_get_lock(struct usbd_bus *bus, kmutex_t **lock) |
1549 | { | | 1543 | { |
1550 | struct ehci_softc *sc = bus->ub_hcpriv; | | 1544 | struct ehci_softc *sc = bus->ub_hcpriv; |
1551 | | | 1545 | |
1552 | *lock = &sc->sc_lock; | | 1546 | *lock = &sc->sc_lock; |
1553 | } | | 1547 | } |
1554 | | | 1548 | |
1555 | Static void | | 1549 | Static void |
| @@ -3228,27 +3222,27 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u | | | @@ -3228,27 +3222,27 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u |
3228 | sqh->qh.qh_qtd.qtd_status = qhstatus; | | 3222 | sqh->qh.qh_qtd.qtd_status = qhstatus; |
3229 | usb_syncmem(&sqh->dma, | | 3223 | usb_syncmem(&sqh->dma, |
3230 | sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), | | 3224 | sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), |
3231 | sizeof(sqh->qh.qh_qtd.qtd_status), | | 3225 | sizeof(sqh->qh.qh_qtd.qtd_status), |
3232 | BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); | | 3226 | BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); |
3233 | } else { | | 3227 | } else { |
3234 | USBHIST_LOG(ehcidebug, "no hit", 0, 0, 0, 0); | | 3228 | USBHIST_LOG(ehcidebug, "no hit", 0, 0, 0, 0); |
3235 | } | | 3229 | } |
3236 | | | 3230 | |
3237 | /* | | 3231 | /* |
3238 | * Step 4: Execute callback. | | 3232 | * Step 4: Execute callback. |
3239 | */ | | 3233 | */ |
3240 | #ifdef DIAGNOSTIC | | 3234 | #ifdef DIAGNOSTIC |
3241 | exfer->ex_isdone = 1; | | 3235 | exfer->ex_isdone = true; |
3242 | #endif | | 3236 | #endif |
3243 | wake = xfer->ux_hcflags & UXFER_ABORTWAIT; | | 3237 | wake = xfer->ux_hcflags & UXFER_ABORTWAIT; |
3244 | xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); | | 3238 | xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); |
3245 | usb_transfer_complete(xfer); | | 3239 | usb_transfer_complete(xfer); |
3246 | if (wake) { | | 3240 | if (wake) { |
3247 | cv_broadcast(&xfer->ux_hccv); | | 3241 | cv_broadcast(&xfer->ux_hccv); |
3248 | } | | 3242 | } |
3249 | | | 3243 | |
3250 | KASSERT(mutex_owned(&sc->sc_lock)); | | 3244 | KASSERT(mutex_owned(&sc->sc_lock)); |
3251 | #undef exfer | | 3245 | #undef exfer |
3252 | } | | 3246 | } |
3253 | | | 3247 | |
3254 | Static void | | 3248 | Static void |
| @@ -3333,27 +3327,27 @@ ehci_abort_isoc_xfer(usbd_xfer_handle xf | | | @@ -3333,27 +3327,27 @@ ehci_abort_isoc_xfer(usbd_xfer_handle xf |
3333 | | | 3327 | |
3334 | usb_syncmem(&sitd->dma, | | 3328 | usb_syncmem(&sitd->dma, |
3335 | sitd->offs + offsetof(ehci_sitd_t, sitd_buffer), | | 3329 | sitd->offs + offsetof(ehci_sitd_t, sitd_buffer), |
3336 | sizeof(sitd->sitd.sitd_buffer), | | 3330 | sizeof(sitd->sitd.sitd_buffer), |
3337 | BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); | | 3331 | BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); |
3338 | } | | 3332 | } |
3339 | } | | 3333 | } |
3340 | | | 3334 | |
3341 | sc->sc_softwake = 1; | | 3335 | sc->sc_softwake = 1; |
3342 | usb_schedsoftintr(&sc->sc_bus); | | 3336 | usb_schedsoftintr(&sc->sc_bus); |
3343 | cv_wait(&sc->sc_softwake_cv, &sc->sc_lock); | | 3337 | cv_wait(&sc->sc_softwake_cv, &sc->sc_lock); |
3344 | | | 3338 | |
3345 | #ifdef DIAGNOSTIC | | 3339 | #ifdef DIAGNOSTIC |
3346 | exfer->ex_isdone = 1; | | 3340 | exfer->ex_isdone = true; |
3347 | #endif | | 3341 | #endif |
3348 | wake = xfer->ux_hcflags & UXFER_ABORTWAIT; | | 3342 | wake = xfer->ux_hcflags & UXFER_ABORTWAIT; |
3349 | xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); | | 3343 | xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); |
3350 | usb_transfer_complete(xfer); | | 3344 | usb_transfer_complete(xfer); |
3351 | if (wake) { | | 3345 | if (wake) { |
3352 | cv_broadcast(&xfer->ux_hccv); | | 3346 | cv_broadcast(&xfer->ux_hccv); |
3353 | } | | 3347 | } |
3354 | | | 3348 | |
3355 | done: | | 3349 | done: |
3356 | KASSERT(mutex_owned(&sc->sc_lock)); | | 3350 | KASSERT(mutex_owned(&sc->sc_lock)); |
3357 | return; | | 3351 | return; |
3358 | } | | 3352 | } |
3359 | | | 3353 | |
| @@ -3603,31 +3597,29 @@ ehci_device_request(usbd_xfer_handle xfe | | | @@ -3603,31 +3597,29 @@ ehci_device_request(usbd_xfer_handle xfe |
3603 | stat->xfer = xfer; | | 3597 | stat->xfer = xfer; |
3604 | stat->len = 0; | | 3598 | stat->len = 0; |
3605 | usb_syncmem(&stat->dma, stat->offs, sizeof(stat->qtd), | | 3599 | usb_syncmem(&stat->dma, stat->offs, sizeof(stat->qtd), |
3606 | BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); | | 3600 | BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); |
3607 | | | 3601 | |
3608 | #ifdef EHCI_DEBUG | | 3602 | #ifdef EHCI_DEBUG |
3609 | USBHIST_LOGN(ehcidebug, 5, "dump:", 0, 0, 0, 0); | | 3603 | USBHIST_LOGN(ehcidebug, 5, "dump:", 0, 0, 0, 0); |
3610 | ehci_dump_sqh(sqh); | | 3604 | ehci_dump_sqh(sqh); |
3611 | ehci_dump_sqtds(setup); | | 3605 | ehci_dump_sqtds(setup); |
3612 | #endif | | 3606 | #endif |
3613 | | | 3607 | |
3614 | exfer->ex_sqtdstart = setup; | | 3608 | exfer->ex_sqtdstart = setup; |
3615 | exfer->ex_sqtdend = stat; | | 3609 | exfer->ex_sqtdend = stat; |
| | | 3610 | KASSERT(exfer->ex_isdone); |
3616 | #ifdef DIAGNOSTIC | | 3611 | #ifdef DIAGNOSTIC |
3617 | if (!exfer->ex_isdone) { | | 3612 | exfer->ex_isdone = false; |
3618 | printf("ehci_device_request: not done, exfer=%p\n", exfer); | | | |
3619 | } | | | |
3620 | exfer->ex_isdone = 0; | | | |
3621 | #endif | | 3613 | #endif |
3622 | | | 3614 | |
3623 | /* Insert qTD in QH list. */ | | 3615 | /* Insert qTD in QH list. */ |
3624 | ehci_set_qh_qtd(sqh, setup); /* also does usb_syncmem(sqh) */ | | 3616 | ehci_set_qh_qtd(sqh, setup); /* also does usb_syncmem(sqh) */ |
3625 | if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { | | 3617 | if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { |
3626 | callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), | | 3618 | callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), |
3627 | ehci_timeout, xfer); | | 3619 | ehci_timeout, xfer); |
3628 | } | | 3620 | } |
3629 | ehci_add_intr_list(sc, exfer); | | 3621 | ehci_add_intr_list(sc, exfer); |
3630 | xfer->ux_status = USBD_IN_PROGRESS; | | 3622 | xfer->ux_status = USBD_IN_PROGRESS; |
3631 | mutex_exit(&sc->sc_lock); | | 3623 | mutex_exit(&sc->sc_lock); |
3632 | | | 3624 | |
3633 | #ifdef EHCI_DEBUG | | 3625 | #ifdef EHCI_DEBUG |
| @@ -3738,31 +3730,29 @@ ehci_device_bulk_start(usbd_xfer_handle | | | @@ -3738,31 +3730,29 @@ ehci_device_bulk_start(usbd_xfer_handle |
3738 | return err; | | 3730 | return err; |
3739 | } | | 3731 | } |
3740 | | | 3732 | |
3741 | #ifdef EHCI_DEBUG | | 3733 | #ifdef EHCI_DEBUG |
3742 | USBHIST_LOGN(ehcidebug, 5, "--- dump start ---", 0, 0, 0, 0); | | 3734 | USBHIST_LOGN(ehcidebug, 5, "--- dump start ---", 0, 0, 0, 0); |
3743 | ehci_dump_sqh(sqh); | | 3735 | ehci_dump_sqh(sqh); |
3744 | ehci_dump_sqtds(data); | | 3736 | ehci_dump_sqtds(data); |
3745 | USBHIST_LOGN(ehcidebug, 5, "--- dump end ---", 0, 0, 0, 0); | | 3737 | USBHIST_LOGN(ehcidebug, 5, "--- dump end ---", 0, 0, 0, 0); |
3746 | #endif | | 3738 | #endif |
3747 | | | 3739 | |
3748 | /* Set up interrupt info. */ | | 3740 | /* Set up interrupt info. */ |
3749 | exfer->ex_sqtdstart = data; | | 3741 | exfer->ex_sqtdstart = data; |
3750 | exfer->ex_sqtdend = dataend; | | 3742 | exfer->ex_sqtdend = dataend; |
| | | 3743 | KASSERT(exfer->ex_isdone); |
3751 | #ifdef DIAGNOSTIC | | 3744 | #ifdef DIAGNOSTIC |
3752 | if (!exfer->ex_isdone) { | | 3745 | exfer->ex_isdone = false; |
3753 | printf("ehci_device_bulk_start: not done, ex=%p\n", exfer); | | | |
3754 | } | | | |
3755 | exfer->ex_isdone = 0; | | | |
3756 | #endif | | 3746 | #endif |
3757 | | | 3747 | |
3758 | ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ | | 3748 | ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ |
3759 | if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { | | 3749 | if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { |
3760 | callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), | | 3750 | callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), |
3761 | ehci_timeout, xfer); | | 3751 | ehci_timeout, xfer); |
3762 | } | | 3752 | } |
3763 | ehci_add_intr_list(sc, exfer); | | 3753 | ehci_add_intr_list(sc, exfer); |
3764 | xfer->ux_status = USBD_IN_PROGRESS; | | 3754 | xfer->ux_status = USBD_IN_PROGRESS; |
3765 | mutex_exit(&sc->sc_lock); | | 3755 | mutex_exit(&sc->sc_lock); |
3766 | | | 3756 | |
3767 | #ifdef EHCI_DEBUG | | 3757 | #ifdef EHCI_DEBUG |
3768 | USBHIST_LOGN(ehcidebug, 5, "data(2)", 0, 0, 0, 0); | | 3758 | USBHIST_LOGN(ehcidebug, 5, "data(2)", 0, 0, 0, 0); |
| @@ -3926,31 +3916,29 @@ ehci_device_intr_start(usbd_xfer_handle | | | @@ -3926,31 +3916,29 @@ ehci_device_intr_start(usbd_xfer_handle |
3926 | return err; | | 3916 | return err; |
3927 | } | | 3917 | } |
3928 | | | 3918 | |
3929 | #ifdef EHCI_DEBUG | | 3919 | #ifdef EHCI_DEBUG |
3930 | USBHIST_LOGN(ehcidebug, 5, "--- dump start ---", 0, 0, 0, 0); | | 3920 | USBHIST_LOGN(ehcidebug, 5, "--- dump start ---", 0, 0, 0, 0); |
3931 | ehci_dump_sqh(sqh); | | 3921 | ehci_dump_sqh(sqh); |
3932 | ehci_dump_sqtds(data); | | 3922 | ehci_dump_sqtds(data); |
3933 | USBHIST_LOGN(ehcidebug, 5, "--- dump end ---", 0, 0, 0, 0); | | 3923 | USBHIST_LOGN(ehcidebug, 5, "--- dump end ---", 0, 0, 0, 0); |
3934 | #endif | | 3924 | #endif |
3935 | | | 3925 | |
3936 | /* Set up interrupt info. */ | | 3926 | /* Set up interrupt info. */ |
3937 | exfer->ex_sqtdstart = data; | | 3927 | exfer->ex_sqtdstart = data; |
3938 | exfer->ex_sqtdend = dataend; | | 3928 | exfer->ex_sqtdend = dataend; |
| | | 3929 | KASSERT(exfer->ex_isdone); |
3939 | #ifdef DIAGNOSTIC | | 3930 | #ifdef DIAGNOSTIC |
3940 | if (!exfer->ex_isdone) { | | 3931 | exfer->ex_isdone = false; |
3941 | printf("ehci_device_intr_start: not done, ex=%p\n", exfer); | | | |
3942 | } | | | |
3943 | exfer->ex_isdone = 0; | | | |
3944 | #endif | | 3932 | #endif |
3945 | | | 3933 | |
3946 | ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ | | 3934 | ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ |
3947 | if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { | | 3935 | if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { |
3948 | callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), | | 3936 | callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), |
3949 | ehci_timeout, xfer); | | 3937 | ehci_timeout, xfer); |
3950 | } | | 3938 | } |
3951 | ehci_add_intr_list(sc, exfer); | | 3939 | ehci_add_intr_list(sc, exfer); |
3952 | xfer->ux_status = USBD_IN_PROGRESS; | | 3940 | xfer->ux_status = USBD_IN_PROGRESS; |
3953 | mutex_exit(&sc->sc_lock); | | 3941 | mutex_exit(&sc->sc_lock); |
3954 | | | 3942 | |
3955 | #ifdef EHCI_DEBUG | | 3943 | #ifdef EHCI_DEBUG |
3956 | USBHIST_LOGN(ehcidebug, 5, "data(2)", 0, 0, 0, 0); | | 3944 | USBHIST_LOGN(ehcidebug, 5, "data(2)", 0, 0, 0, 0); |
| @@ -4029,34 +4017,29 @@ ehci_device_intr_done(usbd_xfer_handle x | | | @@ -4029,34 +4017,29 @@ ehci_device_intr_done(usbd_xfer_handle x |
4029 | sqh = epipe->sqh; | | 4017 | sqh = epipe->sqh; |
4030 | | | 4018 | |
4031 | err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, | | 4019 | err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, |
4032 | &data, &dataend); | | 4020 | &data, &dataend); |
4033 | if (err) { | | 4021 | if (err) { |
4034 | USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); | | 4022 | USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); |
4035 | xfer->ux_status = err; | | 4023 | xfer->ux_status = err; |
4036 | return; | | 4024 | return; |
4037 | } | | 4025 | } |
4038 | | | 4026 | |
4039 | /* Set up interrupt info. */ | | 4027 | /* Set up interrupt info. */ |
4040 | exfer->ex_sqtdstart = data; | | 4028 | exfer->ex_sqtdstart = data; |
4041 | exfer->ex_sqtdend = dataend; | | 4029 | exfer->ex_sqtdend = dataend; |
| | | 4030 | KASSERT(exfer->ex_isdone); |
4042 | #ifdef DIAGNOSTIC | | 4031 | #ifdef DIAGNOSTIC |
4043 | if (!exfer->ex_isdone) { | | 4032 | exfer->ex_isdone = false; |
4044 | USBHIST_LOG(ehcidebug, "marked not done, ex = %p", | | | |
4045 | exfer, 0, 0, 0); | | | |
4046 | printf("ehci_device_intr_done: not done, ex=%p\n", | | | |
4047 | exfer); | | | |
4048 | } | | | |
4049 | exfer->ex_isdone = 0; | | | |
4050 | #endif | | 4033 | #endif |
4051 | | | 4034 | |
4052 | ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ | | 4035 | ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ |
4053 | if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { | | 4036 | if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { |
4054 | callout_reset(&xfer->ux_callout, | | 4037 | callout_reset(&xfer->ux_callout, |
4055 | mstohz(xfer->ux_timeout), ehci_timeout, xfer); | | 4038 | mstohz(xfer->ux_timeout), ehci_timeout, xfer); |
4056 | } | | 4039 | } |
4057 | | | 4040 | |
4058 | xfer->ux_status = USBD_IN_PROGRESS; | | 4041 | xfer->ux_status = USBD_IN_PROGRESS; |
4059 | } else if (xfer->ux_status != USBD_NOMEM && ehci_active_intr_list(ex)) { | | 4042 | } else if (xfer->ux_status != USBD_NOMEM && ehci_active_intr_list(ex)) { |
4060 | ehci_del_intr_list(sc, ex); /* remove from active list */ | | 4043 | ehci_del_intr_list(sc, ex); /* remove from active list */ |
4061 | ehci_free_sqtd_chain(sc, ex->ex_sqtdstart, NULL); | | 4044 | ehci_free_sqtd_chain(sc, ex->ex_sqtdstart, NULL); |
4062 | endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; | | 4045 | endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; |
| @@ -4125,31 +4108,30 @@ ehci_device_fs_isoc_start(usbd_xfer_hand | | | @@ -4125,31 +4108,30 @@ ehci_device_fs_isoc_start(usbd_xfer_hand |
4125 | /* | | 4108 | /* |
4126 | * To avoid complication, don't allow a request right now that'll span | | 4109 | * To avoid complication, don't allow a request right now that'll span |
4127 | * the entire frame table. To within 4 frames, to allow some leeway | | 4110 | * the entire frame table. To within 4 frames, to allow some leeway |
4128 | * on either side of where the hc currently is. | | 4111 | * on either side of where the hc currently is. |
4129 | */ | | 4112 | */ |
4130 | if (epipe->pipe.up_endpoint->ue_edesc->bInterval * | | 4113 | if (epipe->pipe.up_endpoint->ue_edesc->bInterval * |
4131 | xfer->ux_nframes >= sc->sc_flsize - 4) { | | 4114 | xfer->ux_nframes >= sc->sc_flsize - 4) { |
4132 | printf("ehci: isoc descriptor requested that spans the entire" | | 4115 | printf("ehci: isoc descriptor requested that spans the entire" |
4133 | "frametable, too many frames\n"); | | 4116 | "frametable, too many frames\n"); |
4134 | return USBD_INVAL; | | 4117 | return USBD_INVAL; |
4135 | } | | 4118 | } |
4136 | | | 4119 | |
4137 | KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); | | 4120 | KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); |
| | | 4121 | KASSERT(exfer->ex_isdone); |
4138 | | | 4122 | |
4139 | #ifdef DIAGNOSTIC | | 4123 | #ifdef DIAGNOSTIC |
4140 | if (!exfer->ex_isdone) | | 4124 | exfer->ex_isdone = false; |
4141 | printf("ehci_device_fs_isoc_start: not done, ex = %p\n", exfer); | | | |
4142 | exfer->ex_isdone = 0; | | | |
4143 | #endif | | 4125 | #endif |
4144 | | | 4126 | |
4145 | /* | | 4127 | /* |
4146 | * Step 1: Allocate and initialize sitds. | | 4128 | * Step 1: Allocate and initialize sitds. |
4147 | */ | | 4129 | */ |
4148 | | | 4130 | |
4149 | i = epipe->pipe.up_endpoint->ue_edesc->bInterval; | | 4131 | i = epipe->pipe.up_endpoint->ue_edesc->bInterval; |
4150 | if (i > 16 || i == 0) { | | 4132 | if (i > 16 || i == 0) { |
4151 | /* Spec page 271 says intervals > 16 are invalid */ | | 4133 | /* Spec page 271 says intervals > 16 are invalid */ |
4152 | USBHIST_LOG(ehcidebug, "bInterval %d invalid", 0, 0, 0, 0); | | 4134 | USBHIST_LOG(ehcidebug, "bInterval %d invalid", 0, 0, 0, 0); |
4153 | | | 4135 | |
4154 | return USBD_INVAL; | | 4136 | return USBD_INVAL; |
4155 | } | | 4137 | } |
| @@ -4442,34 +4424,29 @@ ehci_device_isoc_start(usbd_xfer_handle | | | @@ -4442,34 +4424,29 @@ ehci_device_isoc_start(usbd_xfer_handle |
4442 | * To avoid complication, don't allow a request right now that'll span | | 4424 | * To avoid complication, don't allow a request right now that'll span |
4443 | * the entire frame table. To within 4 frames, to allow some leeway | | 4425 | * the entire frame table. To within 4 frames, to allow some leeway |
4444 | * on either side of where the hc currently is. | | 4426 | * on either side of where the hc currently is. |
4445 | */ | | 4427 | */ |
4446 | if ((1 << (epipe->pipe.up_endpoint->ue_edesc->bInterval)) * | | 4428 | if ((1 << (epipe->pipe.up_endpoint->ue_edesc->bInterval)) * |
4447 | xfer->ux_nframes >= (sc->sc_flsize - 4) * 8) { | | 4429 | xfer->ux_nframes >= (sc->sc_flsize - 4) * 8) { |
4448 | USBHIST_LOG(ehcidebug, | | 4430 | USBHIST_LOG(ehcidebug, |
4449 | "isoc descriptor spans entire frametable", 0, 0, 0, 0); | | 4431 | "isoc descriptor spans entire frametable", 0, 0, 0, 0); |
4450 | printf("ehci: isoc descriptor requested that spans the entire frametable, too many frames\n"); | | 4432 | printf("ehci: isoc descriptor requested that spans the entire frametable, too many frames\n"); |
4451 | return USBD_INVAL; | | 4433 | return USBD_INVAL; |
4452 | } | | 4434 | } |
4453 | | | 4435 | |
4454 | KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); | | 4436 | KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); |
4455 | | | 4437 | KASSERT(exfer->ex_isdone); |
4456 | #ifdef DIAGNOSTIC | | 4438 | #ifdef DIAGNOSTIC |
4457 | if (!exfer->ex_isdone) { | | 4439 | exfer->ex_isdone = false; |
4458 | USBHIST_LOG(ehcidebug, "marked not done, ex = %p", exfer, | | | |
4459 | 0, 0, 0); | | | |
4460 | printf("ehci_device_isoc_start: not done, ex = %p\n", exfer); | | | |
4461 | } | | | |
4462 | exfer->ex_isdone = 0; | | | |
4463 | #endif | | 4440 | #endif |
4464 | | | 4441 | |
4465 | /* | | 4442 | /* |
4466 | * Step 1: Allocate and initialize itds, how many do we need? | | 4443 | * Step 1: Allocate and initialize itds, how many do we need? |
4467 | * One per transfer if interval >= 8 microframes, fewer if we use | | 4444 | * One per transfer if interval >= 8 microframes, fewer if we use |
4468 | * multiple microframes per frame. | | 4445 | * multiple microframes per frame. |
4469 | */ | | 4446 | */ |
4470 | | | 4447 | |
4471 | i = epipe->pipe.up_endpoint->ue_edesc->bInterval; | | 4448 | i = epipe->pipe.up_endpoint->ue_edesc->bInterval; |
4472 | if (i > 16 || i == 0) { | | 4449 | if (i > 16 || i == 0) { |
4473 | /* Spec page 271 says intervals > 16 are invalid */ | | 4450 | /* Spec page 271 says intervals > 16 are invalid */ |
4474 | USBHIST_LOG(ehcidebug, "bInterval %d invalid", i, 0, 0, 0); | | 4451 | USBHIST_LOG(ehcidebug, "bInterval %d invalid", i, 0, 0, 0); |
4475 | return USBD_INVAL; | | 4452 | return USBD_INVAL; |