Sat Aug 25 14:57:35 2018 UTC ()
Pull up following revision(s) (requested by mrg in ticket #1632):

	sys/dev/usb/usbdivar.h: revision 1.117
	sys/external/bsd/dwc2/dwc2.c: revision 1.52
	sys/dev/usb/xhcivar.h: revision 1.10
	sys/dev/usb/motg.c: revision 1.22
	sys/dev/usb/ehci.c: revision 1.260
	sys/dev/usb/ehci.c: revision 1.261
	sys/dev/usb/xhci.c: revision 1.96
	sys/dev/usb/ohci.c: revision 1.282
	sys/dev/usb/ohci.c: revision 1.283
	sys/dev/usb/ehcivar.h: revision 1.45
	sys/dev/usb/uhci.c: revision 1.281
	sys/dev/usb/uhci.c: revision 1.282
	sys/dev/usb/usbdi.c: revision 1.177
	sys/dev/usb/ohcivar.h: revision 1.60
	sys/dev/usb/uhcivar.h: revision 1.55
	(all via patch)

pull across abort fixes from nick-nhusb.  add more abort fixes, using
ideas from Taylor and Nick, and myself.  special thanks to both who
inspired much of the code here, if not wrote it directly.

among other problems, this assert should no longer trigger:

   panic: kernel diagnostic assertion "xfer->ux_state == XFER_ONQU" failed: file "/current/src/sys/dev/usb/usbdi.c", line 914

using usbhist i was able to track down my instance of it being related
to userland close() beginning, dropping the sc_lock, and then the usb
softintr completes the transfer normally, and when it is done, the
abort path attempts to re-complete the transfer, and the above assert
is tripped.

changes from nhusb were commited with these logs:
--
Move the struct usb_task to struct usbd_xfer for everyone to use.
--
Set device transfer status to USBD_IN_PROGRESS if start methods succeeds
--
Actually set the transfer status on transfers in ohci_abort_xfer and
the controller is dying
--
Don't supply the lock to callout_halt when polling as it won't be held
--
Improve transfer abort
--
Mark device transfers as USBD_IN_PROGRESS appropriately and improve
abort handling
--
--
Mark device transfers as USBD_IN_PROGRESS appropriately and improve
abort handling
--

additional changes include:
- initialise the usb abort task in the HCI allocx routine, so that it
  can be safely usb_rem_task()'d.
- rework the handling of softintr vs cancellation vs timeout abort based
  upon a scheme from Taylor:
  when completing a transfer normally:
  - if the status is not in progress, it must be cancelled or timed out,
    and we should not process this xfer.
  - set the status as normal.
  - unconditionallly callout_stop() and usb_rem_task().  they're safe and
    either aren't running, or will run and do nothing.
  - finally call usb_transfer_complete().
  when aborting a transfer:
  - status should be cancelled or timed out.
  - if cancelling, callout_halt and usb_rem_task_wait() to make sure the
    timer is either done or cancelled.
  - at this point, the ux_status must not be cancelled or timed out, and
    if it is not in progress we're done.
  - set the status.
  - if the controller is dying, just return.
  - perform HCI-specific tasks to abort this xfer.
  - finally call usb_transfer_complete().
  for the timeout and timeout task:
  - if the HCI is not dying, and the ux_status is in progress, then
    trigger the usb abort task.
- remove UXFER_ABORTWAIT and UXFER_ABORTING.

tested on:
- multiple PC systems with several types of devices: ugen/UPS, ucom,
  umass with disk, ssd and cdrom backends, kbd, ms, using uhci, ehci
  and xhci.
- erlite3: sd@umass on dwc2.
- sunblade2000: kbd/ms and umass disk on ohci.

untested:
- motg, slhci and ahci.  motg has some portion of the new scheme
  applied, but slhci and ahci require more study.

future work includes pushing a lot of the common abort handling into
usbdi.c and leaving upm_abort() for HC specific tasks, but this change
is pullup-able to netbsd-7 and netbsd-8 as it does not change any
external API, as well as removing over 100 lines of code while adding
over 30 new asserts.

XXX: pullup-7, pullup-8.

fix DIAGNOSTIC build by not copying ub_usepolling to stack before use

Sprinkle __diagused


(martin)
diff -r1.228.2.2 -r1.228.2.3 src/sys/dev/usb/ehci.c
diff -r1.42.12.1 -r1.42.12.2 src/sys/dev/usb/ehcivar.h
diff -r1.6.4.4 -r1.6.4.5 src/sys/dev/usb/motg.c
diff -r1.253.2.4 -r1.253.2.5 src/sys/dev/usb/ohci.c
diff -r1.55.4.1 -r1.55.4.2 src/sys/dev/usb/ohcivar.h
diff -r1.264.2.3 -r1.264.2.4 src/sys/dev/usb/uhci.c
diff -r1.52.12.1 -r1.52.12.2 src/sys/dev/usb/uhcivar.h
diff -r1.161.2.2 -r1.161.2.3 src/sys/dev/usb/usbdi.c
diff -r1.107.4.2 -r1.107.4.3 src/sys/dev/usb/usbdivar.h
diff -r1.23.2.7 -r1.23.2.8 src/sys/dev/usb/xhci.c
diff -r1.4.8.1 -r1.4.8.2 src/sys/dev/usb/xhcivar.h
diff -r1.31.2.3 -r1.31.2.4 src/sys/external/bsd/dwc2/dwc2.c

cvs diff -r1.228.2.2 -r1.228.2.3 src/sys/dev/usb/ehci.c (expand / switch to unified diff)

--- src/sys/dev/usb/ehci.c 2018/01/03 20:02:37 1.228.2.2
+++ src/sys/dev/usb/ehci.c 2018/08/25 14:57:35 1.228.2.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ehci.c,v 1.228.2.2 2018/01/03 20:02:37 snj Exp $ */ 1/* $NetBSD: ehci.c,v 1.228.2.3 2018/08/25 14:57:35 martin 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.228.2.2 2018/01/03 20:02:37 snj Exp $"); 56__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.228.2.3 2018/08/25 14:57:35 martin Exp $");
57 57
58#include "ohci.h" 58#include "ohci.h"
59#include "uhci.h" 59#include "uhci.h"
60 60
61#ifdef _KERNEL_OPT 61#ifdef _KERNEL_OPT
62#include "opt_usb.h" 62#include "opt_usb.h"
63#endif 63#endif
64 64
65#include <sys/param.h> 65#include <sys/param.h>
66 66
67#include <sys/bus.h> 67#include <sys/bus.h>
68#include <sys/cpu.h> 68#include <sys/cpu.h>
69#include <sys/device.h> 69#include <sys/device.h>
@@ -402,28 +402,27 @@ ehci_init(ehci_softc_t *sc) @@ -402,28 +402,27 @@ ehci_init(ehci_softc_t *sc)
402 uint32_t vers, sparams, cparams, hcr; 402 uint32_t vers, sparams, cparams, hcr;
403 u_int i; 403 u_int i;
404 usbd_status err; 404 usbd_status err;
405 ehci_soft_qh_t *sqh; 405 ehci_soft_qh_t *sqh;
406 u_int ncomp; 406 u_int ncomp;
407 407
408 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 408 EHCIHIST_FUNC(); EHCIHIST_CALLED();
409#ifdef EHCI_DEBUG 409#ifdef EHCI_DEBUG
410 theehci = sc; 410 theehci = sc;
411#endif 411#endif
412 412
413 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 413 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
414 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB); 414 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
415 cv_init(&sc->sc_softwake_cv, "ehciab"); 415 cv_init(&sc->sc_doorbell, "ehcidb");
416 cv_init(&sc->sc_doorbell, "ehcidi"); 
417 416
418 sc->sc_xferpool = pool_cache_init(sizeof(struct ehci_xfer), 0, 0, 0, 417 sc->sc_xferpool = pool_cache_init(sizeof(struct ehci_xfer), 0, 0, 0,
419 "ehcixfer", NULL, IPL_USB, NULL, NULL, NULL); 418 "ehcixfer", NULL, IPL_USB, NULL, NULL, NULL);
420 419
421 sc->sc_doorbell_si = softint_establish(SOFTINT_USB | SOFTINT_MPSAFE, 420 sc->sc_doorbell_si = softint_establish(SOFTINT_USB | SOFTINT_MPSAFE,
422 ehci_doorbell, sc); 421 ehci_doorbell, sc);
423 KASSERT(sc->sc_doorbell_si != NULL); 422 KASSERT(sc->sc_doorbell_si != NULL);
424 sc->sc_pcd_si = softint_establish(SOFTINT_USB | SOFTINT_MPSAFE, 423 sc->sc_pcd_si = softint_establish(SOFTINT_USB | SOFTINT_MPSAFE,
425 ehci_pcd, sc); 424 ehci_pcd, sc);
426 KASSERT(sc->sc_pcd_si != NULL); 425 KASSERT(sc->sc_pcd_si != NULL);
427 426
428 sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH); 427 sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
429 428
@@ -741,26 +740,27 @@ ehci_intr1(ehci_softc_t *sc) @@ -741,26 +740,27 @@ ehci_intr1(ehci_softc_t *sc)
741 sc->sc_eintrs &= ~eintrs; 740 sc->sc_eintrs &= ~eintrs;
742 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); 741 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
743 printf("%s: blocking intrs 0x%x\n", 742 printf("%s: blocking intrs 0x%x\n",
744 device_xname(sc->sc_dev), eintrs); 743 device_xname(sc->sc_dev), eintrs);
745 } 744 }
746 745
747 return 1; 746 return 1;
748} 747}
749 748
750Static void 749Static void
751ehci_doorbell(void *addr) 750ehci_doorbell(void *addr)
752{ 751{
753 ehci_softc_t *sc = addr; 752 ehci_softc_t *sc = addr;
 753 EHCIHIST_FUNC(); EHCIHIST_CALLED();
754 754
755 mutex_enter(&sc->sc_lock); 755 mutex_enter(&sc->sc_lock);
756 cv_broadcast(&sc->sc_doorbell); 756 cv_broadcast(&sc->sc_doorbell);
757 mutex_exit(&sc->sc_lock); 757 mutex_exit(&sc->sc_lock);
758} 758}
759 759
760Static void 760Static void
761ehci_pcd(void *addr) 761ehci_pcd(void *addr)
762{ 762{
763 ehci_softc_t *sc = addr; 763 ehci_softc_t *sc = addr;
764 struct usbd_xfer *xfer; 764 struct usbd_xfer *xfer;
765 u_char *p; 765 u_char *p;
766 int i, m; 766 int i, m;
@@ -843,31 +843,26 @@ ehci_softintr(void *v) @@ -843,31 +843,26 @@ ehci_softintr(void *v)
843 * We abuse ex_next for the interrupt and complete lists and 843 * We abuse ex_next for the interrupt and complete lists and
844 * interrupt transfers will get re-added here so use 844 * interrupt transfers will get re-added here so use
845 * the _SAFE version of TAILQ_FOREACH. 845 * the _SAFE version of TAILQ_FOREACH.
846 */ 846 */
847 TAILQ_FOREACH_SAFE(ex, &cq, ex_next, nextex) { 847 TAILQ_FOREACH_SAFE(ex, &cq, ex_next, nextex) {
848 usb_transfer_complete(&ex->ex_xfer); 848 usb_transfer_complete(&ex->ex_xfer);
849 } 849 }
850 850
851 /* Schedule a callout to catch any dropped transactions. */ 851 /* Schedule a callout to catch any dropped transactions. */
852 if ((sc->sc_flags & EHCIF_DROPPED_INTR_WORKAROUND) && 852 if ((sc->sc_flags & EHCIF_DROPPED_INTR_WORKAROUND) &&
853 !TAILQ_EMPTY(&sc->sc_intrhead)) 853 !TAILQ_EMPTY(&sc->sc_intrhead))
854 callout_reset(&sc->sc_tmo_intrlist, 854 callout_reset(&sc->sc_tmo_intrlist,
855 hz, ehci_intrlist_timeout, sc); 855 hz, ehci_intrlist_timeout, sc);
856 
857 if (sc->sc_softwake) { 
858 sc->sc_softwake = 0; 
859 cv_broadcast(&sc->sc_softwake_cv); 
860 } 
861} 856}
862 857
863Static void 858Static void
864ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) 859ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq)
865{ 860{
866 ehci_soft_qtd_t *sqtd, *fsqtd, *lsqtd; 861 ehci_soft_qtd_t *sqtd, *fsqtd, *lsqtd;
867 uint32_t status; 862 uint32_t status;
868 863
869 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 864 EHCIHIST_FUNC(); EHCIHIST_CALLED();
870 865
871 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 866 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
872 867
873 if (ex->ex_type == EX_CTRL) { 868 if (ex->ex_type == EX_CTRL) {
@@ -929,27 +924,26 @@ ehci_check_qh_intr(ehci_softc_t *sc, str @@ -929,27 +924,26 @@ ehci_check_qh_intr(ehci_softc_t *sc, str
929 } 924 }
930 } 925 }
931 DPRINTFN(10, "ex=%p std=%p still active", ex, ex->ex_sqtdstart, 926 DPRINTFN(10, "ex=%p std=%p still active", ex, ex->ex_sqtdstart,
932 0, 0); 927 0, 0);
933#ifdef EHCI_DEBUG 928#ifdef EHCI_DEBUG
934 DPRINTFN(5, "--- still active start ---", 0, 0, 0, 0); 929 DPRINTFN(5, "--- still active start ---", 0, 0, 0, 0);
935 ehci_dump_sqtds(ex->ex_sqtdstart); 930 ehci_dump_sqtds(ex->ex_sqtdstart);
936 DPRINTFN(5, "--- still active end ---", 0, 0, 0, 0); 931 DPRINTFN(5, "--- still active end ---", 0, 0, 0, 0);
937#endif 932#endif
938 return; 933 return;
939 } 934 }
940 done: 935 done:
941 DPRINTFN(10, "ex=%p done", ex, 0, 0, 0); 936 DPRINTFN(10, "ex=%p done", ex, 0, 0, 0);
942 callout_stop(&ex->ex_xfer.ux_callout); 
943 ehci_idone(ex, cq); 937 ehci_idone(ex, cq);
944} 938}
945 939
946Static void 940Static void
947ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) 941ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq)
948{ 942{
949 ehci_soft_itd_t *itd; 943 ehci_soft_itd_t *itd;
950 int i; 944 int i;
951 945
952 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 946 EHCIHIST_FUNC(); EHCIHIST_CALLED();
953 947
954 KASSERT(mutex_owned(&sc->sc_lock)); 948 KASSERT(mutex_owned(&sc->sc_lock));
955 949
@@ -975,27 +969,26 @@ ehci_check_itd_intr(ehci_softc_t *sc, st @@ -975,27 +969,26 @@ ehci_check_itd_intr(ehci_softc_t *sc, st
975 } 969 }
976 970
977 if (i == EHCI_ITD_NUFRAMES) { 971 if (i == EHCI_ITD_NUFRAMES) {
978 goto done; /* All 8 descriptors inactive, it's done */ 972 goto done; /* All 8 descriptors inactive, it's done */
979 } 973 }
980 974
981 usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_ctl), 975 usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_ctl),
982 sizeof(itd->itd.itd_ctl), BUS_DMASYNC_PREREAD); 976 sizeof(itd->itd.itd_ctl), BUS_DMASYNC_PREREAD);
983 977
984 DPRINTFN(10, "ex %p itd %p still active", ex, ex->ex_itdstart, 0, 0); 978 DPRINTFN(10, "ex %p itd %p still active", ex, ex->ex_itdstart, 0, 0);
985 return; 979 return;
986done: 980done:
987 DPRINTF("ex %p done", ex, 0, 0, 0); 981 DPRINTF("ex %p done", ex, 0, 0, 0);
988 callout_stop(&ex->ex_xfer.ux_callout); 
989 ehci_idone(ex, cq); 982 ehci_idone(ex, cq);
990} 983}
991 984
992void 985void
993ehci_check_sitd_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) 986ehci_check_sitd_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq)
994{ 987{
995 ehci_soft_sitd_t *sitd; 988 ehci_soft_sitd_t *sitd;
996 989
997 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 990 EHCIHIST_FUNC(); EHCIHIST_CALLED();
998 991
999 KASSERT(mutex_owned(&sc->sc_lock)); 992 KASSERT(mutex_owned(&sc->sc_lock));
1000 993
1001 if (&ex->ex_xfer != SIMPLEQ_FIRST(&ex->ex_xfer.ux_pipe->up_queue)) 994 if (&ex->ex_xfer != SIMPLEQ_FIRST(&ex->ex_xfer.ux_pipe->up_queue))
@@ -1013,53 +1006,65 @@ ehci_check_sitd_intr(ehci_softc_t *sc, s @@ -1013,53 +1006,65 @@ ehci_check_sitd_intr(ehci_softc_t *sc, s
1013 usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans), 1006 usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans),
1014 sizeof(sitd->sitd.sitd_trans), 1007 sizeof(sitd->sitd.sitd_trans),
1015 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1008 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1016 1009
1017 bool active = ((le32toh(sitd->sitd.sitd_trans) & EHCI_SITD_ACTIVE) != 0); 1010 bool active = ((le32toh(sitd->sitd.sitd_trans) & EHCI_SITD_ACTIVE) != 0);
1018 1011
1019 usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans), 1012 usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans),
1020 sizeof(sitd->sitd.sitd_trans), BUS_DMASYNC_PREREAD); 1013 sizeof(sitd->sitd.sitd_trans), BUS_DMASYNC_PREREAD);
1021 1014
1022 if (active) 1015 if (active)
1023 return; 1016 return;
1024 1017
1025 DPRINTFN(10, "ex=%p done", ex, 0, 0, 0); 1018 DPRINTFN(10, "ex=%p done", ex, 0, 0, 0);
1026 callout_stop(&(ex->ex_xfer.ux_callout)); 
1027 ehci_idone(ex, cq); 1019 ehci_idone(ex, cq);
1028} 1020}
1029 1021
1030 1022
1031Static void 1023Static void
1032ehci_idone(struct ehci_xfer *ex, ex_completeq_t *cq) 1024ehci_idone(struct ehci_xfer *ex, ex_completeq_t *cq)
1033{ 1025{
 1026 EHCIHIST_FUNC(); EHCIHIST_CALLED();
1034 struct usbd_xfer *xfer = &ex->ex_xfer; 1027 struct usbd_xfer *xfer = &ex->ex_xfer;
1035 struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); 1028 struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer);
1036 struct ehci_softc *sc = EHCI_XFER2SC(xfer); 1029 struct ehci_softc *sc = EHCI_XFER2SC(xfer);
1037 ehci_soft_qtd_t *sqtd, *fsqtd, *lsqtd; 1030 ehci_soft_qtd_t *sqtd, *fsqtd, *lsqtd;
1038 uint32_t status = 0, nstatus = 0; 1031 uint32_t status = 0, nstatus = 0;
1039 int actlen = 0; 1032 int actlen = 0;
1040 1033
1041 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 
1042 
1043 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1034 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1044 1035
1045 DPRINTF("ex=%p", ex, 0, 0, 0); 1036 DPRINTF("ex=%p", ex, 0, 0, 0);
1046 1037
1047 if (xfer->ux_status == USBD_CANCELLED || 1038 /*
1048 xfer->ux_status == USBD_TIMEOUT) { 1039 * If software has completed it, either by cancellation
 1040 * or timeout, drop it on the floor.
 1041 */
 1042 if (xfer->ux_status != USBD_IN_PROGRESS) {
 1043 KASSERT(xfer->ux_status == USBD_CANCELLED ||
 1044 xfer->ux_status == USBD_TIMEOUT);
1049 DPRINTF("aborted xfer=%p", xfer, 0, 0, 0); 1045 DPRINTF("aborted xfer=%p", xfer, 0, 0, 0);
1050 return; 1046 return;
1051 } 1047 }
1052 1048
 1049 /*
 1050 * Cancel the timeout and the task, which have not yet
 1051 * run. If they have already fired, at worst they are
 1052 * waiting for the lock. They will see that the xfer
 1053 * is no longer in progress and give up.
 1054 */
 1055 callout_stop(&xfer->ux_callout);
 1056 usb_rem_task(xfer->ux_pipe->up_dev, &xfer->ux_aborttask);
 1057
1053#ifdef DIAGNOSTIC 1058#ifdef DIAGNOSTIC
1054#ifdef EHCI_DEBUG 1059#ifdef EHCI_DEBUG
1055 if (ex->ex_isdone) { 1060 if (ex->ex_isdone) {
1056 DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); 1061 DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0);
1057 ehci_dump_exfer(ex); 1062 ehci_dump_exfer(ex);
1058 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); 1063 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0);
1059 } 1064 }
1060#endif 1065#endif
1061 KASSERTMSG(!ex->ex_isdone, "xfer %p type %d status %d", xfer, 1066 KASSERTMSG(!ex->ex_isdone, "xfer %p type %d status %d", xfer,
1062 ex->ex_type, xfer->ux_status); 1067 ex->ex_type, xfer->ux_status);
1063 ex->ex_isdone = true; 1068 ex->ex_isdone = true;
1064#endif 1069#endif
1065 1070
@@ -1322,27 +1327,26 @@ ehci_detach(struct ehci_softc *sc, int f @@ -1322,27 +1327,26 @@ ehci_detach(struct ehci_softc *sc, int f
1322 rv = config_detach(sc->sc_child, flags); 1327 rv = config_detach(sc->sc_child, flags);
1323 1328
1324 if (rv != 0) 1329 if (rv != 0)
1325 return rv; 1330 return rv;
1326 1331
1327 callout_halt(&sc->sc_tmo_intrlist, NULL); 1332 callout_halt(&sc->sc_tmo_intrlist, NULL);
1328 callout_destroy(&sc->sc_tmo_intrlist); 1333 callout_destroy(&sc->sc_tmo_intrlist);
1329 1334
1330 /* XXX free other data structures XXX */ 1335 /* XXX free other data structures XXX */
1331 if (sc->sc_softitds) 1336 if (sc->sc_softitds)
1332 kmem_free(sc->sc_softitds, 1337 kmem_free(sc->sc_softitds,
1333 sc->sc_flsize * sizeof(ehci_soft_itd_t *)); 1338 sc->sc_flsize * sizeof(ehci_soft_itd_t *));
1334 cv_destroy(&sc->sc_doorbell); 1339 cv_destroy(&sc->sc_doorbell);
1335 cv_destroy(&sc->sc_softwake_cv); 
1336 1340
1337#if 0 1341#if 0
1338 /* XXX destroyed in ehci_pci.c as it controls ehci_intr access */ 1342 /* XXX destroyed in ehci_pci.c as it controls ehci_intr access */
1339 1343
1340 softint_disestablish(sc->sc_doorbell_si); 1344 softint_disestablish(sc->sc_doorbell_si);
1341 softint_disestablish(sc->sc_pcd_si); 1345 softint_disestablish(sc->sc_pcd_si);
1342 1346
1343 mutex_destroy(&sc->sc_lock); 1347 mutex_destroy(&sc->sc_lock);
1344 mutex_destroy(&sc->sc_intr_lock); 1348 mutex_destroy(&sc->sc_intr_lock);
1345#endif 1349#endif
1346 1350
1347 pool_cache_destroy(sc->sc_xferpool); 1351 pool_cache_destroy(sc->sc_xferpool);
1348 1352
@@ -1501,26 +1505,30 @@ ehci_shutdown(device_t self, int flags) @@ -1501,26 +1505,30 @@ ehci_shutdown(device_t self, int flags)
1501 EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET); 1505 EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
1502 return true; 1506 return true;
1503} 1507}
1504 1508
1505Static struct usbd_xfer * 1509Static struct usbd_xfer *
1506ehci_allocx(struct usbd_bus *bus, unsigned int nframes) 1510ehci_allocx(struct usbd_bus *bus, unsigned int nframes)
1507{ 1511{
1508 struct ehci_softc *sc = EHCI_BUS2SC(bus); 1512 struct ehci_softc *sc = EHCI_BUS2SC(bus);
1509 struct usbd_xfer *xfer; 1513 struct usbd_xfer *xfer;
1510 1514
1511 xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK); 1515 xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK);
1512 if (xfer != NULL) { 1516 if (xfer != NULL) {
1513 memset(xfer, 0, sizeof(struct ehci_xfer)); 1517 memset(xfer, 0, sizeof(struct ehci_xfer));
 1518
 1519 /* Initialise this always so we can call remove on it. */
 1520 usb_init_task(&xfer->ux_aborttask, ehci_timeout_task, xfer,
 1521 USB_TASKQ_MPSAFE);
1514#ifdef DIAGNOSTIC 1522#ifdef DIAGNOSTIC
1515 struct ehci_xfer *ex = EHCI_XFER2EXFER(xfer); 1523 struct ehci_xfer *ex = EHCI_XFER2EXFER(xfer);
1516 ex->ex_isdone = true; 1524 ex->ex_isdone = true;
1517 xfer->ux_state = XFER_BUSY; 1525 xfer->ux_state = XFER_BUSY;
1518#endif 1526#endif
1519 } 1527 }
1520 return xfer; 1528 return xfer;
1521} 1529}
1522 1530
1523Static void 1531Static void
1524ehci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) 1532ehci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
1525{ 1533{
1526 struct ehci_softc *sc = EHCI_BUS2SC(bus); 1534 struct ehci_softc *sc = EHCI_BUS2SC(bus);
@@ -2148,26 +2156,27 @@ ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehc @@ -2148,26 +2156,27 @@ ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehc
2148Static void 2156Static void
2149ehci_sync_hc(ehci_softc_t *sc) 2157ehci_sync_hc(ehci_softc_t *sc)
2150{ 2158{
2151 int error __diagused; 2159 int error __diagused;
2152 2160
2153 KASSERT(mutex_owned(&sc->sc_lock)); 2161 KASSERT(mutex_owned(&sc->sc_lock));
2154 2162
2155 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 2163 EHCIHIST_FUNC(); EHCIHIST_CALLED();
2156 2164
2157 if (sc->sc_dying) { 2165 if (sc->sc_dying) {
2158 DPRINTF("dying", 0, 0, 0, 0); 2166 DPRINTF("dying", 0, 0, 0, 0);
2159 return; 2167 return;
2160 } 2168 }
 2169
2161 /* ask for doorbell */ 2170 /* ask for doorbell */
2162 EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) | EHCI_CMD_IAAD); 2171 EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) | EHCI_CMD_IAAD);
2163 DPRINTF("cmd = 0x%08x sts = 0x%08x", 2172 DPRINTF("cmd = 0x%08x sts = 0x%08x",
2164 EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS), 0, 0); 2173 EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS), 0, 0);
2165 2174
2166 error = cv_timedwait(&sc->sc_doorbell, &sc->sc_lock, hz); /* bell wait */ 2175 error = cv_timedwait(&sc->sc_doorbell, &sc->sc_lock, hz); /* bell wait */
2167 2176
2168 DPRINTF("cmd = 0x%08x sts = 0x%08x ... done", 2177 DPRINTF("cmd = 0x%08x sts = 0x%08x ... done",
2169 EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS), 0, 0); 2178 EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS), 0, 0);
2170#ifdef DIAGNOSTIC 2179#ifdef DIAGNOSTIC
2171 if (error == EWOULDBLOCK) { 2180 if (error == EWOULDBLOCK) {
2172 printf("ehci_sync_hc: timed out\n"); 2181 printf("ehci_sync_hc: timed out\n");
2173 } else if (error) { 2182 } else if (error) {
@@ -3085,90 +3094,105 @@ Static void @@ -3085,90 +3094,105 @@ Static void
3085ehci_close_pipe(struct usbd_pipe *pipe, ehci_soft_qh_t *head) 3094ehci_close_pipe(struct usbd_pipe *pipe, ehci_soft_qh_t *head)
3086{ 3095{
3087 struct ehci_pipe *epipe = EHCI_PIPE2EPIPE(pipe); 3096 struct ehci_pipe *epipe = EHCI_PIPE2EPIPE(pipe);
3088 ehci_softc_t *sc = EHCI_PIPE2SC(pipe); 3097 ehci_softc_t *sc = EHCI_PIPE2SC(pipe);
3089 ehci_soft_qh_t *sqh = epipe->sqh; 3098 ehci_soft_qh_t *sqh = epipe->sqh;
3090 3099
3091 KASSERT(mutex_owned(&sc->sc_lock)); 3100 KASSERT(mutex_owned(&sc->sc_lock));
3092 3101
3093 ehci_rem_qh(sc, sqh, head); 3102 ehci_rem_qh(sc, sqh, head);
3094 ehci_free_sqh(sc, epipe->sqh); 3103 ehci_free_sqh(sc, epipe->sqh);
3095} 3104}
3096 3105
3097/* 3106/*
3098 * Abort a device request. 3107 * Cancel or timeout a device request. We have two cases to deal with
3099 * If this routine is called at splusb() it guarantees that the request 3108 *
3100 * will be removed from the hardware scheduling and that the callback 3109 * 1) A driver wants to stop scheduled or inflight transfers
3101 * for it will be called with USBD_CANCELLED status. 3110 * 2) A transfer has timed out
3102 * It's impossible to guarantee that the requested transfer will not 3111 *
3103 * have happened since the hardware runs concurrently. 3112 * have (partially) happened since the hardware runs concurrently.
3104 * If the transaction has already happened we rely on the ordinary 3113 *
3105 * interrupt processing to process it. 3114 * Transfer state is protected by the bus lock and we set the transfer status
3106 * XXX This is most probably wrong. 3115 * as soon as either of the above happens (with bus lock held).
3107 * XXXMRG this doesn't make sense anymore. 3116 *
 3117 * Then we arrange for the hardware to tells us that it is not still
 3118 * processing the TDs by setting the QH halted bit and wait for the ehci
 3119 * door bell
3108 */ 3120 */
3109Static void 3121Static void
3110ehci_abort_xfer(struct usbd_xfer *xfer, usbd_status status) 3122ehci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
3111{ 3123{
 3124 EHCIHIST_FUNC(); EHCIHIST_CALLED();
3112 struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); 3125 struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer);
3113 struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); 3126 struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer);
3114 ehci_softc_t *sc = EHCI_XFER2SC(xfer); 3127 ehci_softc_t *sc = EHCI_XFER2SC(xfer);
3115 ehci_soft_qh_t *sqh = epipe->sqh; 3128 ehci_soft_qh_t *sqh = epipe->sqh;
3116 ehci_soft_qtd_t *sqtd, *fsqtd, *lsqtd; 3129 ehci_soft_qtd_t *sqtd, *fsqtd, *lsqtd;
3117 ehci_physaddr_t cur; 3130 ehci_physaddr_t cur;
3118 uint32_t qhstatus; 3131 uint32_t qhstatus;
3119 int hit; 3132 int hit;
3120 int wake; 
3121 3133
3122 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 3134 KASSERTMSG((status == USBD_CANCELLED || status == USBD_TIMEOUT),
 3135 "invalid status for abort: %d", (int)status);
3123 3136
3124 DPRINTF("xfer=%p pipe=%p", xfer, epipe, 0, 0); 3137 DPRINTF("xfer=%p pipe=%p", xfer, epipe, 0, 0);
3125 3138
3126 KASSERT(mutex_owned(&sc->sc_lock)); 3139 KASSERT(mutex_owned(&sc->sc_lock));
3127 ASSERT_SLEEPABLE(); 3140 ASSERT_SLEEPABLE();
3128 3141
3129 if (sc->sc_dying) { 3142 if (status == USBD_CANCELLED) {
3130 /* If we're dying, just do the software part. */ 3143 /*
3131 xfer->ux_status = status; /* make software ignore it */ 3144 * We are synchronously aborting. Try to stop the
3132 callout_stop(&xfer->ux_callout); 3145 * callout and task, but if we can't, wait for them to
3133 usb_transfer_complete(xfer); 3146 * complete.
3134 return; 3147 */
 3148 callout_halt(&xfer->ux_callout, &sc->sc_lock);
 3149 usb_rem_task_wait(xfer->ux_pipe->up_dev, &xfer->ux_aborttask,
 3150 USB_TASKQ_HC, &sc->sc_lock);
 3151 } else {
 3152 /* Otherwise, we are timing out. */
 3153 KASSERT(status == USBD_TIMEOUT);
3135 } 3154 }
3136 3155
3137 /* 3156 /*
3138 * If an abort is already in progress then just wait for it to 3157 * The xfer cannot have been cancelled already. It is the
3139 * complete and return. 3158 * responsibility of the caller of usbd_abort_pipe not to try
 3159 * to abort a pipe multiple times, whether concurrently or
 3160 * sequentially.
3140 */ 3161 */
3141 if (xfer->ux_hcflags & UXFER_ABORTING) { 3162
3142 DPRINTF("already aborting", 0, 0, 0, 0); 3163 KASSERT(xfer->ux_status != USBD_CANCELLED);
3143#ifdef DIAGNOSTIC 3164
3144 if (status == USBD_TIMEOUT) 3165 /* Only the timeout, which runs only once, can time it out. */
3145 printf("ehci_abort_xfer: TIMEOUT while aborting\n"); 3166 KASSERT(xfer->ux_status != USBD_TIMEOUT);
3146#endif 3167
3147 /* Override the status which might be USBD_TIMEOUT. */ 3168 /* If anyone else beat us, we're done. */
3148 xfer->ux_status = status; 3169 if (xfer->ux_status != USBD_IN_PROGRESS)
3149 DPRINTF("waiting for abort to finish", 0, 0, 0, 0); 
3150 xfer->ux_hcflags |= UXFER_ABORTWAIT; 
3151 while (xfer->ux_hcflags & UXFER_ABORTING) 
3152 cv_wait(&xfer->ux_hccv, &sc->sc_lock); 
3153 return; 3170 return;
 3171
 3172 /* We beat everyone else. Claim the status. */
 3173 xfer->ux_status = status;
 3174
 3175 /*
 3176 * If we're dying, skip the hardware action and just notify the
 3177 * software that we're done.
 3178 */
 3179 if (sc->sc_dying) {
 3180 goto dying;
3154 } 3181 }
3155 xfer->ux_hcflags |= UXFER_ABORTING; 
3156 3182
3157 /* 3183 /*
3158 * Step 1: Make interrupt routine and hardware ignore xfer. 3184 * HC Step 1: Make interrupt routine and hardware ignore xfer.
3159 */ 3185 */
3160 xfer->ux_status = status; /* make software ignore it */ 
3161 callout_stop(&xfer->ux_callout); 
3162 ehci_del_intr_list(sc, exfer); 3186 ehci_del_intr_list(sc, exfer);
3163 3187
3164 usb_syncmem(&sqh->dma, 3188 usb_syncmem(&sqh->dma,
3165 sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), 3189 sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status),
3166 sizeof(sqh->qh.qh_qtd.qtd_status), 3190 sizeof(sqh->qh.qh_qtd.qtd_status),
3167 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3191 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3168 qhstatus = sqh->qh.qh_qtd.qtd_status; 3192 qhstatus = sqh->qh.qh_qtd.qtd_status;
3169 sqh->qh.qh_qtd.qtd_status = qhstatus | htole32(EHCI_QTD_HALTED); 3193 sqh->qh.qh_qtd.qtd_status = qhstatus | htole32(EHCI_QTD_HALTED);
3170 usb_syncmem(&sqh->dma, 3194 usb_syncmem(&sqh->dma,
3171 sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), 3195 sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status),
3172 sizeof(sqh->qh.qh_qtd.qtd_status), 3196 sizeof(sqh->qh.qh_qtd.qtd_status),
3173 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3197 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3174 3198
@@ -3184,37 +3208,33 @@ ehci_abort_xfer(struct usbd_xfer *xfer,  @@ -3184,37 +3208,33 @@ ehci_abort_xfer(struct usbd_xfer *xfer,
3184 sqtd->offs + offsetof(ehci_qtd_t, qtd_status), 3208 sqtd->offs + offsetof(ehci_qtd_t, qtd_status),
3185 sizeof(sqtd->qtd.qtd_status), 3209 sizeof(sqtd->qtd.qtd_status),
3186 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3210 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3187 sqtd->qtd.qtd_status |= htole32(EHCI_QTD_HALTED); 3211 sqtd->qtd.qtd_status |= htole32(EHCI_QTD_HALTED);
3188 usb_syncmem(&sqtd->dma, 3212 usb_syncmem(&sqtd->dma,
3189 sqtd->offs + offsetof(ehci_qtd_t, qtd_status), 3213 sqtd->offs + offsetof(ehci_qtd_t, qtd_status),
3190 sizeof(sqtd->qtd.qtd_status), 3214 sizeof(sqtd->qtd.qtd_status),
3191 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3215 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3192 if (sqtd == lsqtd) 3216 if (sqtd == lsqtd)
3193 break; 3217 break;
3194 } 3218 }
3195 3219
3196 /* 3220 /*
3197 * Step 2: Wait until we know hardware has finished any possible 3221 * HC Step 2: Wait until we know hardware has finished any possible
3198 * use of the xfer. Also make sure the soft interrupt routine 3222 * use of the xfer.
3199 * has run. 
3200 */ 3223 */
3201 ehci_sync_hc(sc); 3224 ehci_sync_hc(sc);
3202 sc->sc_softwake = 1; 
3203 usb_schedsoftintr(&sc->sc_bus); 
3204 cv_wait(&sc->sc_softwake_cv, &sc->sc_lock); 
3205 3225
3206 /* 3226 /*
3207 * Step 3: Remove any vestiges of the xfer from the hardware. 3227 * HC Step 3: Remove any vestiges of the xfer from the hardware.
3208 * The complication here is that the hardware may have executed 3228 * The complication here is that the hardware may have executed
3209 * beyond the xfer we're trying to abort. So as we're scanning 3229 * beyond the xfer we're trying to abort. So as we're scanning
3210 * the TDs of this xfer we check if the hardware points to 3230 * the TDs of this xfer we check if the hardware points to
3211 * any of them. 3231 * any of them.
3212 */ 3232 */
3213 3233
3214 usb_syncmem(&sqh->dma, 3234 usb_syncmem(&sqh->dma,
3215 sqh->offs + offsetof(ehci_qh_t, qh_curqtd), 3235 sqh->offs + offsetof(ehci_qh_t, qh_curqtd),
3216 sizeof(sqh->qh.qh_curqtd), 3236 sizeof(sqh->qh.qh_curqtd),
3217 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3237 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3218 cur = EHCI_LINK_ADDR(le32toh(sqh->qh.qh_curqtd)); 3238 cur = EHCI_LINK_ADDR(le32toh(sqh->qh.qh_curqtd));
3219 hit = 0; 3239 hit = 0;
3220 for (sqtd = fsqtd; ; sqtd = sqtd->nextqtd) { 3240 for (sqtd = fsqtd; ; sqtd = sqtd->nextqtd) {
@@ -3235,86 +3255,88 @@ ehci_abort_xfer(struct usbd_xfer *xfer,  @@ -3235,86 +3255,88 @@ ehci_abort_xfer(struct usbd_xfer *xfer,
3235 usb_syncmem(&sqh->dma, 3255 usb_syncmem(&sqh->dma,
3236 sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), 3256 sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status),
3237 sizeof(sqh->qh.qh_qtd.qtd_status), 3257 sizeof(sqh->qh.qh_qtd.qtd_status),
3238 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3258 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3239 } else { 3259 } else {
3240 DPRINTF("no hit", 0, 0, 0, 0); 3260 DPRINTF("no hit", 0, 0, 0, 0);
3241 usb_syncmem(&sqh->dma, 3261 usb_syncmem(&sqh->dma,
3242 sqh->offs + offsetof(ehci_qh_t, qh_curqtd), 3262 sqh->offs + offsetof(ehci_qh_t, qh_curqtd),
3243 sizeof(sqh->qh.qh_curqtd), 3263 sizeof(sqh->qh.qh_curqtd),
3244 BUS_DMASYNC_PREREAD); 3264 BUS_DMASYNC_PREREAD);
3245 } 3265 }
3246 3266
3247 /* 3267 /*
3248 * Step 4: Execute callback. 3268 * Final step: Notify completion to waiting xfers.
3249 */ 3269 */
 3270dying:
3250#ifdef DIAGNOSTIC 3271#ifdef DIAGNOSTIC
3251 exfer->ex_isdone = true; 3272 exfer->ex_isdone = true;
3252#endif 3273#endif
3253 wake = xfer->ux_hcflags & UXFER_ABORTWAIT; 
3254 xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); 
3255 usb_transfer_complete(xfer); 3274 usb_transfer_complete(xfer);
3256 if (wake) { 3275 DPRINTFN(14, "end", 0, 0, 0, 0);
3257 cv_broadcast(&xfer->ux_hccv); 
3258 } 
3259 3276
3260 KASSERT(mutex_owned(&sc->sc_lock)); 3277 KASSERT(mutex_owned(&sc->sc_lock));
3261} 3278}
3262 3279
3263Static void 3280Static void
3264ehci_abort_isoc_xfer(struct usbd_xfer *xfer, usbd_status status) 3281ehci_abort_isoc_xfer(struct usbd_xfer *xfer, usbd_status status)
3265{ 3282{
 3283 EHCIHIST_FUNC(); EHCIHIST_CALLED();
3266 ehci_isoc_trans_t trans_status; 3284 ehci_isoc_trans_t trans_status;
3267 struct ehci_xfer *exfer; 3285 struct ehci_xfer *exfer;
3268 ehci_softc_t *sc; 3286 ehci_softc_t *sc;
3269 struct ehci_soft_itd *itd; 3287 struct ehci_soft_itd *itd;
3270 struct ehci_soft_sitd *sitd; 3288 struct ehci_soft_sitd *sitd;
3271 int i, wake; 3289 int i;
3272 3290
3273 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 3291 KASSERTMSG(status == USBD_CANCELLED,
 3292 "invalid status for abort: %d", (int)status);
3274 3293
3275 exfer = EHCI_XFER2EXFER(xfer); 3294 exfer = EHCI_XFER2EXFER(xfer);
3276 sc = EHCI_XFER2SC(xfer); 3295 sc = EHCI_XFER2SC(xfer);
3277 3296
3278 DPRINTF("xfer %p pipe %p", xfer, xfer->ux_pipe, 0, 0); 3297 DPRINTF("xfer %p pipe %p", xfer, xfer->ux_pipe, 0, 0);
3279 3298
3280 KASSERT(mutex_owned(&sc->sc_lock)); 3299 KASSERT(mutex_owned(&sc->sc_lock));
 3300 ASSERT_SLEEPABLE();
3281 3301
3282 if (sc->sc_dying) { 3302 /* No timeout or task here. */
3283 xfer->ux_status = status; 
3284 callout_stop(&xfer->ux_callout); 
3285 usb_transfer_complete(xfer); 
3286 return; 
3287 } 
3288 3303
3289 if (xfer->ux_hcflags & UXFER_ABORTING) { 3304 /*
3290 DPRINTF("already aborting", 0, 0, 0, 0); 3305 * The xfer cannot have been cancelled already. It is the
 3306 * responsibility of the caller of usbd_abort_pipe not to try
 3307 * to abort a pipe multiple times, whether concurrently or
 3308 * sequentially.
 3309 */
 3310 KASSERT(xfer->ux_status != USBD_CANCELLED);
3291 3311
3292#ifdef DIAGNOSTIC 3312 /* If anyone else beat us, we're done. */
3293 if (status == USBD_TIMEOUT) 3313 if (xfer->ux_status != USBD_IN_PROGRESS)
3294 printf("ehci_abort_isoc_xfer: TIMEOUT while aborting\n"); 3314 return;
3295#endif 
3296 3315
3297 xfer->ux_status = status; 3316 /* We beat everyone else. Claim the status. */
3298 DPRINTF("waiting for abort to finish", 0, 0, 0, 0); 3317 xfer->ux_status = status;
3299 xfer->ux_hcflags |= UXFER_ABORTWAIT; 3318
3300 while (xfer->ux_hcflags & UXFER_ABORTING) 3319 /*
3301 cv_wait(&xfer->ux_hccv, &sc->sc_lock); 3320 * If we're dying, skip the hardware action and just notify the
3302 goto done; 3321 * software that we're done.
 3322 */
 3323 if (sc->sc_dying) {
 3324 goto dying;
3303 } 3325 }
3304 xfer->ux_hcflags |= UXFER_ABORTING; 
3305 3326
3306 xfer->ux_status = status; 3327 /*
3307 callout_stop(&xfer->ux_callout); 3328 * HC Step 1: Make interrupt routine and hardware ignore xfer.
 3329 */
3308 ehci_del_intr_list(sc, exfer); 3330 ehci_del_intr_list(sc, exfer);
3309 3331
3310 if (xfer->ux_pipe->up_dev->ud_speed == USB_SPEED_HIGH) { 3332 if (xfer->ux_pipe->up_dev->ud_speed == USB_SPEED_HIGH) {
3311 for (itd = exfer->ex_itdstart; itd != NULL; 3333 for (itd = exfer->ex_itdstart; itd != NULL;
3312 itd = itd->xfer_next) { 3334 itd = itd->xfer_next) {
3313 usb_syncmem(&itd->dma, 3335 usb_syncmem(&itd->dma,
3314 itd->offs + offsetof(ehci_itd_t, itd_ctl), 3336 itd->offs + offsetof(ehci_itd_t, itd_ctl),
3315 sizeof(itd->itd.itd_ctl), 3337 sizeof(itd->itd.itd_ctl),
3316 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3338 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3317 3339
3318 for (i = 0; i < 8; i++) { 3340 for (i = 0; i < 8; i++) {
3319 trans_status = le32toh(itd->itd.itd_ctl[i]); 3341 trans_status = le32toh(itd->itd.itd_ctl[i]);
3320 trans_status &= ~EHCI_ITD_ACTIVE; 3342 trans_status &= ~EHCI_ITD_ACTIVE;
@@ -3335,73 +3357,56 @@ ehci_abort_isoc_xfer(struct usbd_xfer *x @@ -3335,73 +3357,56 @@ ehci_abort_isoc_xfer(struct usbd_xfer *x
3335 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3357 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3336 3358
3337 trans_status = le32toh(sitd->sitd.sitd_trans); 3359 trans_status = le32toh(sitd->sitd.sitd_trans);
3338 trans_status &= ~EHCI_SITD_ACTIVE; 3360 trans_status &= ~EHCI_SITD_ACTIVE;
3339 sitd->sitd.sitd_trans = htole32(trans_status); 3361 sitd->sitd.sitd_trans = htole32(trans_status);
3340 3362
3341 usb_syncmem(&sitd->dma, 3363 usb_syncmem(&sitd->dma,
3342 sitd->offs + offsetof(ehci_sitd_t, sitd_buffer), 3364 sitd->offs + offsetof(ehci_sitd_t, sitd_buffer),
3343 sizeof(sitd->sitd.sitd_buffer), 3365 sizeof(sitd->sitd.sitd_buffer),
3344 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3366 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3345 } 3367 }
3346 } 3368 }
3347 3369
3348 sc->sc_softwake = 1; 3370dying:
3349 usb_schedsoftintr(&sc->sc_bus); 
3350 cv_wait(&sc->sc_softwake_cv, &sc->sc_lock); 
3351 
3352#ifdef DIAGNOSTIC 3371#ifdef DIAGNOSTIC
3353 exfer->ex_isdone = true; 3372 exfer->ex_isdone = true;
3354#endif 3373#endif
3355 wake = xfer->ux_hcflags & UXFER_ABORTWAIT; 
3356 xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); 
3357 usb_transfer_complete(xfer); 3374 usb_transfer_complete(xfer);
3358 if (wake) { 3375 DPRINTFN(14, "end", 0, 0, 0, 0);
3359 cv_broadcast(&xfer->ux_hccv); 
3360 } 
3361 3376
3362done: 
3363 KASSERT(mutex_owned(&sc->sc_lock)); 3377 KASSERT(mutex_owned(&sc->sc_lock));
3364 return; 
3365} 3378}
3366 3379
3367Static void 3380Static void
3368ehci_timeout(void *addr) 3381ehci_timeout(void *addr)
3369{ 3382{
 3383 EHCIHIST_FUNC(); EHCIHIST_CALLED();
3370 struct usbd_xfer *xfer = addr; 3384 struct usbd_xfer *xfer = addr;
3371 struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); 
3372 struct usbd_pipe *pipe = xfer->ux_pipe; 
3373 struct usbd_device *dev = pipe->up_dev; 
3374 ehci_softc_t *sc = EHCI_XFER2SC(xfer); 3385 ehci_softc_t *sc = EHCI_XFER2SC(xfer);
 3386 struct usbd_device *dev = xfer->ux_pipe->up_dev;
3375 3387
3376 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 3388 DPRINTF("xfer %p", xfer, 0, 0, 0);
3377 
3378 DPRINTF("exfer %p", exfer, 0, 0, 0); 
3379#ifdef EHCI_DEBUG 3389#ifdef EHCI_DEBUG
3380 if (ehcidebug >= 2) 3390 if (ehcidebug >= 2) {
 3391 struct usbd_pipe *pipe = xfer->ux_pipe;
3381 usbd_dump_pipe(pipe); 3392 usbd_dump_pipe(pipe);
3382#endif 
3383 
3384 if (sc->sc_dying) { 
3385 mutex_enter(&sc->sc_lock); 
3386 ehci_abort_xfer(xfer, USBD_TIMEOUT); 
3387 mutex_exit(&sc->sc_lock); 
3388 return; 
3389 } 3393 }
 3394#endif
3390 3395
3391 /* Execute the abort in a process context. */ 3396 mutex_enter(&sc->sc_lock);
3392 usb_init_task(&exfer->ex_aborttask, ehci_timeout_task, xfer, 3397 if (!sc->sc_dying && xfer->ux_status == USBD_IN_PROGRESS)
3393 USB_TASKQ_MPSAFE); 3398 usb_add_task(dev, &xfer->ux_aborttask, USB_TASKQ_HC);
3394 usb_add_task(dev, &exfer->ex_aborttask, USB_TASKQ_HC); 3399 mutex_exit(&sc->sc_lock);
3395} 3400}
3396 3401
3397Static void 3402Static void
3398ehci_timeout_task(void *addr) 3403ehci_timeout_task(void *addr)
3399{ 3404{
3400 struct usbd_xfer *xfer = addr; 3405 struct usbd_xfer *xfer = addr;
3401 ehci_softc_t *sc = EHCI_XFER2SC(xfer); 3406 ehci_softc_t *sc = EHCI_XFER2SC(xfer);
3402 3407
3403 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 3408 EHCIHIST_FUNC(); EHCIHIST_CALLED();
3404 3409
3405 DPRINTF("xfer=%p", xfer, 0, 0, 0); 3410 DPRINTF("xfer=%p", xfer, 0, 0, 0);
3406 3411
3407 mutex_enter(&sc->sc_lock); 3412 mutex_enter(&sc->sc_lock);
@@ -4448,27 +4453,26 @@ ehci_device_fs_isoc_transfer(struct usbd @@ -4448,27 +4453,26 @@ ehci_device_fs_isoc_transfer(struct usbd
4448 sitd->slot = frindex; 4453 sitd->slot = frindex;
4449 sitd->frame_list.prev = NULL; 4454 sitd->frame_list.prev = NULL;
4450 4455
4451 frindex += i; 4456 frindex += i;
4452 if (frindex >= sc->sc_flsize) 4457 if (frindex >= sc->sc_flsize)
4453 frindex -= sc->sc_flsize; 4458 frindex -= sc->sc_flsize;
4454 } 4459 }
4455 4460
4456 epipe->isoc.cur_xfers++; 4461 epipe->isoc.cur_xfers++;
4457 epipe->isoc.next_frame = frindex; 4462 epipe->isoc.next_frame = frindex;
4458 4463
4459 ehci_add_intr_list(sc, exfer); 4464 ehci_add_intr_list(sc, exfer);
4460 xfer->ux_status = USBD_IN_PROGRESS; 4465 xfer->ux_status = USBD_IN_PROGRESS;
4461 
4462 mutex_exit(&sc->sc_lock); 4466 mutex_exit(&sc->sc_lock);
4463 4467
4464 return USBD_IN_PROGRESS; 4468 return USBD_IN_PROGRESS;
4465} 4469}
4466 4470
4467Static void 4471Static void
4468ehci_device_fs_isoc_abort(struct usbd_xfer *xfer) 4472ehci_device_fs_isoc_abort(struct usbd_xfer *xfer)
4469{ 4473{
4470 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 4474 EHCIHIST_FUNC(); EHCIHIST_CALLED();
4471 4475
4472 DPRINTF("xfer = %p", xfer, 0, 0, 0); 4476 DPRINTF("xfer = %p", xfer, 0, 0, 0);
4473 ehci_abort_isoc_xfer(xfer, USBD_CANCELLED); 4477 ehci_abort_isoc_xfer(xfer, USBD_CANCELLED);
4474} 4478}
@@ -4842,27 +4846,26 @@ ehci_device_isoc_transfer(struct usbd_xf @@ -4842,27 +4846,26 @@ ehci_device_isoc_transfer(struct usbd_xf
4842 4846
4843 frindex += i; 4847 frindex += i;
4844 if (frindex >= sc->sc_flsize) 4848 if (frindex >= sc->sc_flsize)
4845 frindex -= sc->sc_flsize; 4849 frindex -= sc->sc_flsize;
4846 4850
4847 itd = itd->xfer_next; 4851 itd = itd->xfer_next;
4848 } 4852 }
4849 4853
4850 epipe->isoc.cur_xfers++; 4854 epipe->isoc.cur_xfers++;
4851 epipe->isoc.next_frame = frindex; 4855 epipe->isoc.next_frame = frindex;
4852 4856
4853 ehci_add_intr_list(sc, exfer); 4857 ehci_add_intr_list(sc, exfer);
4854 xfer->ux_status = USBD_IN_PROGRESS; 4858 xfer->ux_status = USBD_IN_PROGRESS;
4855 
4856 mutex_exit(&sc->sc_lock); 4859 mutex_exit(&sc->sc_lock);
4857 4860
4858 return USBD_IN_PROGRESS; 4861 return USBD_IN_PROGRESS;
4859} 4862}
4860 4863
4861Static void 4864Static void
4862ehci_device_isoc_abort(struct usbd_xfer *xfer) 4865ehci_device_isoc_abort(struct usbd_xfer *xfer)
4863{ 4866{
4864 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 4867 EHCIHIST_FUNC(); EHCIHIST_CALLED();
4865 4868
4866 DPRINTF("xfer = %p", xfer, 0, 0, 0); 4869 DPRINTF("xfer = %p", xfer, 0, 0, 0);
4867 ehci_abort_isoc_xfer(xfer, USBD_CANCELLED); 4870 ehci_abort_isoc_xfer(xfer, USBD_CANCELLED);
4868} 4871}

cvs diff -r1.42.12.1 -r1.42.12.2 src/sys/dev/usb/ehcivar.h (expand / switch to unified diff)

--- src/sys/dev/usb/ehcivar.h 2017/04/05 19:54:19 1.42.12.1
+++ src/sys/dev/usb/ehcivar.h 2018/08/25 14:57:35 1.42.12.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ehcivar.h,v 1.42.12.1 2017/04/05 19:54:19 snj Exp $ */ 1/* $NetBSD: ehcivar.h,v 1.42.12.2 2018/08/25 14:57:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 4 * Copyright (c) 2001 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). 8 * by Lennart Augustsson (lennart@augustsson.net).
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -81,27 +81,26 @@ typedef struct ehci_soft_itd { @@ -81,27 +81,26 @@ typedef struct ehci_soft_itd {
81 struct timeval t; /* store free time */ 81 struct timeval t; /* store free time */
82} ehci_soft_itd_t; 82} ehci_soft_itd_t;
83#define EHCI_ITD_SIZE ((sizeof(struct ehci_soft_itd) + EHCI_QH_ALIGN - 1) / EHCI_ITD_ALIGN * EHCI_ITD_ALIGN) 83#define EHCI_ITD_SIZE ((sizeof(struct ehci_soft_itd) + EHCI_QH_ALIGN - 1) / EHCI_ITD_ALIGN * EHCI_ITD_ALIGN)
84#define EHCI_ITD_CHUNK (EHCI_PAGE_SIZE / EHCI_ITD_SIZE) 84#define EHCI_ITD_CHUNK (EHCI_PAGE_SIZE / EHCI_ITD_SIZE)
85 85
86#define ehci_soft_sitd_t ehci_soft_itd_t 86#define ehci_soft_sitd_t ehci_soft_itd_t
87#define ehci_soft_sitd ehci_soft_itd 87#define ehci_soft_sitd ehci_soft_itd
88#define sc_softsitds sc_softitds 88#define sc_softsitds sc_softitds
89#define EHCI_SITD_SIZE ((sizeof(struct ehci_soft_sitd) + EHCI_QH_ALIGN - 1) / EHCI_SITD_ALIGN * EHCI_SITD_ALIGN) 89#define EHCI_SITD_SIZE ((sizeof(struct ehci_soft_sitd) + EHCI_QH_ALIGN - 1) / EHCI_SITD_ALIGN * EHCI_SITD_ALIGN)
90#define EHCI_SITD_CHUNK (EHCI_PAGE_SIZE / EHCI_SITD_SIZE) 90#define EHCI_SITD_CHUNK (EHCI_PAGE_SIZE / EHCI_SITD_SIZE)
91 91
92struct ehci_xfer { 92struct ehci_xfer {
93 struct usbd_xfer ex_xfer; 93 struct usbd_xfer ex_xfer;
94 struct usb_task ex_aborttask; 
95 TAILQ_ENTRY(ehci_xfer) ex_next; /* list of active xfers */ 94 TAILQ_ENTRY(ehci_xfer) ex_next; /* list of active xfers */
96 enum { 95 enum {
97 EX_NONE, 96 EX_NONE,
98 EX_CTRL, 97 EX_CTRL,
99 EX_BULK, 98 EX_BULK,
100 EX_INTR, 99 EX_INTR,
101 EX_ISOC, 100 EX_ISOC,
102 EX_FS_ISOC 101 EX_FS_ISOC
103 } ex_type; 102 } ex_type;
104 /* ctrl/bulk/intr */ 103 /* ctrl/bulk/intr */
105 struct { 104 struct {
106 ehci_soft_qtd_t **ex_sqtds; 105 ehci_soft_qtd_t **ex_sqtds;
107 size_t ex_nsqtd; 106 size_t ex_nsqtd;
@@ -201,28 +200,26 @@ typedef struct ehci_softc { @@ -201,28 +200,26 @@ typedef struct ehci_softc {
201 200
202 TAILQ_HEAD(, ehci_xfer) sc_intrhead; 201 TAILQ_HEAD(, ehci_xfer) sc_intrhead;
203 202
204 ehci_soft_qh_t *sc_freeqhs; 203 ehci_soft_qh_t *sc_freeqhs;
205 ehci_soft_qtd_t *sc_freeqtds; 204 ehci_soft_qtd_t *sc_freeqtds;
206 LIST_HEAD(sc_freeitds, ehci_soft_itd) sc_freeitds; 205 LIST_HEAD(sc_freeitds, ehci_soft_itd) sc_freeitds;
207 LIST_HEAD(sc_freesitds, ehci_soft_sitd) sc_freesitds; 206 LIST_HEAD(sc_freesitds, ehci_soft_sitd) sc_freesitds;
208 207
209 int sc_noport; 208 int sc_noport;
210 uint8_t sc_hasppc; /* has Port Power Control */ 209 uint8_t sc_hasppc; /* has Port Power Control */
211 uint8_t sc_istthreshold; /* ISOC Scheduling Threshold (uframes) */ 210 uint8_t sc_istthreshold; /* ISOC Scheduling Threshold (uframes) */
212 struct usbd_xfer *sc_intrxfer; 211 struct usbd_xfer *sc_intrxfer;
213 char sc_isreset[EHCI_MAX_PORTS]; 212 char sc_isreset[EHCI_MAX_PORTS];
214 char sc_softwake; 
215 kcondvar_t sc_softwake_cv; 
216 213
217 uint32_t sc_eintrs; 214 uint32_t sc_eintrs;
218 ehci_soft_qh_t *sc_async_head; 215 ehci_soft_qh_t *sc_async_head;
219 216
220 pool_cache_t sc_xferpool; /* free xfer pool */ 217 pool_cache_t sc_xferpool; /* free xfer pool */
221 218
222 struct callout sc_tmo_intrlist; 219 struct callout sc_tmo_intrlist;
223 220
224 device_t sc_child; /* /dev/usb# device */ 221 device_t sc_child; /* /dev/usb# device */
225 char sc_dying; 222 char sc_dying;
226 223
227 void (*sc_vendor_init)(struct ehci_softc *); 224 void (*sc_vendor_init)(struct ehci_softc *);
228 int (*sc_vendor_port_status)(struct ehci_softc *, uint32_t, int); 225 int (*sc_vendor_port_status)(struct ehci_softc *, uint32_t, int);

cvs diff -r1.6.4.4 -r1.6.4.5 src/sys/dev/usb/motg.c (expand / switch to unified diff)

--- src/sys/dev/usb/motg.c 2018/01/03 20:02:37 1.6.4.4
+++ src/sys/dev/usb/motg.c 2018/08/25 14:57:35 1.6.4.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: motg.c,v 1.6.4.4 2018/01/03 20:02:37 snj Exp $ */ 1/* $NetBSD: motg.c,v 1.6.4.5 2018/08/25 14:57:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2004, 2011, 2012, 2014 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2004, 2011, 2012, 2014 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, Jared D. McNeill (jmcneill@invisible.ca), 9 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca),
10 * Matthew R. Green (mrg@eterna.com.au), and Manuel Bouyer (bouyer@netbsd.org). 10 * Matthew R. Green (mrg@eterna.com.au), and Manuel Bouyer (bouyer@netbsd.org).
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:
@@ -30,27 +30,27 @@ @@ -30,27 +30,27 @@
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34 34
35/* 35/*
36 * This file contains the driver for the Mentor Graphics Inventra USB 36 * This file contains the driver for the Mentor Graphics Inventra USB
37 * 2.0 High Speed Dual-Role controller. 37 * 2.0 High Speed Dual-Role controller.
38 * 38 *
39 * NOTE: The current implementation only supports Device Side Mode! 39 * NOTE: The current implementation only supports Device Side Mode!
40 */ 40 */
41 41
42#include <sys/cdefs.h> 42#include <sys/cdefs.h>
43__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.6.4.4 2018/01/03 20:02:37 snj Exp $"); 43__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.6.4.5 2018/08/25 14:57:35 martin Exp $");
44 44
45#ifdef _KERNEL_OPT 45#ifdef _KERNEL_OPT
46#include "opt_motg.h" 46#include "opt_motg.h"
47#include "opt_usb.h" 47#include "opt_usb.h"
48#endif 48#endif
49 49
50#include <sys/param.h> 50#include <sys/param.h>
51 51
52#include <sys/bus.h> 52#include <sys/bus.h>
53#include <sys/cpu.h> 53#include <sys/cpu.h>
54#include <sys/device.h> 54#include <sys/device.h>
55#include <sys/kernel.h> 55#include <sys/kernel.h>
56#include <sys/kmem.h> 56#include <sys/kmem.h>
@@ -2150,42 +2150,66 @@ motg_device_data_done(struct usbd_xfer * @@ -2150,42 +2150,66 @@ motg_device_data_done(struct usbd_xfer *
2150} 2150}
2151 2151
2152void 2152void
2153motg_device_clear_toggle(struct usbd_pipe *pipe) 2153motg_device_clear_toggle(struct usbd_pipe *pipe)
2154{ 2154{
2155 struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); 2155 struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe);
2156 otgpipe->nexttoggle = 0; 2156 otgpipe->nexttoggle = 0;
2157} 2157}
2158 2158
2159/* Abort a device control request. */ 2159/* Abort a device control request. */
2160static void 2160static void
2161motg_device_xfer_abort(struct usbd_xfer *xfer) 2161motg_device_xfer_abort(struct usbd_xfer *xfer)
2162{ 2162{
2163 int wake; 2163 MOTGHIST_FUNC(); MOTGHIST_CALLED();
2164 uint8_t csr; 2164 uint8_t csr;
2165 struct motg_softc *sc = MOTG_XFER2SC(xfer); 2165 struct motg_softc *sc = MOTG_XFER2SC(xfer);
2166 struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 2166 struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe);
 2167
2167 KASSERT(mutex_owned(&sc->sc_lock)); 2168 KASSERT(mutex_owned(&sc->sc_lock));
 2169 ASSERT_SLEEPABLE();
2168 2170
2169 MOTGHIST_FUNC(); MOTGHIST_CALLED(); 2171 /*
 2172 * We are synchronously aborting. Try to stop the
 2173 * callout and task, but if we can't, wait for them to
 2174 * complete.
 2175 */
 2176 callout_halt(&xfer->ux_callout, &sc->sc_lock);
 2177 usb_rem_task_wait(xfer->ux_pipe->up_dev, &xfer->ux_aborttask,
 2178 USB_TASKQ_HC, &sc->sc_lock);
 2179
 2180 /*
 2181 * The xfer cannot have been cancelled already. It is the
 2182 * responsibility of the caller of usbd_abort_pipe not to try
 2183 * to abort a pipe multiple times, whether concurrently or
 2184 * sequentially.
 2185 */
 2186 KASSERT(xfer->ux_status != USBD_CANCELLED);
2170 2187
2171 if (xfer->ux_hcflags & UXFER_ABORTING) { 2188 /* If anyone else beat us, we're done. */
2172 DPRINTF("already aborting", 0, 0, 0, 0); 2189 if (xfer->ux_status != USBD_IN_PROGRESS)
2173 xfer->ux_hcflags |= UXFER_ABORTWAIT; 
2174 while (xfer->ux_hcflags & UXFER_ABORTING) 
2175 cv_wait(&xfer->ux_hccv, &sc->sc_lock); 
2176 return; 2190 return;
 2191
 2192 /* We beat everyone else. Claim the status. */
 2193 xfer->ux_status = USBD_CANCELLED;
 2194
 2195 /*
 2196 * If we're dying, skip the hardware action and just notify the
 2197 * software that we're done.
 2198 */
 2199 if (sc->sc_dying) {
 2200 goto dying;
2177 } 2201 }
2178 xfer->ux_hcflags |= UXFER_ABORTING; 2202
2179 if (otgpipe->hw_ep->xfer == xfer) { 2203 if (otgpipe->hw_ep->xfer == xfer) {
2180 KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 2204 KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
2181 otgpipe->hw_ep->xfer = NULL; 2205 otgpipe->hw_ep->xfer = NULL;
2182 if (otgpipe->hw_ep->ep_number > 0) { 2206 if (otgpipe->hw_ep->ep_number > 0) {
2183 /* select endpoint */ 2207 /* select endpoint */
2184 UWRITE1(sc, MUSB2_REG_EPINDEX, 2208 UWRITE1(sc, MUSB2_REG_EPINDEX,
2185 otgpipe->hw_ep->ep_number); 2209 otgpipe->hw_ep->ep_number);
2186 if (otgpipe->hw_ep->phase == DATA_OUT) { 2210 if (otgpipe->hw_ep->phase == DATA_OUT) {
2187 csr = UREAD1(sc, MUSB2_REG_TXCSRL); 2211 csr = UREAD1(sc, MUSB2_REG_TXCSRL);
2188 while (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) { 2212 while (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
2189 csr |= MUSB2_MASK_CSRL_TXFFLUSH; 2213 csr |= MUSB2_MASK_CSRL_TXFFLUSH;
2190 UWRITE1(sc, MUSB2_REG_TXCSRL, csr); 2214 UWRITE1(sc, MUSB2_REG_TXCSRL, csr);
2191 csr = UREAD1(sc, MUSB2_REG_TXCSRL); 2215 csr = UREAD1(sc, MUSB2_REG_TXCSRL);
@@ -2193,20 +2217,17 @@ motg_device_xfer_abort(struct usbd_xfer  @@ -2193,20 +2217,17 @@ motg_device_xfer_abort(struct usbd_xfer
2193 UWRITE1(sc, MUSB2_REG_TXCSRL, 0); 2217 UWRITE1(sc, MUSB2_REG_TXCSRL, 0);
2194 } else if (otgpipe->hw_ep->phase == DATA_IN) { 2218 } else if (otgpipe->hw_ep->phase == DATA_IN) {
2195 csr = UREAD1(sc, MUSB2_REG_RXCSRL); 2219 csr = UREAD1(sc, MUSB2_REG_RXCSRL);
2196 while (csr & MUSB2_MASK_CSRL_RXPKTRDY) { 2220 while (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
2197 csr |= MUSB2_MASK_CSRL_RXFFLUSH; 2221 csr |= MUSB2_MASK_CSRL_RXFFLUSH;
2198 UWRITE1(sc, MUSB2_REG_RXCSRL, csr); 2222 UWRITE1(sc, MUSB2_REG_RXCSRL, csr);
2199 csr = UREAD1(sc, MUSB2_REG_RXCSRL); 2223 csr = UREAD1(sc, MUSB2_REG_RXCSRL);
2200 } 2224 }
2201 UWRITE1(sc, MUSB2_REG_RXCSRL, 0); 2225 UWRITE1(sc, MUSB2_REG_RXCSRL, 0);
2202 } 2226 }
2203 otgpipe->hw_ep->phase = IDLE; 2227 otgpipe->hw_ep->phase = IDLE;
2204 } 2228 }
2205 } 2229 }
2206 xfer->ux_status = USBD_CANCELLED; /* make software ignore it */ 2230dying:
2207 wake = xfer->ux_hcflags & UXFER_ABORTWAIT; 
2208 xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); 
2209 usb_transfer_complete(xfer); 2231 usb_transfer_complete(xfer);
2210 if (wake) 2232 KASSERT(mutex_owned(&sc->sc_lock));
2211 cv_broadcast(&xfer->ux_hccv); 
2212} 2233}

cvs diff -r1.253.2.4 -r1.253.2.5 src/sys/dev/usb/ohci.c (expand / switch to unified diff)

--- src/sys/dev/usb/ohci.c 2018/01/03 20:02:37 1.253.2.4
+++ src/sys/dev/usb/ohci.c 2018/08/25 14:57:35 1.253.2.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ohci.c,v 1.253.2.4 2018/01/03 20:02:37 snj Exp $ */ 1/* $NetBSD: ohci.c,v 1.253.2.5 2018/08/25 14:57:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2004, 2005, 2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2004, 2005, 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) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca) 9 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca)
10 * and Matthew R. Green (mrg@eterna.com.au). 10 * and Matthew R. Green (mrg@eterna.com.au).
11 * This code is derived from software contributed to The NetBSD Foundation 11 * This code is derived from software contributed to The NetBSD Foundation
12 * by Charles M. Hannum. 12 * by Charles M. Hannum.
13 * 13 *
14 * Redistribution and use in source and binary forms, with or without 14 * Redistribution and use in source and binary forms, with or without
@@ -31,27 +31,27 @@ @@ -31,27 +31,27 @@
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE. 33 * POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36/* 36/*
37 * USB Open Host Controller driver. 37 * USB Open Host Controller driver.
38 * 38 *
39 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html 39 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
40 * USB spec: http://www.usb.org/developers/docs/ 40 * USB spec: http://www.usb.org/developers/docs/
41 */ 41 */
42 42
43#include <sys/cdefs.h> 43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.253.2.4 2018/01/03 20:02:37 snj Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.253.2.5 2018/08/25 14:57:35 martin Exp $");
45 45
46#ifdef _KERNEL_OPT 46#ifdef _KERNEL_OPT
47#include "opt_usb.h" 47#include "opt_usb.h"
48#endif 48#endif
49 49
50#include <sys/param.h> 50#include <sys/param.h>
51 51
52#include <sys/cpu.h> 52#include <sys/cpu.h>
53#include <sys/device.h> 53#include <sys/device.h>
54#include <sys/kernel.h> 54#include <sys/kernel.h>
55#include <sys/kmem.h> 55#include <sys/kmem.h>
56#include <sys/proc.h> 56#include <sys/proc.h>
57#include <sys/queue.h> 57#include <sys/queue.h>
@@ -374,28 +374,26 @@ ohci_detach(struct ohci_softc *sc, int f @@ -374,28 +374,26 @@ ohci_detach(struct ohci_softc *sc, int f
374 if (sc->sc_child != NULL) 374 if (sc->sc_child != NULL)
375 rv = config_detach(sc->sc_child, flags); 375 rv = config_detach(sc->sc_child, flags);
376 376
377 if (rv != 0) 377 if (rv != 0)
378 return rv; 378 return rv;
379 379
380 callout_halt(&sc->sc_tmo_rhsc, &sc->sc_lock); 380 callout_halt(&sc->sc_tmo_rhsc, &sc->sc_lock);
381 381
382 usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */ 382 usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
383 callout_destroy(&sc->sc_tmo_rhsc); 383 callout_destroy(&sc->sc_tmo_rhsc);
384 384
385 softint_disestablish(sc->sc_rhsc_si); 385 softint_disestablish(sc->sc_rhsc_si);
386 386
387 cv_destroy(&sc->sc_softwake_cv); 
388 
389 mutex_destroy(&sc->sc_lock); 387 mutex_destroy(&sc->sc_lock);
390 mutex_destroy(&sc->sc_intr_lock); 388 mutex_destroy(&sc->sc_intr_lock);
391 389
392 if (sc->sc_hcca != NULL) 390 if (sc->sc_hcca != NULL)
393 usb_freemem(&sc->sc_bus, &sc->sc_hccadma); 391 usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
394 pool_cache_destroy(sc->sc_xferpool); 392 pool_cache_destroy(sc->sc_xferpool);
395 393
396 return rv; 394 return rv;
397} 395}
398 396
399ohci_soft_ed_t * 397ohci_soft_ed_t *
400ohci_alloc_sed(ohci_softc_t *sc) 398ohci_alloc_sed(ohci_softc_t *sc)
401{ 399{
@@ -776,27 +774,26 @@ ohci_init(ohci_softc_t *sc) @@ -776,27 +774,26 @@ ohci_init(ohci_softc_t *sc)
776 usbd_status err; 774 usbd_status err;
777 int i; 775 int i;
778 uint32_t s, ctl, rwc, ival, hcr, fm, per, rev, desca /*, descb */; 776 uint32_t s, ctl, rwc, ival, hcr, fm, per, rev, desca /*, descb */;
779 777
780 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 778 OHCIHIST_FUNC(); OHCIHIST_CALLED();
781 779
782 aprint_normal_dev(sc->sc_dev, ""); 780 aprint_normal_dev(sc->sc_dev, "");
783 781
784 sc->sc_hcca = NULL; 782 sc->sc_hcca = NULL;
785 callout_init(&sc->sc_tmo_rhsc, CALLOUT_MPSAFE); 783 callout_init(&sc->sc_tmo_rhsc, CALLOUT_MPSAFE);
786 784
787 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 785 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
788 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB); 786 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
789 cv_init(&sc->sc_softwake_cv, "ohciab"); 
790 787
791 sc->sc_rhsc_si = softint_establish(SOFTINT_USB | SOFTINT_MPSAFE, 788 sc->sc_rhsc_si = softint_establish(SOFTINT_USB | SOFTINT_MPSAFE,
792 ohci_rhsc_softint, sc); 789 ohci_rhsc_softint, sc);
793 790
794 for (i = 0; i < OHCI_HASH_SIZE; i++) 791 for (i = 0; i < OHCI_HASH_SIZE; i++)
795 LIST_INIT(&sc->sc_hash_tds[i]); 792 LIST_INIT(&sc->sc_hash_tds[i]);
796 for (i = 0; i < OHCI_HASH_SIZE; i++) 793 for (i = 0; i < OHCI_HASH_SIZE; i++)
797 LIST_INIT(&sc->sc_hash_itds[i]); 794 LIST_INIT(&sc->sc_hash_itds[i]);
798 795
799 sc->sc_xferpool = pool_cache_init(sizeof(struct ohci_xfer), 0, 0, 0, 796 sc->sc_xferpool = pool_cache_init(sizeof(struct ohci_xfer), 0, 0, 0,
800 "ohcixfer", NULL, IPL_USB, NULL, NULL, NULL); 797 "ohcixfer", NULL, IPL_USB, NULL, NULL, NULL);
801 798
802 rev = OREAD4(sc, OHCI_REVISION); 799 rev = OREAD4(sc, OHCI_REVISION);
@@ -1058,26 +1055,30 @@ ohci_init(ohci_softc_t *sc) @@ -1058,26 +1055,30 @@ ohci_init(ohci_softc_t *sc)
1058 sc->sc_hcca = NULL; 1055 sc->sc_hcca = NULL;
1059 return err; 1056 return err;
1060} 1057}
1061 1058
1062struct usbd_xfer * 1059struct usbd_xfer *
1063ohci_allocx(struct usbd_bus *bus, unsigned int nframes) 1060ohci_allocx(struct usbd_bus *bus, unsigned int nframes)
1064{ 1061{
1065 ohci_softc_t *sc = OHCI_BUS2SC(bus); 1062 ohci_softc_t *sc = OHCI_BUS2SC(bus);
1066 struct usbd_xfer *xfer; 1063 struct usbd_xfer *xfer;
1067 1064
1068 xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK); 1065 xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK);
1069 if (xfer != NULL) { 1066 if (xfer != NULL) {
1070 memset(xfer, 0, sizeof(struct ohci_xfer)); 1067 memset(xfer, 0, sizeof(struct ohci_xfer));
 1068
 1069 /* Initialise this always so we can call remove on it. */
 1070 usb_init_task(&xfer->ux_aborttask, ohci_timeout_task, xfer,
 1071 USB_TASKQ_MPSAFE);
1071#ifdef DIAGNOSTIC 1072#ifdef DIAGNOSTIC
1072 xfer->ux_state = XFER_BUSY; 1073 xfer->ux_state = XFER_BUSY;
1073#endif 1074#endif
1074 } 1075 }
1075 return xfer; 1076 return xfer;
1076} 1077}
1077 1078
1078void 1079void
1079ohci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) 1080ohci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
1080{ 1081{
1081 ohci_softc_t *sc = OHCI_BUS2SC(bus); 1082 ohci_softc_t *sc = OHCI_BUS2SC(bus);
1082 1083
1083 KASSERTMSG(xfer->ux_state == XFER_BUSY, 1084 KASSERTMSG(xfer->ux_state == XFER_BUSY,
@@ -1443,33 +1444,45 @@ ohci_softintr(void *v) @@ -1443,33 +1444,45 @@ ohci_softintr(void *v)
1443 xfer = std->xfer; 1444 xfer = std->xfer;
1444 stdnext = std->dnext; 1445 stdnext = std->dnext;
1445 DPRINTFN(10, "std=%p xfer=%p hcpriv=%p", std, xfer, 1446 DPRINTFN(10, "std=%p xfer=%p hcpriv=%p", std, xfer,
1446 xfer ? xfer->ux_hcpriv : 0, 0); 1447 xfer ? xfer->ux_hcpriv : 0, 0);
1447 if (xfer == NULL) { 1448 if (xfer == NULL) {
1448 /* 1449 /*
1449 * xfer == NULL: There seems to be no xfer associated 1450 * xfer == NULL: There seems to be no xfer associated
1450 * with this TD. It is tailp that happened to end up on 1451 * with this TD. It is tailp that happened to end up on
1451 * the done queue. 1452 * the done queue.
1452 * Shouldn't happen, but some chips are broken(?). 1453 * Shouldn't happen, but some chips are broken(?).
1453 */ 1454 */
1454 continue; 1455 continue;
1455 } 1456 }
1456 if (xfer->ux_status == USBD_CANCELLED || 1457
1457 xfer->ux_status == USBD_TIMEOUT) { 1458 /*
1458 DPRINTF("cancel/timeout %p", xfer, 0, 0, 0); 1459 * If software has completed it, either by cancellation
1459 /* Handled by abort routine. */ 1460 * or timeout, drop it on the floor.
 1461 */
 1462 if (xfer->ux_status != USBD_IN_PROGRESS) {
 1463 KASSERT(xfer->ux_status == USBD_CANCELLED ||
 1464 xfer->ux_status == USBD_TIMEOUT);
1460 continue; 1465 continue;
1461 } 1466 }
 1467
 1468 /*
 1469 * Cancel the timeout and the task, which have not yet
 1470 * run. If they have already fired, at worst they are
 1471 * waiting for the lock. They will see that the xfer
 1472 * is no longer in progress and give up.
 1473 */
1462 callout_stop(&xfer->ux_callout); 1474 callout_stop(&xfer->ux_callout);
 1475 usb_rem_task(xfer->ux_pipe->up_dev, &xfer->ux_aborttask);
1463 1476
1464 len = std->len; 1477 len = std->len;
1465 if (std->td.td_cbp != 0) 1478 if (std->td.td_cbp != 0)
1466 len -= O32TOH(std->td.td_be) - 1479 len -= O32TOH(std->td.td_be) -
1467 O32TOH(std->td.td_cbp) + 1; 1480 O32TOH(std->td.td_cbp) + 1;
1468 DPRINTFN(10, "len=%d, flags=0x%x", len, std->flags, 0, 0); 1481 DPRINTFN(10, "len=%d, flags=0x%x", len, std->flags, 0, 0);
1469 if (std->flags & OHCI_ADD_LEN) 1482 if (std->flags & OHCI_ADD_LEN)
1470 xfer->ux_actlen += len; 1483 xfer->ux_actlen += len;
1471 1484
1472 cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags)); 1485 cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags));
1473 if (cc == OHCI_CC_NO_ERROR) { 1486 if (cc == OHCI_CC_NO_ERROR) {
1474 ohci_hash_rem_td(sc, std); 1487 ohci_hash_rem_td(sc, std);
1475 if (std->flags & OHCI_CALL_DONE) { 1488 if (std->flags & OHCI_CALL_DONE) {
@@ -1519,32 +1532,46 @@ ohci_softintr(void *v) @@ -1519,32 +1532,46 @@ ohci_softintr(void *v)
1519 for (sitd = sidone; sitd; sitd = sitd->dnext) 1532 for (sitd = sidone; sitd; sitd = sitd->dnext)
1520 ohci_dump_itd(sc, sitd); 1533 ohci_dump_itd(sc, sitd);
1521 } 1534 }
1522#endif 1535#endif
1523 DPRINTFN(10, "--- ITD dump end ---", 0, 0, 0, 0); 1536 DPRINTFN(10, "--- ITD dump end ---", 0, 0, 0, 0);
1524 1537
1525 for (sitd = sidone; sitd != NULL; sitd = sitdnext) { 1538 for (sitd = sidone; sitd != NULL; sitd = sitdnext) {
1526 xfer = sitd->xfer; 1539 xfer = sitd->xfer;
1527 sitdnext = sitd->dnext; 1540 sitdnext = sitd->dnext;
1528 DPRINTFN(1, "sitd=%p xfer=%p hcpriv=%p", sitd, xfer, 1541 DPRINTFN(1, "sitd=%p xfer=%p hcpriv=%p", sitd, xfer,
1529 xfer ? xfer->ux_hcpriv : 0, 0); 1542 xfer ? xfer->ux_hcpriv : 0, 0);
1530 if (xfer == NULL) 1543 if (xfer == NULL)
1531 continue; 1544 continue;
1532 if (xfer->ux_status == USBD_CANCELLED || 1545
1533 xfer->ux_status == USBD_TIMEOUT) { 1546 /*
1534 DPRINTF("cancel/timeout %p", xfer, 0, 0, 0); 1547 * If software has completed it, either by cancellation
1535 /* Handled by abort routine. */ 1548 * or timeout, drop it on the floor.
 1549 */
 1550 if (xfer->ux_status != USBD_IN_PROGRESS) {
 1551 KASSERT(xfer->ux_status == USBD_CANCELLED ||
 1552 xfer->ux_status == USBD_TIMEOUT);
1536 continue; 1553 continue;
1537 } 1554 }
 1555
 1556 /*
 1557 * Cancel the timeout and the task, which have not yet
 1558 * run. If they have already fired, at worst they are
 1559 * waiting for the lock. They will see that the xfer
 1560 * is no longer in progress and give up.
 1561 */
 1562 callout_stop(&xfer->ux_callout);
 1563 usb_rem_task(xfer->ux_pipe->up_dev, &xfer->ux_aborttask);
 1564
1538 KASSERT(!sitd->isdone); 1565 KASSERT(!sitd->isdone);
1539#ifdef DIAGNOSTIC 1566#ifdef DIAGNOSTIC
1540 sitd->isdone = true; 1567 sitd->isdone = true;
1541#endif 1568#endif
1542 if (sitd->flags & OHCI_CALL_DONE) { 1569 if (sitd->flags & OHCI_CALL_DONE) {
1543 ohci_soft_itd_t *next; 1570 ohci_soft_itd_t *next;
1544 1571
1545 opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); 1572 opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe);
1546 opipe->isoc.inuse -= xfer->ux_nframes; 1573 opipe->isoc.inuse -= xfer->ux_nframes;
1547 uedir = UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc-> 1574 uedir = UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->
1548 bEndpointAddress); 1575 bEndpointAddress);
1549 xfer->ux_status = USBD_NORMAL_COMPLETION; 1576 xfer->ux_status = USBD_NORMAL_COMPLETION;
1550 actlen = 0; 1577 actlen = 0;
@@ -1578,32 +1605,28 @@ ohci_softintr(void *v) @@ -1578,32 +1605,28 @@ ohci_softintr(void *v)
1578 ohci_hash_rem_itd(sc, sitd); 1605 ohci_hash_rem_itd(sc, sitd);
1579 1606
1580 } 1607 }
1581 ohci_hash_rem_itd(sc, sitd); 1608 ohci_hash_rem_itd(sc, sitd);
1582 if (uedir == UE_DIR_IN && 1609 if (uedir == UE_DIR_IN &&
1583 xfer->ux_status == USBD_NORMAL_COMPLETION) 1610 xfer->ux_status == USBD_NORMAL_COMPLETION)
1584 xfer->ux_actlen = actlen; 1611 xfer->ux_actlen = actlen;
1585 xfer->ux_hcpriv = NULL; 1612 xfer->ux_hcpriv = NULL;
1586 1613
1587 usb_transfer_complete(xfer); 1614 usb_transfer_complete(xfer);
1588 } 1615 }
1589 } 1616 }
1590 1617
1591 if (sc->sc_softwake) { 
1592 sc->sc_softwake = 0; 
1593 cv_broadcast(&sc->sc_softwake_cv); 
1594 } 
1595 
1596 DPRINTFN(10, "done", 0, 0, 0, 0); 1618 DPRINTFN(10, "done", 0, 0, 0, 0);
 1619 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1597} 1620}
1598 1621
1599void 1622void
1600ohci_device_ctrl_done(struct usbd_xfer *xfer) 1623ohci_device_ctrl_done(struct usbd_xfer *xfer)
1601{ 1624{
1602 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); 1625 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe);
1603 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); 1626 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer);
1604 int len = UGETW(xfer->ux_request.wLength); 1627 int len = UGETW(xfer->ux_request.wLength);
1605 int isread = (xfer->ux_request.bmRequestType & UT_READ); 1628 int isread = (xfer->ux_request.bmRequestType & UT_READ);
1606 1629
1607 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 1630 OHCIHIST_FUNC(); OHCIHIST_CALLED();
1608 DPRINTFN(10, "xfer=%p", xfer, 0, 0, 0); 1631 DPRINTFN(10, "xfer=%p", xfer, 0, 0, 0);
1609 1632
@@ -1866,45 +1889,37 @@ ohci_hash_find_itd(ohci_softc_t *sc, ohc @@ -1866,45 +1889,37 @@ ohci_hash_find_itd(ohci_softc_t *sc, ohc
1866 ohci_soft_itd_t *sitd; 1889 ohci_soft_itd_t *sitd;
1867 1890
1868 for (sitd = LIST_FIRST(&sc->sc_hash_itds[h]); 1891 for (sitd = LIST_FIRST(&sc->sc_hash_itds[h]);
1869 sitd != NULL; 1892 sitd != NULL;
1870 sitd = LIST_NEXT(sitd, hnext)) 1893 sitd = LIST_NEXT(sitd, hnext))
1871 if (sitd->physaddr == a) 1894 if (sitd->physaddr == a)
1872 return sitd; 1895 return sitd;
1873 return NULL; 1896 return NULL;
1874} 1897}
1875 1898
1876void 1899void
1877ohci_timeout(void *addr) 1900ohci_timeout(void *addr)
1878{ 1901{
 1902 OHCIHIST_FUNC(); OHCIHIST_CALLED();
1879 struct usbd_xfer *xfer = addr; 1903 struct usbd_xfer *xfer = addr;
1880 struct ohci_xfer *oxfer = OHCI_XFER2OXFER(xfer); 
1881 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 1904 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
 1905 struct usbd_device *dev = xfer->ux_pipe->up_dev;
1882 1906
1883 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 1907 DPRINTF("xfer=%p", xfer, 0, 0, 0);
1884 DPRINTF("oxfer=%p", oxfer, 0, 0, 0); 
1885 
1886 if (sc->sc_dying) { 
1887 mutex_enter(&sc->sc_lock); 
1888 ohci_abort_xfer(xfer, USBD_TIMEOUT); 
1889 mutex_exit(&sc->sc_lock); 
1890 return; 
1891 } 
1892 1908
1893 /* Execute the abort in a process context. */ 1909 mutex_enter(&sc->sc_lock);
1894 usb_init_task(&oxfer->abort_task, ohci_timeout_task, addr, 1910 if (!sc->sc_dying && xfer->ux_status == USBD_IN_PROGRESS)
1895 USB_TASKQ_MPSAFE); 1911 usb_add_task(dev, &xfer->ux_aborttask, USB_TASKQ_HC);
1896 usb_add_task(xfer->ux_pipe->up_dev, &oxfer->abort_task, 1912 mutex_exit(&sc->sc_lock);
1897 USB_TASKQ_HC); 
1898} 1913}
1899 1914
1900void 1915void
1901ohci_timeout_task(void *addr) 1916ohci_timeout_task(void *addr)
1902{ 1917{
1903 struct usbd_xfer *xfer = addr; 1918 struct usbd_xfer *xfer = addr;
1904 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 1919 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
1905 1920
1906 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 1921 OHCIHIST_FUNC(); OHCIHIST_CALLED();
1907 1922
1908 DPRINTF("xfer=%p", xfer, 0, 0, 0); 1923 DPRINTF("xfer=%p", xfer, 0, 0, 0);
1909 1924
1910 mutex_enter(&sc->sc_lock); 1925 mutex_enter(&sc->sc_lock);
@@ -2174,109 +2189,133 @@ ohci_close_pipe(struct usbd_pipe *pipe,  @@ -2174,109 +2189,133 @@ ohci_close_pipe(struct usbd_pipe *pipe,
2174 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) 2189 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK))
2175 printf("ohci_close_pipe: pipe still not empty\n"); 2190 printf("ohci_close_pipe: pipe still not empty\n");
2176 } 2191 }
2177#endif 2192#endif
2178 ohci_rem_ed(sc, sed, head); 2193 ohci_rem_ed(sc, sed, head);
2179 /* Make sure the host controller is not touching this ED */ 2194 /* Make sure the host controller is not touching this ED */
2180 usb_delay_ms(&sc->sc_bus, 1); 2195 usb_delay_ms(&sc->sc_bus, 1);
2181 pipe->up_endpoint->ue_toggle = 2196 pipe->up_endpoint->ue_toggle =
2182 (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0; 2197 (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0;
2183 ohci_free_sed_locked(sc, opipe->sed); 2198 ohci_free_sed_locked(sc, opipe->sed);
2184} 2199}
2185 2200
2186/* 2201/*
2187 * Abort a device request. 2202 * Cancel or timeout a device request. We have two cases to deal with
2188 * If this routine is called at splusb() it guarantees that the request 2203 *
2189 * will be removed from the hardware scheduling and that the callback 2204 * 1) A driver wants to stop scheduled or inflight transfers
2190 * for it will be called with USBD_CANCELLED status. 2205 * 2) A transfer has timed out
 2206 *
2191 * It's impossible to guarantee that the requested transfer will not 2207 * It's impossible to guarantee that the requested transfer will not
2192 * have happened since the hardware runs concurrently. 2208 * have (partially) happened since the hardware runs concurrently.
2193 * If the transaction has already happened we rely on the ordinary 2209 *
2194 * interrupt processing to process it. 2210 * Transfer state is protected by the bus lock and we set the transfer status
2195 * XXX This is most probably wrong. 2211 * as soon as either of the above happens (with bus lock held).
2196 * XXXMRG this doesn't make sense anymore. 2212 *
 2213 * Then we arrange for the hardware to tells us that it is not still
 2214 * processing the TDs by setting the sKip bit and requesting a SOF interrupt
 2215 *
 2216 * Once we see the SOF interrupt we can check the transfer TDs/iTDs to see if
 2217 * they've been processed and either
 2218 * a) if they're unused recover them for later use, or
 2219 * b) if they've been used allocate new TD/iTDs to replace those
 2220 * used. The softint handler will free the old ones.
2197 */ 2221 */
2198void 2222void
2199ohci_abort_xfer(struct usbd_xfer *xfer, usbd_status status) 2223ohci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
2200{ 2224{
 2225 OHCIHIST_FUNC(); OHCIHIST_CALLED();
2201 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); 2226 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe);
2202 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 2227 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
2203 ohci_soft_ed_t *sed = opipe->sed; 2228 ohci_soft_ed_t *sed = opipe->sed;
2204 ohci_soft_td_t *p, *n; 2229 ohci_soft_td_t *p, *n;
2205 ohci_physaddr_t headp; 2230 ohci_physaddr_t headp;
2206 int hit; 2231 int hit;
2207 int wake; 
2208 2232
2209 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 2233 KASSERTMSG((status == USBD_CANCELLED || status == USBD_TIMEOUT),
 2234 "invalid status for abort: %d", (int)status);
 2235
2210 DPRINTF("xfer=%p pipe=%p sed=%p", xfer, opipe,sed, 0); 2236 DPRINTF("xfer=%p pipe=%p sed=%p", xfer, opipe,sed, 0);
2211 2237
2212 KASSERT(mutex_owned(&sc->sc_lock)); 2238 KASSERT(mutex_owned(&sc->sc_lock));
2213 ASSERT_SLEEPABLE(); 2239 ASSERT_SLEEPABLE();
2214 2240
2215 if (sc->sc_dying) { 2241 if (status == USBD_CANCELLED) {
2216 /* If we're dying, just do the software part. */ 2242 /*
2217 xfer->ux_status = status; /* make software ignore it */ 2243 * We are synchronously aborting. Try to stop the
 2244 * callout and task, but if we can't, wait for them to
 2245 * complete.
 2246 */
2218 callout_halt(&xfer->ux_callout, &sc->sc_lock); 2247 callout_halt(&xfer->ux_callout, &sc->sc_lock);
2219 usb_transfer_complete(xfer); 2248 usb_rem_task_wait(xfer->ux_pipe->up_dev, &xfer->ux_aborttask,
2220 return; 2249 USB_TASKQ_HC, &sc->sc_lock);
 2250 } else {
 2251 /* Otherwise, we are timing out. */
 2252 KASSERT(status == USBD_TIMEOUT);
2221 } 2253 }
2222 2254
2223 /* 2255 /*
2224 * If an abort is already in progress then just wait for it to 2256 * The xfer cannot have been cancelled already. It is the
2225 * complete and return. 2257 * responsibility of the caller of usbd_abort_pipe not to try
 2258 * to abort a pipe multiple times, whether concurrently or
 2259 * sequentially.
2226 */ 2260 */
2227 if (xfer->ux_hcflags & UXFER_ABORTING) { 2261 KASSERT(xfer->ux_status != USBD_CANCELLED);
2228 DPRINTFN(2, "already aborting", 0, 0, 0, 0); 2262
2229#ifdef DIAGNOSTIC 2263 /* Only the timeout, which runs only once, can time it out. */
2230 if (status == USBD_TIMEOUT) 2264 KASSERT(xfer->ux_status != USBD_TIMEOUT);
2231 printf("%s: TIMEOUT while aborting\n", __func__); 2265
2232#endif 2266 /* If anyone else beat us, we're done. */
2233 /* Override the status which might be USBD_TIMEOUT. */ 2267 if (xfer->ux_status != USBD_IN_PROGRESS)
2234 xfer->ux_status = status; 2268 return;
2235 DPRINTFN(2, "waiting for abort to finish", 0, 0, 0, 0); 2269
2236 xfer->ux_hcflags |= UXFER_ABORTWAIT; 2270 /* We beat everyone else. Claim the status. */
2237 while (xfer->ux_hcflags & UXFER_ABORTING) 2271 xfer->ux_status = status;
2238 cv_wait(&xfer->ux_hccv, &sc->sc_lock); 2272
2239 goto done; 2273 /*
 2274 * If we're dying, skip the hardware action and just notify the
 2275 * software that we're done.
 2276 */
 2277 if (sc->sc_dying) {
 2278 DPRINTFN(4, "xfer %#jx dying %ju", (uintptr_t)xfer,
 2279 xfer->ux_status, 0, 0);
 2280 goto dying;
2240 } 2281 }
2241 xfer->ux_hcflags |= UXFER_ABORTING; 
2242 2282
2243 /* 2283 /*
2244 * Step 1: Make interrupt routine and hardware ignore xfer. 2284 * HC Step 1: Unless the endpoint is already halted, we set the endpoint
 2285 * descriptor sKip bit and wait for hardware to complete processing.
 2286 *
 2287 * This includes ensuring that any TDs of the transfer that got onto
 2288 * the done list are also removed. We ensure this by waiting for
 2289 * both a WDH and SOF interrupt.
2245 */ 2290 */
2246 xfer->ux_status = status; /* make software ignore it */ 
2247 callout_stop(&xfer->ux_callout); 
2248 DPRINTFN(1, "stop ed=%p", sed, 0, 0, 0); 2291 DPRINTFN(1, "stop ed=%p", sed, 0, 0, 0);
2249 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2292 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
2250 sizeof(sed->ed.ed_flags), 2293 sizeof(sed->ed.ed_flags),
2251 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2294 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
2252 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */ 2295 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */
2253 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2296 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
2254 sizeof(sed->ed.ed_flags), 2297 sizeof(sed->ed.ed_flags),
2255 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2298 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2256 2299
2257 /* 2300 /*
2258 * Step 2: Wait until we know hardware has finished any possible 2301 * HC Step 2: Wait until we know hardware has finished any possible
2259 * use of the xfer. Also make sure the soft interrupt routine 2302 * use of the xfer.
2260 * has run. 
2261 */ 2303 */
2262 /* Hardware finishes in 1ms */ 2304 /* Hardware finishes in 1ms */
2263 usb_delay_ms_locked(opipe->pipe.up_dev->ud_bus, 20, &sc->sc_lock); 2305 usb_delay_ms_locked(opipe->pipe.up_dev->ud_bus, 20, &sc->sc_lock);
2264 sc->sc_softwake = 1; 
2265 usb_schedsoftintr(&sc->sc_bus); 
2266 cv_wait(&sc->sc_softwake_cv, &sc->sc_lock); 
2267 2306
2268 /* 2307 /*
2269 * Step 3: Remove any vestiges of the xfer from the hardware. 2308 * HC Step 3: Remove any vestiges of the xfer from the hardware.
2270 * The complication here is that the hardware may have executed 2309 * The complication here is that the hardware may have executed
2271 * beyond the xfer we're trying to abort. So as we're scanning 2310 * beyond the xfer we're trying to abort. So as we're scanning
2272 * the TDs of this xfer we check if the hardware points to 2311 * the TDs of this xfer we check if the hardware points to
2273 * any of them. 2312 * any of them.
2274 */ 2313 */
2275 p = xfer->ux_hcpriv; 2314 p = xfer->ux_hcpriv;
2276 KASSERT(p); 2315 KASSERT(p);
2277 2316
2278#ifdef OHCI_DEBUG 2317#ifdef OHCI_DEBUG
2279 DPRINTF("--- dump start ---", 0, 0, 0, 0); 2318 DPRINTF("--- dump start ---", 0, 0, 0, 0);
2280 2319
2281 if (ohcidebug >= 2) { 2320 if (ohcidebug >= 2) {
2282 DPRINTF("sed:", 0, 0, 0, 0); 2321 DPRINTF("sed:", 0, 0, 0, 0);
@@ -2296,46 +2335,43 @@ ohci_abort_xfer(struct usbd_xfer *xfer,  @@ -2296,46 +2335,43 @@ ohci_abort_xfer(struct usbd_xfer *xfer,
2296 if (hit) { 2335 if (hit) {
2297 DPRINTFN(1, "set hd=0x%08x, tl=0x%08x", (int)p->physaddr, 2336 DPRINTFN(1, "set hd=0x%08x, tl=0x%08x", (int)p->physaddr,
2298 (int)O32TOH(sed->ed.ed_tailp), 0, 0); 2337 (int)O32TOH(sed->ed.ed_tailp), 0, 0);
2299 sed->ed.ed_headp = HTOO32(p->physaddr); /* unlink TDs */ 2338 sed->ed.ed_headp = HTOO32(p->physaddr); /* unlink TDs */
2300 usb_syncmem(&sed->dma, 2339 usb_syncmem(&sed->dma,
2301 sed->offs + offsetof(ohci_ed_t, ed_headp), 2340 sed->offs + offsetof(ohci_ed_t, ed_headp),
2302 sizeof(sed->ed.ed_headp), 2341 sizeof(sed->ed.ed_headp),
2303 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2342 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2304 } else { 2343 } else {
2305 DPRINTFN(1, "no hit", 0, 0, 0, 0); 2344 DPRINTFN(1, "no hit", 0, 0, 0, 0);
2306 } 2345 }
2307 2346
2308 /* 2347 /*
2309 * Step 4: Turn on hardware again. 2348 * HC Step 4: Turn on hardware again.
2310 */ 2349 */
2311 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2350 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
2312 sizeof(sed->ed.ed_flags), 2351 sizeof(sed->ed.ed_flags),
2313 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2352 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
2314 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */ 2353 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */
2315 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2354 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
2316 sizeof(sed->ed.ed_flags), 2355 sizeof(sed->ed.ed_flags),
2317 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2356 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2318 2357
2319 /* 2358 /*
2320 * Step 5: Execute callback. 2359 * Final step: Notify completion to waiting xfers.
2321 */ 2360 */
2322 wake = xfer->ux_hcflags & UXFER_ABORTWAIT; 2361dying:
2323 xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); 
2324 usb_transfer_complete(xfer); 2362 usb_transfer_complete(xfer);
2325 if (wake) 2363 DPRINTFN(14, "end", 0, 0, 0, 0);
2326 cv_broadcast(&xfer->ux_hccv); 
2327 2364
2328done: 
2329 KASSERT(mutex_owned(&sc->sc_lock)); 2365 KASSERT(mutex_owned(&sc->sc_lock));
2330} 2366}
2331 2367
2332/* 2368/*
2333 * Data structures and routines to emulate the root hub. 2369 * Data structures and routines to emulate the root hub.
2334 */ 2370 */
2335Static int 2371Static int
2336ohci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 2372ohci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
2337 void *buf, int buflen) 2373 void *buf, int buflen)
2338{ 2374{
2339 ohci_softc_t *sc = OHCI_BUS2SC(bus); 2375 ohci_softc_t *sc = OHCI_BUS2SC(bus);
2340 usb_port_status_t ps; 2376 usb_port_status_t ps;
2341 uint16_t len, value, index; 2377 uint16_t len, value, index;
@@ -2830,26 +2866,27 @@ ohci_device_ctrl_start(struct usbd_xfer  @@ -2830,26 +2866,27 @@ ohci_device_ctrl_start(struct usbd_xfer
2830 sed->ed.ed_tailp = HTOO32(tail->physaddr); 2866 sed->ed.ed_tailp = HTOO32(tail->physaddr);
2831 usb_syncmem(&sed->dma, 2867 usb_syncmem(&sed->dma,
2832 sed->offs + offsetof(ohci_ed_t, ed_tailp), 2868 sed->offs + offsetof(ohci_ed_t, ed_tailp),
2833 sizeof(sed->ed.ed_tailp), 2869 sizeof(sed->ed.ed_tailp),
2834 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2870 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2835 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); 2871 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
2836 if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { 2872 if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) {
2837 callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), 2873 callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout),
2838 ohci_timeout, xfer); 2874 ohci_timeout, xfer);
2839 } 2875 }
2840 2876
2841 DPRINTF("done", 0, 0, 0, 0); 2877 DPRINTF("done", 0, 0, 0, 0);
2842 2878
 2879 xfer->ux_status = USBD_IN_PROGRESS;
2843 mutex_exit(&sc->sc_lock); 2880 mutex_exit(&sc->sc_lock);
2844 2881
2845 return USBD_IN_PROGRESS; 2882 return USBD_IN_PROGRESS;
2846} 2883}
2847 2884
2848/* Abort a device control request. */ 2885/* Abort a device control request. */
2849Static void 2886Static void
2850ohci_device_ctrl_abort(struct usbd_xfer *xfer) 2887ohci_device_ctrl_abort(struct usbd_xfer *xfer)
2851{ 2888{
2852 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); 2889 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer);
2853 2890
2854 KASSERT(mutex_owned(&sc->sc_lock)); 2891 KASSERT(mutex_owned(&sc->sc_lock));
2855 2892
@@ -3037,26 +3074,28 @@ ohci_device_bulk_start(struct usbd_xfer  @@ -3037,26 +3074,28 @@ ohci_device_bulk_start(struct usbd_xfer
3037 KASSERT(tdp->xfer == xfer); 3074 KASSERT(tdp->xfer == xfer);
3038 } 3075 }
3039 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3076 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3040 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3077 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3041 sed->ed.ed_tailp = HTOO32(tail->physaddr); 3078 sed->ed.ed_tailp = HTOO32(tail->physaddr);
3042 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3079 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3043 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3080 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3044 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3081 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3045 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF); 3082 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
3046 if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { 3083 if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) {
3047 callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), 3084 callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout),
3048 ohci_timeout, xfer); 3085 ohci_timeout, xfer);
3049 } 3086 }
 3087
 3088 xfer->ux_status = USBD_IN_PROGRESS;
3050 mutex_exit(&sc->sc_lock); 3089 mutex_exit(&sc->sc_lock);
3051 3090
3052 return USBD_IN_PROGRESS; 3091 return USBD_IN_PROGRESS;
3053} 3092}
3054 3093
3055Static void 3094Static void
3056ohci_device_bulk_abort(struct usbd_xfer *xfer) 3095ohci_device_bulk_abort(struct usbd_xfer *xfer)
3057{ 3096{
3058 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); 3097 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer);
3059 3098
3060 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 3099 OHCIHIST_FUNC(); OHCIHIST_CALLED();
3061 3100
3062 KASSERT(mutex_owned(&sc->sc_lock)); 3101 KASSERT(mutex_owned(&sc->sc_lock));
@@ -3221,26 +3260,27 @@ ohci_device_intr_start(struct usbd_xfer  @@ -3221,26 +3260,27 @@ ohci_device_intr_start(struct usbd_xfer
3221 ohci_dump_tds(sc, data); 3260 ohci_dump_tds(sc, data);
3222 } 3261 }
3223 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); 3262 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0);
3224#endif 3263#endif
3225 3264
3226 /* Insert ED in schedule */ 3265 /* Insert ED in schedule */
3227 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3266 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3228 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3267 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3229 sed->ed.ed_tailp = HTOO32(tail->physaddr); 3268 sed->ed.ed_tailp = HTOO32(tail->physaddr);
3230 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3269 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3231 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3270 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3232 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3271 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3233 3272
 3273 xfer->ux_status = USBD_IN_PROGRESS;
3234 mutex_exit(&sc->sc_lock); 3274 mutex_exit(&sc->sc_lock);
3235 3275
3236 return USBD_IN_PROGRESS; 3276 return USBD_IN_PROGRESS;
3237} 3277}
3238 3278
3239/* Abort a device interrupt request. */ 3279/* Abort a device interrupt request. */
3240Static void 3280Static void
3241ohci_device_intr_abort(struct usbd_xfer *xfer) 3281ohci_device_intr_abort(struct usbd_xfer *xfer)
3242{ 3282{
3243 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); 3283 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer);
3244 3284
3245 KASSERT(mutex_owned(&sc->sc_lock)); 3285 KASSERT(mutex_owned(&sc->sc_lock));
3246 KASSERT(xfer->ux_pipe->up_intrxfer == xfer); 3286 KASSERT(xfer->ux_pipe->up_intrxfer == xfer);

cvs diff -r1.55.4.1 -r1.55.4.2 src/sys/dev/usb/ohcivar.h (expand / switch to unified diff)

--- src/sys/dev/usb/ohcivar.h 2017/04/05 19:54:19 1.55.4.1
+++ src/sys/dev/usb/ohcivar.h 2018/08/25 14:57:35 1.55.4.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ohcivar.h,v 1.55.4.1 2017/04/05 19:54:19 snj Exp $ */ 1/* $NetBSD: ohcivar.h,v 1.55.4.2 2018/08/25 14:57:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998 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
@@ -108,54 +108,50 @@ typedef struct ohci_softc { @@ -108,54 +108,50 @@ typedef struct ohci_softc {
108 LIST_HEAD(, ohci_soft_td) sc_hash_tds[OHCI_HASH_SIZE]; 108 LIST_HEAD(, ohci_soft_td) sc_hash_tds[OHCI_HASH_SIZE];
109 LIST_HEAD(, ohci_soft_itd) sc_hash_itds[OHCI_HASH_SIZE]; 109 LIST_HEAD(, ohci_soft_itd) sc_hash_itds[OHCI_HASH_SIZE];
110 110
111 int sc_noport; 111 int sc_noport;
112 112
113 int sc_endian; 113 int sc_endian;
114#define OHCI_LITTLE_ENDIAN 0 /* typical (uninitialized default) */ 114#define OHCI_LITTLE_ENDIAN 0 /* typical (uninitialized default) */
115#define OHCI_BIG_ENDIAN 1 /* big endian OHCI? never seen it */ 115#define OHCI_BIG_ENDIAN 1 /* big endian OHCI? never seen it */
116#define OHCI_HOST_ENDIAN 2 /* if OHCI always matches CPU */ 116#define OHCI_HOST_ENDIAN 2 /* if OHCI always matches CPU */
117 117
118 int sc_flags; 118 int sc_flags;
119#define OHCIF_SUPERIO 0x0001 119#define OHCIF_SUPERIO 0x0001
120 120
121 char sc_softwake; 
122 kcondvar_t sc_softwake_cv; 
123 
124 ohci_soft_ed_t *sc_freeeds; 121 ohci_soft_ed_t *sc_freeeds;
125 ohci_soft_td_t *sc_freetds; 122 ohci_soft_td_t *sc_freetds;
126 ohci_soft_itd_t *sc_freeitds; 123 ohci_soft_itd_t *sc_freeitds;
127 124
128 pool_cache_t sc_xferpool; /* free xfer pool */ 125 pool_cache_t sc_xferpool; /* free xfer pool */
129 126
130 struct usbd_xfer *sc_intrxfer; 127 struct usbd_xfer *sc_intrxfer;
131 128
132 char sc_vendor[32]; 129 char sc_vendor[32];
133 int sc_id_vendor; 130 int sc_id_vendor;
134 131
135 uint32_t sc_control; /* Preserved during suspend/standby */ 132 uint32_t sc_control; /* Preserved during suspend/standby */
136 uint32_t sc_intre; 133 uint32_t sc_intre;
137 134
138 u_int sc_overrun_cnt; 135 u_int sc_overrun_cnt;
139 struct timeval sc_overrun_ntc; 136 struct timeval sc_overrun_ntc;
140 137
141 struct callout sc_tmo_rhsc; 138 struct callout sc_tmo_rhsc;
142 device_t sc_child; 139 device_t sc_child;
143 char sc_dying; 140 char sc_dying;
144} ohci_softc_t; 141} ohci_softc_t;
145 142
146struct ohci_xfer { 143struct ohci_xfer {
147 struct usbd_xfer xfer; 144 struct usbd_xfer xfer;
148 struct usb_task abort_task; 
149 /* ctrl */ 145 /* ctrl */
150 ohci_soft_td_t *ox_setup; 146 ohci_soft_td_t *ox_setup;
151 ohci_soft_td_t *ox_stat; 147 ohci_soft_td_t *ox_stat;
152 union { 148 union {
153 /* ctrl/bulk/intr */ 149 /* ctrl/bulk/intr */
154 struct { 150 struct {
155 ohci_soft_td_t **ox_stds; 151 ohci_soft_td_t **ox_stds;
156 size_t ox_nstd; 152 size_t ox_nstd;
157 }; 153 };
158 /* isoc */ 154 /* isoc */
159 struct { 155 struct {
160 ohci_soft_itd_t **ox_sitds; 156 ohci_soft_itd_t **ox_sitds;
161 size_t ox_nsitd; 157 size_t ox_nsitd;

cvs diff -r1.264.2.3 -r1.264.2.4 src/sys/dev/usb/uhci.c (expand / switch to unified diff)

--- src/sys/dev/usb/uhci.c 2018/01/03 20:02:37 1.264.2.3
+++ src/sys/dev/usb/uhci.c 2018/08/25 14:57:35 1.264.2.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: uhci.c,v 1.264.2.3 2018/01/03 20:02:37 snj Exp $ */ 1/* $NetBSD: uhci.c,v 1.264.2.4 2018/08/25 14:57:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2004, 2011, 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) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca) 9 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca)
10 * and Matthew R. Green (mrg@eterna.com.au). 10 * 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:
@@ -32,27 +32,27 @@ @@ -32,27 +32,27 @@
32 */ 32 */
33 33
34/* 34/*
35 * USB Universal Host Controller driver. 35 * USB Universal Host Controller driver.
36 * Handles e.g. PIIX3 and PIIX4. 36 * Handles e.g. PIIX3 and PIIX4.
37 * 37 *
38 * UHCI spec: http://www.intel.com/technology/usb/spec.htm 38 * UHCI spec: http://www.intel.com/technology/usb/spec.htm
39 * USB spec: http://www.usb.org/developers/docs/ 39 * USB spec: http://www.usb.org/developers/docs/
40 * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf 40 * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf
41 * ftp://download.intel.com/design/intarch/datashts/29056201.pdf 41 * ftp://download.intel.com/design/intarch/datashts/29056201.pdf
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.264.2.3 2018/01/03 20:02:37 snj Exp $"); 45__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.264.2.4 2018/08/25 14:57:35 martin Exp $");
46 46
47#ifdef _KERNEL_OPT 47#ifdef _KERNEL_OPT
48#include "opt_usb.h" 48#include "opt_usb.h"
49#endif 49#endif
50 50
51#include <sys/param.h> 51#include <sys/param.h>
52 52
53#include <sys/bus.h> 53#include <sys/bus.h>
54#include <sys/cpu.h> 54#include <sys/cpu.h>
55#include <sys/device.h> 55#include <sys/device.h>
56#include <sys/kernel.h> 56#include <sys/kernel.h>
57#include <sys/kmem.h> 57#include <sys/kmem.h>
58#include <sys/mutex.h> 58#include <sys/mutex.h>
@@ -564,28 +564,26 @@ uhci_init(uhci_softc_t *sc) @@ -564,28 +564,26 @@ uhci_init(uhci_softc_t *sc)
564 } 564 }
565 usb_syncmem(&sc->sc_dma, 0, 565 usb_syncmem(&sc->sc_dma, 0,
566 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), 566 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
567 BUS_DMASYNC_PREWRITE); 567 BUS_DMASYNC_PREWRITE);
568 568
569 569
570 TAILQ_INIT(&sc->sc_intrhead); 570 TAILQ_INIT(&sc->sc_intrhead);
571 571
572 sc->sc_xferpool = pool_cache_init(sizeof(struct uhci_xfer), 0, 0, 0, 572 sc->sc_xferpool = pool_cache_init(sizeof(struct uhci_xfer), 0, 0, 0,
573 "uhcixfer", NULL, IPL_USB, NULL, NULL, NULL); 573 "uhcixfer", NULL, IPL_USB, NULL, NULL, NULL);
574 574
575 callout_init(&sc->sc_poll_handle, CALLOUT_MPSAFE); 575 callout_init(&sc->sc_poll_handle, CALLOUT_MPSAFE);
576 576
577 cv_init(&sc->sc_softwake_cv, "uhciab"); 
578 
579 /* Set up the bus struct. */ 577 /* Set up the bus struct. */
580 sc->sc_bus.ub_methods = &uhci_bus_methods; 578 sc->sc_bus.ub_methods = &uhci_bus_methods;
581 sc->sc_bus.ub_pipesize = sizeof(struct uhci_pipe); 579 sc->sc_bus.ub_pipesize = sizeof(struct uhci_pipe);
582 sc->sc_bus.ub_usedma = true; 580 sc->sc_bus.ub_usedma = true;
583 581
584 UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */ 582 UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */
585 583
586 DPRINTF("Enabling...", 0, 0, 0, 0); 584 DPRINTF("Enabling...", 0, 0, 0, 0);
587 585
588 err = uhci_run(sc, 1, 0); /* and here we go... */ 586 err = uhci_run(sc, 1, 0); /* and here we go... */
589 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | 587 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
590 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */ 588 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */
591 return err; 589 return err;
@@ -629,48 +627,49 @@ int @@ -629,48 +627,49 @@ int
629uhci_detach(struct uhci_softc *sc, int flags) 627uhci_detach(struct uhci_softc *sc, int flags)
630{ 628{
631 int rv = 0; 629 int rv = 0;
632 630
633 if (sc->sc_child != NULL) 631 if (sc->sc_child != NULL)
634 rv = config_detach(sc->sc_child, flags); 632 rv = config_detach(sc->sc_child, flags);
635 633
636 if (rv != 0) 634 if (rv != 0)
637 return rv; 635 return rv;
638 636
639 callout_halt(&sc->sc_poll_handle, NULL); 637 callout_halt(&sc->sc_poll_handle, NULL);
640 callout_destroy(&sc->sc_poll_handle); 638 callout_destroy(&sc->sc_poll_handle);
641 639
642 cv_destroy(&sc->sc_softwake_cv); 
643 
644 mutex_destroy(&sc->sc_lock); 640 mutex_destroy(&sc->sc_lock);
645 mutex_destroy(&sc->sc_intr_lock); 641 mutex_destroy(&sc->sc_intr_lock);
646 642
647 pool_cache_destroy(sc->sc_xferpool); 643 pool_cache_destroy(sc->sc_xferpool);
648 644
649 /* XXX free other data structures XXX */ 645 /* XXX free other data structures XXX */
650 646
651 return rv; 647 return rv;
652} 648}
653 649
654struct usbd_xfer * 650struct usbd_xfer *
655uhci_allocx(struct usbd_bus *bus, unsigned int nframes) 651uhci_allocx(struct usbd_bus *bus, unsigned int nframes)
656{ 652{
657 struct uhci_softc *sc = UHCI_BUS2SC(bus); 653 struct uhci_softc *sc = UHCI_BUS2SC(bus);
658 struct usbd_xfer *xfer; 654 struct usbd_xfer *xfer;
659 655
660 xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK); 656 xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK);
661 if (xfer != NULL) { 657 if (xfer != NULL) {
662 memset(xfer, 0, sizeof(struct uhci_xfer)); 658 memset(xfer, 0, sizeof(struct uhci_xfer));
663 659
 660 /* Initialise this always so we can call remove on it. */
 661 usb_init_task(&xfer->ux_aborttask, uhci_timeout_task, xfer,
 662 USB_TASKQ_MPSAFE);
664#ifdef DIAGNOSTIC 663#ifdef DIAGNOSTIC
665 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); 664 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer);
666 uxfer->ux_isdone = true; 665 uxfer->ux_isdone = true;
667 xfer->ux_state = XFER_BUSY; 666 xfer->ux_state = XFER_BUSY;
668#endif 667#endif
669 } 668 }
670 return xfer; 669 return xfer;
671} 670}
672 671
673void 672void
674uhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) 673uhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
675{ 674{
676 struct uhci_softc *sc = UHCI_BUS2SC(bus); 675 struct uhci_softc *sc = UHCI_BUS2SC(bus);
@@ -1413,30 +1412,27 @@ uhci_softintr(void *v) @@ -1413,30 +1412,27 @@ uhci_softintr(void *v)
1413 uhci_check_intr(sc, ux, &cq); 1412 uhci_check_intr(sc, ux, &cq);
1414 } 1413 }
1415 1414
1416 /* 1415 /*
1417 * We abuse ux_list for the interrupt and complete lists and 1416 * We abuse ux_list for the interrupt and complete lists and
1418 * interrupt transfers will get re-added here so use 1417 * interrupt transfers will get re-added here so use
1419 * the _SAFE version of TAILQ_FOREACH. 1418 * the _SAFE version of TAILQ_FOREACH.
1420 */ 1419 */
1421 TAILQ_FOREACH_SAFE(ux, &cq, ux_list, nextux) { 1420 TAILQ_FOREACH_SAFE(ux, &cq, ux_list, nextux) {
1422 DPRINTF("ux %p", ux, 0, 0, 0); 1421 DPRINTF("ux %p", ux, 0, 0, 0);
1423 usb_transfer_complete(&ux->ux_xfer); 1422 usb_transfer_complete(&ux->ux_xfer);
1424 } 1423 }
1425 1424
1426 if (sc->sc_softwake) { 1425 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1427 sc->sc_softwake = 0; 
1428 cv_broadcast(&sc->sc_softwake_cv); 
1429 } 
1430} 1426}
1431 1427
1432/* Check for an interrupt. */ 1428/* Check for an interrupt. */
1433void 1429void
1434uhci_check_intr(uhci_softc_t *sc, struct uhci_xfer *ux, ux_completeq_t *cqp) 1430uhci_check_intr(uhci_softc_t *sc, struct uhci_xfer *ux, ux_completeq_t *cqp)
1435{ 1431{
1436 uhci_soft_td_t *std, *fstd = NULL, *lstd = NULL; 1432 uhci_soft_td_t *std, *fstd = NULL, *lstd = NULL;
1437 uint32_t status; 1433 uint32_t status;
1438 1434
1439 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1435 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1440 DPRINTFN(15, "ux %p", ux, 0, 0, 0); 1436 DPRINTFN(15, "ux %p", ux, 0, 0, 0);
1441 1437
1442 KASSERT(ux != NULL); 1438 KASSERT(ux != NULL);
@@ -1472,28 +1468,26 @@ uhci_check_intr(uhci_softc_t *sc, struct @@ -1472,28 +1468,26 @@ uhci_check_intr(uhci_softc_t *sc, struct
1472 lstd->offs + offsetof(uhci_td_t, td_status), 1468 lstd->offs + offsetof(uhci_td_t, td_status),
1473 sizeof(lstd->td.td_status), 1469 sizeof(lstd->td.td_status),
1474 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1470 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1475 status = le32toh(lstd->td.td_status); 1471 status = le32toh(lstd->td.td_status);
1476 usb_syncmem(&lstd->dma, 1472 usb_syncmem(&lstd->dma,
1477 lstd->offs + offsetof(uhci_td_t, td_status), 1473 lstd->offs + offsetof(uhci_td_t, td_status),
1478 sizeof(lstd->td.td_status), 1474 sizeof(lstd->td.td_status),
1479 BUS_DMASYNC_PREREAD); 1475 BUS_DMASYNC_PREREAD);
1480 1476
1481 /* If the last TD is not marked active we can complete */ 1477 /* If the last TD is not marked active we can complete */
1482 if (!(status & UHCI_TD_ACTIVE)) { 1478 if (!(status & UHCI_TD_ACTIVE)) {
1483 done: 1479 done:
1484 DPRINTFN(12, "ux=%p done", ux, 0, 0, 0); 1480 DPRINTFN(12, "ux=%p done", ux, 0, 0, 0);
1485 
1486 callout_stop(&xfer->ux_callout); 
1487 uhci_idone(ux, cqp); 1481 uhci_idone(ux, cqp);
1488 return; 1482 return;
1489 } 1483 }
1490 1484
1491 /* 1485 /*
1492 * If the last TD is still active we need to check whether there 1486 * If the last TD is still active we need to check whether there
1493 * is an error somewhere in the middle, or whether there was a 1487 * is an error somewhere in the middle, or whether there was a
1494 * short packet (SPD and not ACTIVE). 1488 * short packet (SPD and not ACTIVE).
1495 */ 1489 */
1496 DPRINTFN(12, "active ux=%p", ux, 0, 0, 0); 1490 DPRINTFN(12, "active ux=%p", ux, 0, 0, 0);
1497 for (std = fstd; std != lstd; std = std->link.std) { 1491 for (std = fstd; std != lstd; std = std->link.std) {
1498 usb_syncmem(&std->dma, 1492 usb_syncmem(&std->dma,
1499 std->offs + offsetof(uhci_td_t, td_status), 1493 std->offs + offsetof(uhci_td_t, td_status),
@@ -1544,38 +1538,58 @@ uhci_check_intr(uhci_softc_t *sc, struct @@ -1544,38 +1538,58 @@ uhci_check_intr(uhci_softc_t *sc, struct
1544 1538
1545 if ((status & UHCI_TD_SPD) && 1539 if ((status & UHCI_TD_SPD) &&
1546 UHCI_TD_GET_ACTLEN(status) < 1540 UHCI_TD_GET_ACTLEN(status) <
1547 UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token))) { 1541 UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token))) {
1548 goto done; 1542 goto done;
1549 } 1543 }
1550 } 1544 }
1551} 1545}
1552 1546
1553/* Called with USB lock held. */ 1547/* Called with USB lock held. */
1554void 1548void
1555uhci_idone(struct uhci_xfer *ux, ux_completeq_t *cqp) 1549uhci_idone(struct uhci_xfer *ux, ux_completeq_t *cqp)
1556{ 1550{
 1551 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1557 struct usbd_xfer *xfer = &ux->ux_xfer; 1552 struct usbd_xfer *xfer = &ux->ux_xfer;
1558 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); 1553 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer);
1559 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 1554 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
1560 uhci_soft_td_t *std; 1555 uhci_soft_td_t *std;
1561 uint32_t status = 0, nstatus; 1556 uint32_t status = 0, nstatus;
1562 int actlen; 1557 int actlen;
1563 1558
1564 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1559 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1565 1560
1566 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 
1567 DPRINTFN(12, "ux=%p", ux, 0, 0, 0); 1561 DPRINTFN(12, "ux=%p", ux, 0, 0, 0);
1568 1562
 1563 /*
 1564 * If software has completed it, either by cancellation
 1565 * or timeout, drop it on the floor.
 1566 */
 1567 if (xfer->ux_status != USBD_IN_PROGRESS) {
 1568 KASSERT(xfer->ux_status == USBD_CANCELLED ||
 1569 xfer->ux_status == USBD_TIMEOUT);
 1570 DPRINTF("aborted xfer=%#jx", (uintptr_t)xfer, 0, 0, 0);
 1571 return;
 1572 }
 1573
 1574 /*
 1575 * Cancel the timeout and the task, which have not yet
 1576 * run. If they have already fired, at worst they are
 1577 * waiting for the lock. They will see that the xfer
 1578 * is no longer in progress and give up.
 1579 */
 1580 callout_stop(&xfer->ux_callout);
 1581 usb_rem_task(xfer->ux_pipe->up_dev, &xfer->ux_aborttask);
 1582
1569#ifdef DIAGNOSTIC 1583#ifdef DIAGNOSTIC
1570#ifdef UHCI_DEBUG 1584#ifdef UHCI_DEBUG
1571 if (ux->ux_isdone) { 1585 if (ux->ux_isdone) {
1572 DPRINTF("--- dump start ---", 0, 0, 0, 0); 1586 DPRINTF("--- dump start ---", 0, 0, 0, 0);
1573 uhci_dump_ii(ux); 1587 uhci_dump_ii(ux);
1574 DPRINTF("--- dump end ---", 0, 0, 0, 0); 1588 DPRINTF("--- dump end ---", 0, 0, 0, 0);
1575 } 1589 }
1576#endif 1590#endif
1577 KASSERT(!ux->ux_isdone); 1591 KASSERT(!ux->ux_isdone);
1578 KASSERTMSG(!ux->ux_isdone, "xfer %p type %d status %d", xfer, 1592 KASSERTMSG(!ux->ux_isdone, "xfer %p type %d status %d", xfer,
1579 ux->ux_type, xfer->ux_status); 1593 ux->ux_type, xfer->ux_status);
1580 ux->ux_isdone = true; 1594 ux->ux_isdone = true;
1581#endif 1595#endif
@@ -1689,46 +1703,37 @@ uhci_idone(struct uhci_xfer *ux, ux_comp @@ -1689,46 +1703,37 @@ uhci_idone(struct uhci_xfer *ux, ux_comp
1689 if (cqp) 1703 if (cqp)
1690 TAILQ_INSERT_TAIL(cqp, ux, ux_list); 1704 TAILQ_INSERT_TAIL(cqp, ux, ux_list);
1691 1705
1692 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1706 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1693 DPRINTFN(12, "ux=%p done", ux, 0, 0, 0); 1707 DPRINTFN(12, "ux=%p done", ux, 0, 0, 0);
1694} 1708}
1695 1709
1696/* 1710/*
1697 * Called when a request does not complete. 1711 * Called when a request does not complete.
1698 */ 1712 */
1699void 1713void
1700uhci_timeout(void *addr) 1714uhci_timeout(void *addr)
1701{ 1715{
 1716 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1702 struct usbd_xfer *xfer = addr; 1717 struct usbd_xfer *xfer = addr;
1703 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); 
1704 uhci_softc_t *sc = UHCI_XFER2SC(xfer); 1718 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
 1719 struct usbd_device *dev = xfer->ux_pipe->up_dev;
1705 1720
1706 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1721 DPRINTF("xfer %p", xfer, 0, 0, 0);
1707 
1708 DPRINTF("uxfer %p", uxfer, 0, 0, 0); 
1709 1722
1710 if (sc->sc_dying) { 1723 mutex_enter(&sc->sc_lock);
1711 mutex_enter(&sc->sc_lock); 1724 if (!sc->sc_dying && xfer->ux_status == USBD_IN_PROGRESS)
1712 uhci_abort_xfer(xfer, USBD_TIMEOUT); 1725 usb_add_task(dev, &xfer->ux_aborttask, USB_TASKQ_HC);
1713 mutex_exit(&sc->sc_lock); 1726 mutex_exit(&sc->sc_lock);
1714 return; 
1715 } 
1716 
1717 /* Execute the abort in a process context. */ 
1718 usb_init_task(&uxfer->ux_aborttask, uhci_timeout_task, xfer, 
1719 USB_TASKQ_MPSAFE); 
1720 usb_add_task(uxfer->ux_xfer.ux_pipe->up_dev, &uxfer->ux_aborttask, 
1721 USB_TASKQ_HC); 
1722} 1727}
1723 1728
1724void 1729void
1725uhci_timeout_task(void *addr) 1730uhci_timeout_task(void *addr)
1726{ 1731{
1727 struct usbd_xfer *xfer = addr; 1732 struct usbd_xfer *xfer = addr;
1728 uhci_softc_t *sc = UHCI_XFER2SC(xfer); 1733 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
1729 1734
1730 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1735 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1731 1736
1732 DPRINTF("xfer=%p", xfer, 0, 0, 0); 1737 DPRINTF("xfer=%p", xfer, 0, 0, 0);
1733 1738
1734 mutex_enter(&sc->sc_lock); 1739 mutex_enter(&sc->sc_lock);
@@ -2315,125 +2320,133 @@ uhci_device_bulk_start(struct usbd_xfer  @@ -2315,125 +2320,133 @@ uhci_device_bulk_start(struct usbd_xfer
2315void 2320void
2316uhci_device_bulk_abort(struct usbd_xfer *xfer) 2321uhci_device_bulk_abort(struct usbd_xfer *xfer)
2317{ 2322{
2318 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); 2323 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer);
2319 2324
2320 KASSERT(mutex_owned(&sc->sc_lock)); 2325 KASSERT(mutex_owned(&sc->sc_lock));
2321 2326
2322 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2327 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2323 2328
2324 uhci_abort_xfer(xfer, USBD_CANCELLED); 2329 uhci_abort_xfer(xfer, USBD_CANCELLED);
2325} 2330}
2326 2331
2327/* 2332/*
2328 * Abort a device request. 2333 * Cancel or timeout a device request. We have two cases to deal with
2329 * If this routine is called at splusb() it guarantees that the request 2334 *
2330 * will be removed from the hardware scheduling and that the callback 2335 * 1) A driver wants to stop scheduled or inflight transfers
2331 * for it will be called with USBD_CANCELLED status. 2336 * 2) A transfer has timed out
 2337 *
2332 * It's impossible to guarantee that the requested transfer will not 2338 * It's impossible to guarantee that the requested transfer will not
2333 * have happened since the hardware runs concurrently. 2339 * have (partially) happened since the hardware runs concurrently.
2334 * If the transaction has already happened we rely on the ordinary 2340 *
2335 * interrupt processing to process it. 2341 * Transfer state is protected by the bus lock and we set the transfer status
2336 * XXX This is most probably wrong. 2342 * as soon as either of the above happens (with bus lock held).
2337 * XXXMRG this doesn't make sense anymore. 2343 *
 2344 * To allow the hardware time to notice we simply wait.
2338 */ 2345 */
2339void 2346void
2340uhci_abort_xfer(struct usbd_xfer *xfer, usbd_status status) 2347uhci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
2341{ 2348{
 2349 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2342 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2350 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2343 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2351 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2344 uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2352 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2345 uhci_soft_td_t *std; 2353 uhci_soft_td_t *std;
2346 int wake; 
2347 2354
2348 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2355 KASSERTMSG((status == USBD_CANCELLED || status == USBD_TIMEOUT),
 2356 "invalid status for abort: %d", (int)status);
 2357
2349 DPRINTFN(1,"xfer=%p, status=%d", xfer, status, 0, 0); 2358 DPRINTFN(1,"xfer=%p, status=%d", xfer, status, 0, 0);
2350 2359
2351 KASSERT(mutex_owned(&sc->sc_lock)); 2360 KASSERT(mutex_owned(&sc->sc_lock));
2352 ASSERT_SLEEPABLE(); 2361 ASSERT_SLEEPABLE();
2353 2362
2354 if (sc->sc_dying) { 2363 if (status == USBD_CANCELLED) {
2355 /* If we're dying, just do the software part. */ 2364 /*
2356 xfer->ux_status = status; /* make software ignore it */ 2365 * We are synchronously aborting. Try to stop the
2357 callout_stop(&xfer->ux_callout); 2366 * callout and task, but if we can't, wait for them to
2358 usb_transfer_complete(xfer); 2367 * complete.
2359 return; 2368 */
 2369 callout_halt(&xfer->ux_callout, &sc->sc_lock);
 2370 usb_rem_task_wait(xfer->ux_pipe->up_dev, &xfer->ux_aborttask,
 2371 USB_TASKQ_HC, &sc->sc_lock);
 2372 } else {
 2373 /* Otherwise, we are timing out. */
 2374 KASSERT(status == USBD_TIMEOUT);
2360 } 2375 }
2361 2376
2362 /* 2377 /*
2363 * If an abort is already in progress then just wait for it to 2378 * The xfer cannot have been cancelled already. It is the
2364 * complete and return. 2379 * responsibility of the caller of usbd_abort_pipe not to try
 2380 * to abort a pipe multiple times, whether concurrently or
 2381 * sequentially.
2365 */ 2382 */
2366 if (xfer->ux_hcflags & UXFER_ABORTING) { 2383 KASSERT(xfer->ux_status != USBD_CANCELLED);
2367 DPRINTFN(2, "already aborting", 0, 0, 0, 0); 2384
2368#ifdef DIAGNOSTIC 2385 /* Only the timeout, which runs only once, can time it out. */
2369 if (status == USBD_TIMEOUT) 2386 KASSERT(xfer->ux_status != USBD_TIMEOUT);
2370 printf("%s: TIMEOUT while aborting\n", __func__); 2387
2371#endif 2388 /* If anyone else beat us, we're done. */
2372 /* Override the status which might be USBD_TIMEOUT. */ 2389 if (xfer->ux_status != USBD_IN_PROGRESS)
2373 xfer->ux_status = status; 2390 return;
2374 DPRINTFN(2, "waiting for abort to finish", 0, 0, 0, 0); 2391
2375 xfer->ux_hcflags |= UXFER_ABORTWAIT; 2392 /* We beat everyone else. Claim the status. */
2376 while (xfer->ux_hcflags & UXFER_ABORTING) 2393 xfer->ux_status = status;
2377 cv_wait(&xfer->ux_hccv, &sc->sc_lock); 2394
2378 goto done; 2395 /*
 2396 * If we're dying, skip the hardware action and just notify the
 2397 * software that we're done.
 2398 */
 2399 if (sc->sc_dying) {
 2400 DPRINTFN(4, "xfer %#jx dying %ju", (uintptr_t)xfer,
 2401 xfer->ux_status, 0, 0);
 2402 goto dying;
2379 } 2403 }
2380 xfer->ux_hcflags |= UXFER_ABORTING; 
2381 2404
2382 /* 2405 /*
2383 * Step 1: Make interrupt routine and hardware ignore xfer. 2406 * HC Step 1: Make interrupt routine and hardware ignore xfer.
2384 */ 2407 */
2385 xfer->ux_status = status; /* make software ignore it */ 
2386 callout_stop(&xfer->ux_callout); 
2387 uhci_del_intr_list(sc, ux); 2408 uhci_del_intr_list(sc, ux);
2388 2409
2389 DPRINTF("stop ux=%p", ux, 0, 0, 0); 2410 DPRINTF("stop ux=%p", ux, 0, 0, 0);
2390 for (std = ux->ux_stdstart; std != NULL; std = std->link.std) { 2411 for (std = ux->ux_stdstart; std != NULL; std = std->link.std) {
2391 usb_syncmem(&std->dma, 2412 usb_syncmem(&std->dma,
2392 std->offs + offsetof(uhci_td_t, td_status), 2413 std->offs + offsetof(uhci_td_t, td_status),
2393 sizeof(std->td.td_status), 2414 sizeof(std->td.td_status),
2394 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2415 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
2395 std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); 2416 std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
2396 usb_syncmem(&std->dma, 2417 usb_syncmem(&std->dma,
2397 std->offs + offsetof(uhci_td_t, td_status), 2418 std->offs + offsetof(uhci_td_t, td_status),
2398 sizeof(std->td.td_status), 2419 sizeof(std->td.td_status),
2399 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2420 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2400 } 2421 }
2401 2422
2402 /* 2423 /*
2403 * Step 2: Wait until we know hardware has finished any possible 2424 * HC Step 2: Wait until we know hardware has finished any possible
2404 * use of the xfer. Also make sure the soft interrupt routine 2425 * use of the xfer.
2405 * has run. 
2406 */ 2426 */
2407 /* Hardware finishes in 1ms */ 2427 /* Hardware finishes in 1ms */
2408 usb_delay_ms_locked(upipe->pipe.up_dev->ud_bus, 2, &sc->sc_lock); 2428 usb_delay_ms_locked(upipe->pipe.up_dev->ud_bus, 2, &sc->sc_lock);
2409 sc->sc_softwake = 1; 
2410 usb_schedsoftintr(&sc->sc_bus); 
2411 DPRINTF("cv_wait", 0, 0, 0, 0); 
2412 cv_wait(&sc->sc_softwake_cv, &sc->sc_lock); 
2413 2429
2414 /* 2430 /*
2415 * Step 3: Execute callback. 2431 * HC Step 3: Notify completion to waiting xfers.
2416 */ 2432 */
2417 DPRINTF("callback", 0, 0, 0, 0); 2433dying:
2418#ifdef DIAGNOSTIC 2434#ifdef DIAGNOSTIC
2419 ux->ux_isdone = true; 2435 ux->ux_isdone = true;
2420#endif 2436#endif
2421 wake = xfer->ux_hcflags & UXFER_ABORTWAIT; 
2422 xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); 
2423 usb_transfer_complete(xfer); 2437 usb_transfer_complete(xfer);
2424 if (wake) 2438 DPRINTFN(14, "end", 0, 0, 0, 0);
2425 cv_broadcast(&xfer->ux_hccv); 2439
2426done: 
2427 KASSERT(mutex_owned(&sc->sc_lock)); 2440 KASSERT(mutex_owned(&sc->sc_lock));
2428} 2441}
2429 2442
2430/* Close a device bulk pipe. */ 2443/* Close a device bulk pipe. */
2431void 2444void
2432uhci_device_bulk_close(struct usbd_pipe *pipe) 2445uhci_device_bulk_close(struct usbd_pipe *pipe)
2433{ 2446{
2434 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); 2447 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe);
2435 uhci_softc_t *sc = UHCI_PIPE2SC(pipe); 2448 uhci_softc_t *sc = UHCI_PIPE2SC(pipe);
2436 2449
2437 KASSERT(mutex_owned(&sc->sc_lock)); 2450 KASSERT(mutex_owned(&sc->sc_lock));
2438 2451
2439 uhci_free_sqh(sc, upipe->bulk.sqh); 2452 uhci_free_sqh(sc, upipe->bulk.sqh);

cvs diff -r1.52.12.1 -r1.52.12.2 src/sys/dev/usb/uhcivar.h (expand / switch to unified diff)

--- src/sys/dev/usb/uhcivar.h 2017/04/05 19:54:20 1.52.12.1
+++ src/sys/dev/usb/uhcivar.h 2018/08/25 14:57:35 1.52.12.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: uhcivar.h,v 1.52.12.1 2017/04/05 19:54:20 snj Exp $ */ 1/* $NetBSD: uhcivar.h,v 1.52.12.2 2018/08/25 14:57:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998 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
@@ -51,27 +51,26 @@ @@ -51,27 +51,26 @@
51 */ 51 */
52#define UHCI_VFRAMELIST_COUNT 128 52#define UHCI_VFRAMELIST_COUNT 128
53 53
54typedef struct uhci_soft_qh uhci_soft_qh_t; 54typedef struct uhci_soft_qh uhci_soft_qh_t;
55typedef struct uhci_soft_td uhci_soft_td_t; 55typedef struct uhci_soft_td uhci_soft_td_t;
56 56
57typedef union { 57typedef union {
58 struct uhci_soft_qh *sqh; 58 struct uhci_soft_qh *sqh;
59 struct uhci_soft_td *std; 59 struct uhci_soft_td *std;
60} uhci_soft_td_qh_t; 60} uhci_soft_td_qh_t;
61 61
62struct uhci_xfer { 62struct uhci_xfer {
63 struct usbd_xfer ux_xfer; 63 struct usbd_xfer ux_xfer;
64 struct usb_task ux_aborttask; 
65 enum { 64 enum {
66 UX_NONE, UX_CTRL, UX_BULK, UX_INTR, UX_ISOC 65 UX_NONE, UX_CTRL, UX_BULK, UX_INTR, UX_ISOC
67 } ux_type; 66 } ux_type;
68 /* ctrl/bulk/intr */ 67 /* ctrl/bulk/intr */
69 struct { 68 struct {
70 uhci_soft_td_t **ux_stds; 69 uhci_soft_td_t **ux_stds;
71 size_t ux_nstd; 70 size_t ux_nstd;
72 }; 71 };
73 union { 72 union {
74 /* ctrl */ 73 /* ctrl */
75 struct { 74 struct {
76 uhci_soft_td_t *ux_setup; 75 uhci_soft_td_t *ux_setup;
77 uhci_soft_td_t *ux_data; 76 uhci_soft_td_t *ux_data;
@@ -142,51 +141,48 @@ struct uhci_vframe { @@ -142,51 +141,48 @@ struct uhci_vframe {
142 uhci_soft_qh_t *eqh; /* pointer to last QH */ 141 uhci_soft_qh_t *eqh; /* pointer to last QH */
143 u_int bandwidth; /* max bandwidth used by this frame */ 142 u_int bandwidth; /* max bandwidth used by this frame */
144}; 143};
145 144
146typedef struct uhci_softc { 145typedef struct uhci_softc {
147 device_t sc_dev; 146 device_t sc_dev;
148 struct usbd_bus sc_bus; 147 struct usbd_bus sc_bus;
149 bus_space_tag_t iot; 148 bus_space_tag_t iot;
150 bus_space_handle_t ioh; 149 bus_space_handle_t ioh;
151 bus_size_t sc_size; 150 bus_size_t sc_size;
152 151
153 kmutex_t sc_lock; 152 kmutex_t sc_lock;
154 kmutex_t sc_intr_lock; 153 kmutex_t sc_intr_lock;
155 kcondvar_t sc_softwake_cv; 
156 154
157 uhci_physaddr_t *sc_pframes; 155 uhci_physaddr_t *sc_pframes;
158 usb_dma_t sc_dma; 156 usb_dma_t sc_dma;
159 struct uhci_vframe sc_vframes[UHCI_VFRAMELIST_COUNT]; 157 struct uhci_vframe sc_vframes[UHCI_VFRAMELIST_COUNT];
160 158
161 uhci_soft_qh_t *sc_lctl_start; /* dummy QH for low speed control */ 159 uhci_soft_qh_t *sc_lctl_start; /* dummy QH for low speed control */
162 uhci_soft_qh_t *sc_lctl_end; /* last control QH */ 160 uhci_soft_qh_t *sc_lctl_end; /* last control QH */
163 uhci_soft_qh_t *sc_hctl_start; /* dummy QH for high speed control */ 161 uhci_soft_qh_t *sc_hctl_start; /* dummy QH for high speed control */
164 uhci_soft_qh_t *sc_hctl_end; /* last control QH */ 162 uhci_soft_qh_t *sc_hctl_end; /* last control QH */
165 uhci_soft_qh_t *sc_bulk_start; /* dummy QH for bulk */ 163 uhci_soft_qh_t *sc_bulk_start; /* dummy QH for bulk */
166 uhci_soft_qh_t *sc_bulk_end; /* last bulk transfer */ 164 uhci_soft_qh_t *sc_bulk_end; /* last bulk transfer */
167 uhci_soft_qh_t *sc_last_qh; /* dummy QH at the end */ 165 uhci_soft_qh_t *sc_last_qh; /* dummy QH at the end */
168 uint32_t sc_loops; /* number of QHs that wants looping */ 166 uint32_t sc_loops; /* number of QHs that wants looping */
169 167
170 uhci_soft_td_t *sc_freetds; /* TD free list */ 168 uhci_soft_td_t *sc_freetds; /* TD free list */
171 uhci_soft_qh_t *sc_freeqhs; /* QH free list */ 169 uhci_soft_qh_t *sc_freeqhs; /* QH free list */
172 170
173 pool_cache_t sc_xferpool; /* free xfer pool */ 171 pool_cache_t sc_xferpool; /* free xfer pool */
174 172
175 uint8_t sc_saved_sof; 173 uint8_t sc_saved_sof;
176 uint16_t sc_saved_frnum; 174 uint16_t sc_saved_frnum;
177 175
178 char sc_softwake; 
179 
180 char sc_isreset; 176 char sc_isreset;
181 char sc_suspend; 177 char sc_suspend;
182 char sc_dying; 178 char sc_dying;
183 179
184 TAILQ_HEAD(, uhci_xfer) sc_intrhead; 180 TAILQ_HEAD(, uhci_xfer) sc_intrhead;
185 181
186 /* Info for the root hub interrupt "pipe". */ 182 /* Info for the root hub interrupt "pipe". */
187 int sc_ival; /* time between root hub intrs */ 183 int sc_ival; /* time between root hub intrs */
188 struct usbd_xfer *sc_intr_xfer; /* root hub interrupt transfer */ 184 struct usbd_xfer *sc_intr_xfer; /* root hub interrupt transfer */
189 struct callout sc_poll_handle; 185 struct callout sc_poll_handle;
190 186
191 char sc_vendor[32]; /* vendor string for root hub */ 187 char sc_vendor[32]; /* vendor string for root hub */
192 int sc_id_vendor; /* vendor ID for root hub */ 188 int sc_id_vendor; /* vendor ID for root hub */

cvs diff -r1.161.2.2 -r1.161.2.3 src/sys/dev/usb/usbdi.c (expand / switch to unified diff)

--- src/sys/dev/usb/usbdi.c 2017/04/05 19:54:21 1.161.2.2
+++ src/sys/dev/usb/usbdi.c 2018/08/25 14:57:35 1.161.2.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: usbdi.c,v 1.161.2.2 2017/04/05 19:54:21 snj Exp $ */ 1/* $NetBSD: usbdi.c,v 1.161.2.3 2018/08/25 14:57:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2012, 2015 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, Matthew R. Green (mrg@eterna.com.au), 9 * Carlstedt Research & Technology, Matthew R. Green (mrg@eterna.com.au),
10 * and Nick Hudson. 10 * and Nick Hudson.
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:
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.161.2.2 2017/04/05 19:54:21 snj Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.161.2.3 2018/08/25 14:57:35 martin Exp $");
36 36
37#ifdef _KERNEL_OPT 37#ifdef _KERNEL_OPT
38#include "opt_usb.h" 38#include "opt_usb.h"
39#include "opt_compat_netbsd.h" 39#include "opt_compat_netbsd.h"
40#include "usb_dma.h" 40#include "usb_dma.h"
41#endif 41#endif
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/device.h> 46#include <sys/device.h>
47#include <sys/kmem.h> 47#include <sys/kmem.h>
48#include <sys/proc.h> 48#include <sys/proc.h>
@@ -269,26 +269,27 @@ usbd_close_pipe(struct usbd_pipe *pipe) @@ -269,26 +269,27 @@ usbd_close_pipe(struct usbd_pipe *pipe)
269 269
270usbd_status 270usbd_status
271usbd_transfer(struct usbd_xfer *xfer) 271usbd_transfer(struct usbd_xfer *xfer)
272{ 272{
273 struct usbd_pipe *pipe = xfer->ux_pipe; 273 struct usbd_pipe *pipe = xfer->ux_pipe;
274 usbd_status err; 274 usbd_status err;
275 unsigned int size, flags; 275 unsigned int size, flags;
276 276
277 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 277 USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
278 278
279 USBHIST_LOG(usbdebug, 279 USBHIST_LOG(usbdebug,
280 "xfer = %p, flags = %#x, pipe = %p, running = %d", 280 "xfer = %p, flags = %#x, pipe = %p, running = %d",
281 xfer, xfer->ux_flags, pipe, pipe->up_running); 281 xfer, xfer->ux_flags, pipe, pipe->up_running);
 282 KASSERT(xfer->ux_status == USBD_NOT_STARTED);
282 283
283#ifdef USB_DEBUG 284#ifdef USB_DEBUG
284 if (usbdebug > 5) 285 if (usbdebug > 5)
285 usbd_dump_queue(pipe); 286 usbd_dump_queue(pipe);
286#endif 287#endif
287 xfer->ux_done = 0; 288 xfer->ux_done = 0;
288 289
289 if (pipe->up_aborting) { 290 if (pipe->up_aborting) {
290 USBHIST_LOG(usbdebug, "<- done xfer %p, aborting", xfer, 0, 0, 291 USBHIST_LOG(usbdebug, "<- done xfer %p, aborting", xfer, 0, 0,
291 0); 292 0);
292 return USBD_CANCELLED; 293 return USBD_CANCELLED;
293 } 294 }
294 295
@@ -333,27 +334,27 @@ usbd_transfer(struct usbd_xfer *xfer) @@ -333,27 +334,27 @@ usbd_transfer(struct usbd_xfer *xfer)
333 SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next); 334 SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next);
334 if (pipe->up_serialise) 335 if (pipe->up_serialise)
335 usbd_start_next(pipe); 336 usbd_start_next(pipe);
336 usbd_unlock_pipe(pipe); 337 usbd_unlock_pipe(pipe);
337 } 338 }
338 339
339 if (!(flags & USBD_SYNCHRONOUS)) { 340 if (!(flags & USBD_SYNCHRONOUS)) {
340 USBHIST_LOG(usbdebug, "<- done xfer %p, not sync (err %d)", 341 USBHIST_LOG(usbdebug, "<- done xfer %p, not sync (err %d)",
341 xfer, err, 0, 0); 342 xfer, err, 0, 0);
342 return err; 343 return err;
343 } 344 }
344 345
345 if (err != USBD_IN_PROGRESS) { 346 if (err != USBD_IN_PROGRESS) {
346 USBHIST_LOG(usbdebug, "<- done xfer %p, err %d (complete/error)", xfer, 347 USBHIST_LOG(usbdebug, "<- done xfer %p, sync err %d (complete/error)", xfer,
347 err, 0, 0); 348 err, 0, 0);
348 return err; 349 return err;
349 } 350 }
350 351
351 /* Sync transfer, wait for completion. */ 352 /* Sync transfer, wait for completion. */
352 usbd_lock_pipe(pipe); 353 usbd_lock_pipe(pipe);
353 while (!xfer->ux_done) { 354 while (!xfer->ux_done) {
354 if (pipe->up_dev->ud_bus->ub_usepolling) 355 if (pipe->up_dev->ud_bus->ub_usepolling)
355 panic("usbd_transfer: not done"); 356 panic("usbd_transfer: not done");
356 USBHIST_LOG(usbdebug, "<- sleeping on xfer %p", xfer, 0, 0, 0); 357 USBHIST_LOG(usbdebug, "<- sleeping on xfer %p", xfer, 0, 0, 0);
357 358
358 err = 0; 359 err = 0;
359 if ((flags & USBD_SYNCHRONOUS_SIG) != 0) { 360 if ((flags & USBD_SYNCHRONOUS_SIG) != 0) {
@@ -465,50 +466,48 @@ usbd_alloc_xfer(struct usbd_device *dev, @@ -465,50 +466,48 @@ usbd_alloc_xfer(struct usbd_device *dev,
465{ 466{
466 struct usbd_xfer *xfer; 467 struct usbd_xfer *xfer;
467 468
468 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 469 USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
469 470
470 ASSERT_SLEEPABLE(); 471 ASSERT_SLEEPABLE();
471 472
472 xfer = dev->ud_bus->ub_methods->ubm_allocx(dev->ud_bus, nframes); 473 xfer = dev->ud_bus->ub_methods->ubm_allocx(dev->ud_bus, nframes);
473 if (xfer == NULL) 474 if (xfer == NULL)
474 return NULL; 475 return NULL;
475 xfer->ux_bus = dev->ud_bus; 476 xfer->ux_bus = dev->ud_bus;
476 callout_init(&xfer->ux_callout, CALLOUT_MPSAFE); 477 callout_init(&xfer->ux_callout, CALLOUT_MPSAFE);
477 cv_init(&xfer->ux_cv, "usbxfer"); 478 cv_init(&xfer->ux_cv, "usbxfer");
478 cv_init(&xfer->ux_hccv, "usbhcxfer"); 
479 479
480 USBHIST_LOG(usbdebug, "returns %p", xfer, 0, 0, 0); 480 USBHIST_LOG(usbdebug, "returns %p", xfer, 0, 0, 0);
481 481
482 return xfer; 482 return xfer;
483} 483}
484 484
485static usbd_status 485static usbd_status
486usbd_free_xfer(struct usbd_xfer *xfer) 486usbd_free_xfer(struct usbd_xfer *xfer)
487{ 487{
488 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 488 USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
489 489
490 USBHIST_LOG(usbdebug, "%p", xfer, 0, 0, 0); 490 USBHIST_LOG(usbdebug, "%p", xfer, 0, 0, 0);
491 if (xfer->ux_buf) { 491 if (xfer->ux_buf) {
492 usbd_free_buffer(xfer); 492 usbd_free_buffer(xfer);
493 } 493 }
494#if defined(DIAGNOSTIC) 494#if defined(DIAGNOSTIC)
495 if (callout_pending(&xfer->ux_callout)) { 495 if (callout_pending(&xfer->ux_callout)) {
496 callout_stop(&xfer->ux_callout); 496 callout_stop(&xfer->ux_callout);
497 printf("usbd_free_xfer: timeout_handle pending\n"); 497 printf("usbd_free_xfer: timeout_handle pending\n");
498 } 498 }
499#endif 499#endif
500 cv_destroy(&xfer->ux_cv); 500 cv_destroy(&xfer->ux_cv);
501 cv_destroy(&xfer->ux_hccv); 
502 xfer->ux_bus->ub_methods->ubm_freex(xfer->ux_bus, xfer); 501 xfer->ux_bus->ub_methods->ubm_freex(xfer->ux_bus, xfer);
503 return USBD_NORMAL_COMPLETION; 502 return USBD_NORMAL_COMPLETION;
504} 503}
505 504
506int 505int
507usbd_create_xfer(struct usbd_pipe *pipe, size_t len, unsigned int flags, 506usbd_create_xfer(struct usbd_pipe *pipe, size_t len, unsigned int flags,
508 unsigned int nframes, struct usbd_xfer **xp) 507 unsigned int nframes, struct usbd_xfer **xp)
509{ 508{
510 KASSERT(xp != NULL); 509 KASSERT(xp != NULL);
511 void *buf = NULL; 510 void *buf = NULL;
512 511
513 struct usbd_xfer *xfer = usbd_alloc_xfer(pipe->up_dev, nframes); 512 struct usbd_xfer *xfer = usbd_alloc_xfer(pipe->up_dev, nframes);
514 if (xfer == NULL) 513 if (xfer == NULL)
@@ -897,27 +896,28 @@ usb_transfer_complete(struct usbd_xfer * @@ -897,27 +896,28 @@ usb_transfer_complete(struct usbd_xfer *
897 int sync = xfer->ux_flags & USBD_SYNCHRONOUS; 896 int sync = xfer->ux_flags & USBD_SYNCHRONOUS;
898 int erred = 897 int erred =
899 xfer->ux_status == USBD_CANCELLED || 898 xfer->ux_status == USBD_CANCELLED ||
900 xfer->ux_status == USBD_TIMEOUT; 899 xfer->ux_status == USBD_TIMEOUT;
901 int polling = bus->ub_usepolling; 900 int polling = bus->ub_usepolling;
902 int repeat = pipe->up_repeat; 901 int repeat = pipe->up_repeat;
903 902
904 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 903 USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
905 904
906 USBHIST_LOG(usbdebug, "pipe = %p xfer = %p status = %d actlen = %d", 905 USBHIST_LOG(usbdebug, "pipe = %p xfer = %p status = %d actlen = %d",
907 pipe, xfer, xfer->ux_status, xfer->ux_actlen); 906 pipe, xfer, xfer->ux_status, xfer->ux_actlen);
908 907
909 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 908 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock));
910 KASSERT(xfer->ux_state == XFER_ONQU); 909 KASSERTMSG(xfer->ux_state == XFER_ONQU, "xfer %p state is %x", xfer,
 910 xfer->ux_state);
911 KASSERT(pipe != NULL); 911 KASSERT(pipe != NULL);
912 912
913 if (!repeat) { 913 if (!repeat) {
914 /* Remove request from queue. */ 914 /* Remove request from queue. */
915 915
916 KASSERTMSG(!SIMPLEQ_EMPTY(&pipe->up_queue), 916 KASSERTMSG(!SIMPLEQ_EMPTY(&pipe->up_queue),
917 "pipe %p is empty, but xfer %p wants to complete", pipe, 917 "pipe %p is empty, but xfer %p wants to complete", pipe,
918 xfer); 918 xfer);
919 KASSERTMSG(xfer == SIMPLEQ_FIRST(&pipe->up_queue), 919 KASSERTMSG(xfer == SIMPLEQ_FIRST(&pipe->up_queue),
920 "xfer %p is not start of queue (%p is at start)", xfer, 920 "xfer %p is not start of queue (%p is at start)", xfer,
921 SIMPLEQ_FIRST(&pipe->up_queue)); 921 SIMPLEQ_FIRST(&pipe->up_queue));
922 922
923#ifdef DIAGNOSTIC 923#ifdef DIAGNOSTIC

cvs diff -r1.107.4.2 -r1.107.4.3 src/sys/dev/usb/usbdivar.h (expand / switch to unified diff)

--- src/sys/dev/usb/usbdivar.h 2017/04/05 19:54:21 1.107.4.2
+++ src/sys/dev/usb/usbdivar.h 2018/08/25 14:57:35 1.107.4.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: usbdivar.h,v 1.107.4.2 2017/04/05 19:54:21 snj Exp $ */ 1/* $NetBSD: usbdivar.h,v 1.107.4.3 2018/08/25 14:57:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 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) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology and Matthew R. Green (mrg@eterna.com.au). 9 * Carlstedt Research & Technology and Matthew R. Green (mrg@eterna.com.au).
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
@@ -274,31 +274,28 @@ struct usbd_xfer { @@ -274,31 +274,28 @@ struct usbd_xfer {
274 /* For memory allocation and softc */ 274 /* For memory allocation and softc */
275 struct usbd_bus *ux_bus; 275 struct usbd_bus *ux_bus;
276 usb_dma_t ux_dmabuf; 276 usb_dma_t ux_dmabuf;
277 void *ux_buf; 277 void *ux_buf;
278 uint32_t ux_bufsize; 278 uint32_t ux_bufsize;
279 279
280 uint8_t ux_rqflags; 280 uint8_t ux_rqflags;
281#define URQ_REQUEST 0x01 281#define URQ_REQUEST 0x01
282 282
283 SIMPLEQ_ENTRY(usbd_xfer) 283 SIMPLEQ_ENTRY(usbd_xfer)
284 ux_next; 284 ux_next;
285 285
286 void *ux_hcpriv; /* private use by the HC driver */ 286 void *ux_hcpriv; /* private use by the HC driver */
287 uint8_t ux_hcflags; /* private use by the HC driver */ 
288#define UXFER_ABORTING 0x01 /* xfer is aborting. */ 
289#define UXFER_ABORTWAIT 0x02 /* abort completion is being awaited. */ 
290 kcondvar_t ux_hccv; /* private use by the HC driver */ 
291 287
 288 struct usb_task ux_aborttask;
292 struct callout ux_callout; 289 struct callout ux_callout;
293}; 290};
294 291
295void usbd_init(void); 292void usbd_init(void);
296void usbd_finish(void); 293void usbd_finish(void);
297 294
298#if defined(USB_DEBUG) 295#if defined(USB_DEBUG)
299void usbd_dump_iface(struct usbd_interface *); 296void usbd_dump_iface(struct usbd_interface *);
300void usbd_dump_device(struct usbd_device *); 297void usbd_dump_device(struct usbd_device *);
301void usbd_dump_endpoint(struct usbd_endpoint *); 298void usbd_dump_endpoint(struct usbd_endpoint *);
302void usbd_dump_queue(struct usbd_pipe *); 299void usbd_dump_queue(struct usbd_pipe *);
303void usbd_dump_pipe(struct usbd_pipe *); 300void usbd_dump_pipe(struct usbd_pipe *);
304#endif 301#endif

cvs diff -r1.23.2.7 -r1.23.2.8 src/sys/dev/usb/xhci.c (expand / switch to unified diff)

--- src/sys/dev/usb/xhci.c 2018/01/03 20:02:37 1.23.2.7
+++ src/sys/dev/usb/xhci.c 2018/08/25 14:57:35 1.23.2.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xhci.c,v 1.23.2.7 2018/01/03 20:02:37 snj Exp $ */ 1/* $NetBSD: xhci.c,v 1.23.2.8 2018/08/25 14:57:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2013 Jonathan A. Kollasch 4 * Copyright (c) 2013 Jonathan A. Kollasch
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * USB rev 2.0 and rev 3.1 specification 30 * USB rev 2.0 and rev 3.1 specification
31 * http://www.usb.org/developers/docs/ 31 * http://www.usb.org/developers/docs/
32 * xHCI rev 1.1 specification 32 * xHCI rev 1.1 specification
33 * http://www.intel.com/technology/usb/spec.htm 33 * http://www.intel.com/technology/usb/spec.htm
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.23.2.7 2018/01/03 20:02:37 snj Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.23.2.8 2018/08/25 14:57:35 martin Exp $");
38 38
39#ifdef _KERNEL_OPT 39#ifdef _KERNEL_OPT
40#include "opt_usb.h" 40#include "opt_usb.h"
41#endif 41#endif
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/kmem.h> 46#include <sys/kmem.h>
47#include <sys/device.h> 47#include <sys/device.h>
48#include <sys/select.h> 48#include <sys/select.h>
49#include <sys/proc.h> 49#include <sys/proc.h>
50#include <sys/queue.h> 50#include <sys/queue.h>
@@ -1650,105 +1650,111 @@ xhci_close_pipe(struct usbd_pipe *pipe) @@ -1650,105 +1650,111 @@ xhci_close_pipe(struct usbd_pipe *pipe)
1650 XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_CONFIGURE_EP); 1650 XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_CONFIGURE_EP);
1651 1651
1652 (void)xhci_do_command_locked(sc, &trb, USBD_DEFAULT_TIMEOUT); 1652 (void)xhci_do_command_locked(sc, &trb, USBD_DEFAULT_TIMEOUT);
1653 usb_syncmem(&xs->xs_dc_dma, 0, sc->sc_pgsz, BUS_DMASYNC_POSTREAD); 1653 usb_syncmem(&xs->xs_dc_dma, 0, sc->sc_pgsz, BUS_DMASYNC_POSTREAD);
1654} 1654}
1655 1655
1656/* 1656/*
1657 * Abort transfer. 1657 * Abort transfer.
1658 * Should be called with sc_lock held. 1658 * Should be called with sc_lock held.
1659 */ 1659 */
1660static void 1660static void
1661xhci_abort_xfer(struct usbd_xfer *xfer, usbd_status status) 1661xhci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
1662{ 1662{
 1663 XHCIHIST_FUNC(); XHCIHIST_CALLED();
1663 struct xhci_softc * const sc = XHCI_XFER2SC(xfer); 1664 struct xhci_softc * const sc = XHCI_XFER2SC(xfer);
1664 struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; 1665 struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv;
1665 const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); 1666 const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc);
1666 1667
1667 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 1668 KASSERTMSG((status == USBD_CANCELLED || status == USBD_TIMEOUT),
 1669 "invalid status for abort: %d", (int)status);
 1670
1668 DPRINTFN(4, "xfer %p pipe %p status %d", 1671 DPRINTFN(4, "xfer %p pipe %p status %d",
1669 xfer, xfer->ux_pipe, status, 0); 1672 xfer, xfer->ux_pipe, status, 0);
1670 1673
1671 KASSERT(mutex_owned(&sc->sc_lock)); 1674 KASSERT(mutex_owned(&sc->sc_lock));
 1675 ASSERT_SLEEPABLE();
1672 1676
1673 if (sc->sc_dying) { 1677 if (status == USBD_CANCELLED) {
1674 /* If we're dying, just do the software part. */ 1678 /*
1675 DPRINTFN(4, "xfer %p dying %u", xfer, xfer->ux_status, 0, 0); 1679 * We are synchronously aborting. Try to stop the
1676 xfer->ux_status = status; 1680 * callout and task, but if we can't, wait for them to
1677 callout_stop(&xfer->ux_callout); 1681 * complete.
1678 usb_transfer_complete(xfer); 1682 */
1679 return; 1683 callout_halt(&xfer->ux_callout, &sc->sc_lock);
 1684 usb_rem_task_wait(xfer->ux_pipe->up_dev, &xfer->ux_aborttask,
 1685 USB_TASKQ_HC, &sc->sc_lock);
 1686 } else {
 1687 /* Otherwise, we are timing out. */
 1688 KASSERT(status == USBD_TIMEOUT);
1680 } 1689 }
1681 1690
1682 /* 1691 /*
1683 * If an abort is already in progress then just wait for it to 1692 * The xfer cannot have been cancelled already. It is the
1684 * complete and return. 1693 * responsibility of the caller of usbd_abort_pipe not to try
 1694 * to abort a pipe multiple times, whether concurrently or
 1695 * sequentially.
1685 */ 1696 */
1686 if (xfer->ux_hcflags & UXFER_ABORTING) { 1697 KASSERT(xfer->ux_status != USBD_CANCELLED);
1687 DPRINTFN(4, "already aborting", 0, 0, 0, 0); 1698
1688#ifdef DIAGNOSTIC 1699 /* Only the timeout, which runs only once, can time it out. */
1689 if (status == USBD_TIMEOUT) 1700 KASSERT(xfer->ux_status != USBD_TIMEOUT);
1690 DPRINTFN(4, "TIMEOUT while aborting", 0, 0, 0, 0); 1701
1691#endif 1702 /* If anyone else beat us, we're done. */
1692 /* Override the status which might be USBD_TIMEOUT. */ 1703 if (xfer->ux_status != USBD_IN_PROGRESS)
1693 xfer->ux_status = status; 1704 return;
1694 DPRINTFN(4, "xfer %p waiting for abort to finish", xfer, 0, 0, 1705
1695 0); 1706 /* We beat everyone else. Claim the status. */
1696 xfer->ux_hcflags |= UXFER_ABORTWAIT; 1707 xfer->ux_status = status;
1697 while (xfer->ux_hcflags & UXFER_ABORTING) 
1698 cv_wait(&xfer->ux_hccv, &sc->sc_lock); 
1699 return; 
1700 } 
1701 xfer->ux_hcflags |= UXFER_ABORTING; 
1702 1708
1703 /* 1709 /*
1704 * Step 1: Stop xfer timeout timer. 1710 * If we're dying, skip the hardware action and just notify the
 1711 * software that we're done.
1705 */ 1712 */
1706 xfer->ux_status = status; 1713 if (sc->sc_dying) {
1707 callout_stop(&xfer->ux_callout); 1714 DPRINTFN(4, "xfer %#jx dying %ju", (uintptr_t)xfer,
 1715 xfer->ux_status, 0, 0);
 1716 goto dying;
 1717 }
1708 1718
1709 /* 1719 /*
1710 * Step 2: Stop execution of TD on the ring. 1720 * HC Step 1: Stop execution of TD on the ring.
1711 */ 1721 */
1712 switch (xhci_get_epstate(sc, xs, dci)) { 1722 switch (xhci_get_epstate(sc, xs, dci)) {
1713 case XHCI_EPSTATE_HALTED: 1723 case XHCI_EPSTATE_HALTED:
1714 (void)xhci_reset_endpoint_locked(xfer->ux_pipe); 1724 (void)xhci_reset_endpoint_locked(xfer->ux_pipe);
1715 break; 1725 break;
1716 case XHCI_EPSTATE_STOPPED: 1726 case XHCI_EPSTATE_STOPPED:
1717 break; 1727 break;
1718 default: 1728 default:
1719 (void)xhci_stop_endpoint(xfer->ux_pipe); 1729 (void)xhci_stop_endpoint(xfer->ux_pipe);
1720 break; 1730 break;
1721 } 1731 }
1722#ifdef DIAGNOSTIC 1732#ifdef DIAGNOSTIC
1723 uint32_t epst = xhci_get_epstate(sc, xs, dci); 1733 uint32_t epst = xhci_get_epstate(sc, xs, dci);
1724 if (epst != XHCI_EPSTATE_STOPPED) 1734 if (epst != XHCI_EPSTATE_STOPPED)
1725 DPRINTFN(4, "dci %u not stopped %u", dci, epst, 0, 0); 1735 DPRINTFN(4, "dci %u not stopped %u", dci, epst, 0, 0);
1726#endif 1736#endif
1727 1737
1728 /* 1738 /*
1729 * Step 3: Remove any vestiges of the xfer from the ring. 1739 * HC Step 2: Remove any vestiges of the xfer from the ring.
1730 */ 1740 */
1731 xhci_set_dequeue_locked(xfer->ux_pipe); 1741 xhci_set_dequeue_locked(xfer->ux_pipe);
1732 1742
1733 /* 1743 /*
1734 * Step 4: Notify completion to waiting xfers. 1744 * Final Step: Notify completion to waiting xfers.
1735 */ 1745 */
1736 int wake = xfer->ux_hcflags & UXFER_ABORTWAIT; 1746dying:
1737 xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); 
1738 usb_transfer_complete(xfer); 1747 usb_transfer_complete(xfer);
1739 if (wake) { 
1740 cv_broadcast(&xfer->ux_hccv); 
1741 } 
1742 DPRINTFN(14, "end", 0, 0, 0, 0); 1748 DPRINTFN(14, "end", 0, 0, 0, 0);
1743 1749
1744 KASSERT(mutex_owned(&sc->sc_lock)); 1750 KASSERT(mutex_owned(&sc->sc_lock));
1745} 1751}
1746 1752
1747static void 1753static void
1748xhci_host_dequeue(struct xhci_ring * const xr) 1754xhci_host_dequeue(struct xhci_ring * const xr)
1749{ 1755{
1750 /* When dequeueing the controller, update our struct copy too */ 1756 /* When dequeueing the controller, update our struct copy too */
1751 memset(xr->xr_trb, 0, xr->xr_ntrb * XHCI_TRB_SIZE); 1757 memset(xr->xr_trb, 0, xr->xr_ntrb * XHCI_TRB_SIZE);
1752 usb_syncmem(&xr->xr_dma, 0, xr->xr_ntrb * XHCI_TRB_SIZE, 1758 usb_syncmem(&xr->xr_dma, 0, xr->xr_ntrb * XHCI_TRB_SIZE,
1753 BUS_DMASYNC_PREWRITE); 1759 BUS_DMASYNC_PREWRITE);
1754 memset(xr->xr_cookies, 0, xr->xr_ntrb * sizeof(*xr->xr_cookies)); 1760 memset(xr->xr_cookies, 0, xr->xr_ntrb * sizeof(*xr->xr_cookies));
@@ -1957,68 +1963,96 @@ xhci_event_transfer(struct xhci_softc *  @@ -1957,68 +1963,96 @@ xhci_event_transfer(struct xhci_softc *
1957 } 1963 }
1958 } else if ((trb_0 & 0x3) == 0x3) { 1964 } else if ((trb_0 & 0x3) == 0x3) {
1959 return; 1965 return;
1960 } 1966 }
1961 err = USBD_NORMAL_COMPLETION; 1967 err = USBD_NORMAL_COMPLETION;
1962 break; 1968 break;
1963 case XHCI_TRB_ERROR_STOPPED: 1969 case XHCI_TRB_ERROR_STOPPED:
1964 case XHCI_TRB_ERROR_LENGTH: 1970 case XHCI_TRB_ERROR_LENGTH:
1965 case XHCI_TRB_ERROR_STOPPED_SHORT: 1971 case XHCI_TRB_ERROR_STOPPED_SHORT:
1966 /* 1972 /*
1967 * don't complete the transfer being aborted 1973 * don't complete the transfer being aborted
1968 * as abort_xfer does instead. 1974 * as abort_xfer does instead.
1969 */ 1975 */
1970 if (xfer->ux_hcflags & UXFER_ABORTING) { 1976 if (xfer->ux_status == USBD_CANCELLED ||
 1977 xfer->ux_status == USBD_TIMEOUT) {
1971 DPRINTFN(14, "ignore aborting xfer %p", xfer, 0, 0, 0); 1978 DPRINTFN(14, "ignore aborting xfer %p", xfer, 0, 0, 0);
1972 return; 1979 return;
1973 } 1980 }
1974 err = USBD_CANCELLED; 1981 err = USBD_CANCELLED;
1975 break; 1982 break;
1976 case XHCI_TRB_ERROR_STALL: 1983 case XHCI_TRB_ERROR_STALL:
1977 case XHCI_TRB_ERROR_BABBLE: 1984 case XHCI_TRB_ERROR_BABBLE:
1978 DPRINTFN(1, "ERR %u slot %u dci %u", trbcode, slot, dci, 0); 1985 DPRINTFN(1, "ERR %u slot %u dci %u", trbcode, slot, dci, 0);
1979 xr->is_halted = true; 1986 xr->is_halted = true;
1980 err = USBD_STALLED; 
1981 /* 1987 /*
1982 * Stalled endpoints can be recoverd by issuing 1988 * Stalled endpoints can be recoverd by issuing
1983 * command TRB TYPE_RESET_EP on xHCI instead of 1989 * command TRB TYPE_RESET_EP on xHCI instead of
1984 * issuing request CLEAR_FEATURE UF_ENDPOINT_HALT 1990 * issuing request CLEAR_FEATURE UF_ENDPOINT_HALT
1985 * on the endpoint. However, this function may be 1991 * on the endpoint. However, this function may be
1986 * called from softint context (e.g. from umass), 1992 * called from softint context (e.g. from umass),
1987 * in that case driver gets KASSERT in cv_timedwait 1993 * in that case driver gets KASSERT in cv_timedwait
1988 * in xhci_do_command. 1994 * in xhci_do_command.
1989 * To avoid this, this runs reset_endpoint and 1995 * To avoid this, this runs reset_endpoint and
1990 * usb_transfer_complete in usb task thread 1996 * usb_transfer_complete in usb task thread
1991 * asynchronously (and then umass issues clear 1997 * asynchronously (and then umass issues clear
1992 * UF_ENDPOINT_HALT). 1998 * UF_ENDPOINT_HALT).
1993 */ 1999 */
1994 xfer->ux_status = err; 2000
 2001 /* Override the status. */
 2002 xfer->ux_status = USBD_STALLED;
 2003
 2004 /*
 2005 * Cancel the timeout and the task, which have not yet
 2006 * run. If they have already fired, at worst they are
 2007 * waiting for the lock. They will see that the xfer
 2008 * is no longer in progress and give up.
 2009 */
1995 callout_stop(&xfer->ux_callout); 2010 callout_stop(&xfer->ux_callout);
 2011 usb_rem_task(xfer->ux_pipe->up_dev, &xfer->ux_aborttask);
 2012
1996 xhci_clear_endpoint_stall_async(xfer); 2013 xhci_clear_endpoint_stall_async(xfer);
1997 return; 2014 return;
1998 default: 2015 default:
1999 DPRINTFN(1, "ERR %u slot %u dci %u", trbcode, slot, dci, 0); 2016 DPRINTFN(1, "ERR %u slot %u dci %u", trbcode, slot, dci, 0);
2000 err = USBD_IOERROR; 2017 err = USBD_IOERROR;
2001 break; 2018 break;
2002 } 2019 }
 2020
 2021 /*
 2022 * If software has completed it, either by cancellation
 2023 * or timeout, drop it on the floor.
 2024 */
 2025 if (xfer->ux_status != USBD_IN_PROGRESS) {
 2026 KASSERTMSG((xfer->ux_status == USBD_CANCELLED ||
 2027 xfer->ux_status == USBD_TIMEOUT),
 2028 "xfer %p status %x", xfer, xfer->ux_status);
 2029 return;;
 2030 }
 2031
 2032 /* Otherwise, set the status. */
2003 xfer->ux_status = err; 2033 xfer->ux_status = err;
2004 2034
2005 if ((trb_3 & XHCI_TRB_3_ED_BIT) != 0) { 2035 /*
2006 if ((trb_0 & 0x3) == 0x0) { 2036 * Cancel the timeout and the task, which have not yet
2007 callout_stop(&xfer->ux_callout); 2037 * run. If they have already fired, at worst they are
2008 usb_transfer_complete(xfer); 2038 * waiting for the lock. They will see that the xfer
2009 } 2039 * is no longer in progress and give up.
2010 } else { 2040 */
2011 callout_stop(&xfer->ux_callout); 2041 callout_stop(&xfer->ux_callout);
 2042 usb_rem_task(xfer->ux_pipe->up_dev, &xfer->ux_aborttask);
 2043
 2044 if ((trb_3 & XHCI_TRB_3_ED_BIT) == 0 ||
 2045 (trb_0 & 0x3) == 0x0) {
2012 usb_transfer_complete(xfer); 2046 usb_transfer_complete(xfer);
2013 } 2047 }
2014} 2048}
2015 2049
2016/* Process Command complete events */ 2050/* Process Command complete events */
2017static void 2051static void
2018xhci_event_cmd(struct xhci_softc * const sc, const struct xhci_trb * const trb) 2052xhci_event_cmd(struct xhci_softc * const sc, const struct xhci_trb * const trb)
2019{ 2053{
2020 uint64_t trb_0; 2054 uint64_t trb_0;
2021 uint32_t trb_2, trb_3; 2055 uint32_t trb_2, trb_3;
2022 2056
2023 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 2057 XHCIHIST_FUNC(); XHCIHIST_CALLED();
2024 2058
@@ -2161,26 +2195,28 @@ xhci_poll(struct usbd_bus *bus) @@ -2161,26 +2195,28 @@ xhci_poll(struct usbd_bus *bus)
2161} 2195}
2162 2196
2163static struct usbd_xfer * 2197static struct usbd_xfer *
2164xhci_allocx(struct usbd_bus *bus, unsigned int nframes) 2198xhci_allocx(struct usbd_bus *bus, unsigned int nframes)
2165{ 2199{
2166 struct xhci_softc * const sc = XHCI_BUS2SC(bus); 2200 struct xhci_softc * const sc = XHCI_BUS2SC(bus);
2167 struct usbd_xfer *xfer; 2201 struct usbd_xfer *xfer;
2168 2202
2169 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 2203 XHCIHIST_FUNC(); XHCIHIST_CALLED();
2170 2204
2171 xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK); 2205 xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK);
2172 if (xfer != NULL) { 2206 if (xfer != NULL) {
2173 memset(xfer, 0, sizeof(struct xhci_xfer)); 2207 memset(xfer, 0, sizeof(struct xhci_xfer));
 2208 usb_init_task(&xfer->ux_aborttask, xhci_timeout_task, xfer,
 2209 USB_TASKQ_MPSAFE);
2174#ifdef DIAGNOSTIC 2210#ifdef DIAGNOSTIC
2175 xfer->ux_state = XFER_BUSY; 2211 xfer->ux_state = XFER_BUSY;
2176#endif 2212#endif
2177 } 2213 }
2178 2214
2179 return xfer; 2215 return xfer;
2180} 2216}
2181 2217
2182static void 2218static void
2183xhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) 2219xhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
2184{ 2220{
2185 struct xhci_softc * const sc = XHCI_BUS2SC(bus); 2221 struct xhci_softc * const sc = XHCI_BUS2SC(bus);
2186 2222
@@ -3762,26 +3798,27 @@ xhci_device_ctrl_start(struct usbd_xfer  @@ -3762,26 +3798,27 @@ xhci_device_ctrl_start(struct usbd_xfer
3762 XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DATA_STAGE) | 3798 XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DATA_STAGE) |
3763 (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) | 3799 (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) |
3764 XHCI_TRB_3_IOC_BIT; 3800 XHCI_TRB_3_IOC_BIT;
3765 xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); 3801 xhci_trb_put(&xx->xx_trb[i++], parameter, status, control);
3766 } 3802 }
3767 3803
3768 parameter = 0; 3804 parameter = 0;
3769 status = XHCI_TRB_2_IRQ_SET(0); 3805 status = XHCI_TRB_2_IRQ_SET(0);
3770 /* the status stage has inverted direction */ 3806 /* the status stage has inverted direction */
3771 control = ((isread && (len > 0)) ? 0 : XHCI_TRB_3_DIR_IN) | 3807 control = ((isread && (len > 0)) ? 0 : XHCI_TRB_3_DIR_IN) |
3772 XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_STATUS_STAGE) | 3808 XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_STATUS_STAGE) |
3773 XHCI_TRB_3_IOC_BIT; 3809 XHCI_TRB_3_IOC_BIT;
3774 xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); 3810 xhci_trb_put(&xx->xx_trb[i++], parameter, status, control);
 3811 xfer->ux_status = USBD_IN_PROGRESS;
3775 3812
3776 mutex_enter(&tr->xr_lock); 3813 mutex_enter(&tr->xr_lock);
3777 xhci_ring_put(sc, tr, xfer, xx->xx_trb, i); 3814 xhci_ring_put(sc, tr, xfer, xx->xx_trb, i);
3778 mutex_exit(&tr->xr_lock); 3815 mutex_exit(&tr->xr_lock);
3779 3816
3780 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); 3817 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci);
3781 3818
3782 if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { 3819 if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) {
3783 callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), 3820 callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout),
3784 xhci_timeout, xfer); 3821 xhci_timeout, xfer);
3785 } 3822 }
3786 3823
3787 return USBD_IN_PROGRESS; 3824 return USBD_IN_PROGRESS;
@@ -3878,26 +3915,27 @@ xhci_device_bulk_start(struct usbd_xfer  @@ -3878,26 +3915,27 @@ xhci_device_bulk_start(struct usbd_xfer
3878 * blocks needed to complete the transfer. 3915 * blocks needed to complete the transfer.
3879 * Setting it to 1 in the last TRB causes an extra zero-length 3916 * Setting it to 1 in the last TRB causes an extra zero-length
3880 * data block be sent. 3917 * data block be sent.
3881 * The earlier documentation differs, I don't know how it behaves. 3918 * The earlier documentation differs, I don't know how it behaves.
3882 */ 3919 */
3883 KASSERTMSG(len <= 0x10000, "len %d", len); 3920 KASSERTMSG(len <= 0x10000, "len %d", len);
3884 status = XHCI_TRB_2_IRQ_SET(0) | 3921 status = XHCI_TRB_2_IRQ_SET(0) |
3885 XHCI_TRB_2_TDSZ_SET(1) | 3922 XHCI_TRB_2_TDSZ_SET(1) |
3886 XHCI_TRB_2_BYTES_SET(len); 3923 XHCI_TRB_2_BYTES_SET(len);
3887 control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL) | 3924 control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL) |
3888 (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) | 3925 (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) |
3889 XHCI_TRB_3_IOC_BIT; 3926 XHCI_TRB_3_IOC_BIT;
3890 xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); 3927 xhci_trb_put(&xx->xx_trb[i++], parameter, status, control);
 3928 xfer->ux_status = USBD_IN_PROGRESS;
3891 3929
3892 mutex_enter(&tr->xr_lock); 3930 mutex_enter(&tr->xr_lock);
3893 xhci_ring_put(sc, tr, xfer, xx->xx_trb, i); 3931 xhci_ring_put(sc, tr, xfer, xx->xx_trb, i);
3894 mutex_exit(&tr->xr_lock); 3932 mutex_exit(&tr->xr_lock);
3895 3933
3896 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); 3934 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci);
3897 3935
3898 if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { 3936 if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) {
3899 callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), 3937 callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout),
3900 xhci_timeout, xfer); 3938 xhci_timeout, xfer);
3901 } 3939 }
3902 3940
3903 return USBD_IN_PROGRESS; 3941 return USBD_IN_PROGRESS;
@@ -3984,26 +4022,27 @@ xhci_device_intr_start(struct usbd_xfer  @@ -3984,26 +4022,27 @@ xhci_device_intr_start(struct usbd_xfer
3984 return USBD_IOERROR; 4022 return USBD_IOERROR;
3985 4023
3986 KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0); 4024 KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0);
3987 4025
3988 parameter = DMAADDR(dma, 0); 4026 parameter = DMAADDR(dma, 0);
3989 KASSERTMSG(len <= 0x10000, "len %d", len); 4027 KASSERTMSG(len <= 0x10000, "len %d", len);
3990 status = XHCI_TRB_2_IRQ_SET(0) | 4028 status = XHCI_TRB_2_IRQ_SET(0) |
3991 XHCI_TRB_2_TDSZ_SET(1) | 4029 XHCI_TRB_2_TDSZ_SET(1) |
3992 XHCI_TRB_2_BYTES_SET(len); 4030 XHCI_TRB_2_BYTES_SET(len);
3993 control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL) | 4031 control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL) |
3994 (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) | 4032 (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) |
3995 XHCI_TRB_3_IOC_BIT; 4033 XHCI_TRB_3_IOC_BIT;
3996 xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); 4034 xhci_trb_put(&xx->xx_trb[i++], parameter, status, control);
 4035 xfer->ux_status = USBD_IN_PROGRESS;
3997 4036
3998 mutex_enter(&tr->xr_lock); 4037 mutex_enter(&tr->xr_lock);
3999 xhci_ring_put(sc, tr, xfer, xx->xx_trb, i); 4038 xhci_ring_put(sc, tr, xfer, xx->xx_trb, i);
4000 mutex_exit(&tr->xr_lock); 4039 mutex_exit(&tr->xr_lock);
4001 4040
4002 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); 4041 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci);
4003 4042
4004 if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { 4043 if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) {
4005 callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), 4044 callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout),
4006 xhci_timeout, xfer); 4045 xhci_timeout, xfer);
4007 } 4046 }
4008 4047
4009 return USBD_IN_PROGRESS; 4048 return USBD_IN_PROGRESS;
@@ -4048,41 +4087,36 @@ xhci_device_intr_close(struct usbd_pipe  @@ -4048,41 +4087,36 @@ xhci_device_intr_close(struct usbd_pipe
4048 //struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); 4087 //struct xhci_softc * const sc = XHCI_PIPE2SC(pipe);
4049 4088
4050 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 4089 XHCIHIST_FUNC(); XHCIHIST_CALLED();
4051 DPRINTFN(15, "%p", pipe, 0, 0, 0); 4090 DPRINTFN(15, "%p", pipe, 0, 0, 0);
4052 4091
4053 xhci_close_pipe(pipe); 4092 xhci_close_pipe(pipe);
4054} 4093}
4055 4094
4056/* ------------ */ 4095/* ------------ */
4057 4096
4058static void 4097static void
4059xhci_timeout(void *addr) 4098xhci_timeout(void *addr)
4060{ 4099{
 4100 XHCIHIST_FUNC(); XHCIHIST_CALLED();
4061 struct xhci_xfer * const xx = addr; 4101 struct xhci_xfer * const xx = addr;
4062 struct usbd_xfer * const xfer = &xx->xx_xfer; 4102 struct usbd_xfer * const xfer = &xx->xx_xfer;
4063 struct xhci_softc * const sc = XHCI_XFER2SC(xfer); 4103 struct xhci_softc * const sc = XHCI_XFER2SC(xfer);
 4104 struct usbd_device *dev = xfer->ux_pipe->up_dev;
4064 4105
4065 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 4106 mutex_enter(&sc->sc_lock);
4066 4107 if (!sc->sc_dying && xfer->ux_status == USBD_IN_PROGRESS)
4067 if (sc->sc_dying) { 4108 usb_add_task(dev, &xfer->ux_aborttask, USB_TASKQ_HC);
4068 return; 4109 mutex_exit(&sc->sc_lock);
4069 } 
4070 
4071 usb_init_task(&xx->xx_abort_task, xhci_timeout_task, addr, 
4072 USB_TASKQ_MPSAFE); 
4073 usb_add_task(xx->xx_xfer.ux_pipe->up_dev, &xx->xx_abort_task, 
4074 USB_TASKQ_HC); 
4075} 4110}
4076 4111
4077static void 4112static void
4078xhci_timeout_task(void *addr) 4113xhci_timeout_task(void *addr)
4079{ 4114{
 4115 XHCIHIST_FUNC(); XHCIHIST_CALLED();
4080 struct usbd_xfer * const xfer = addr; 4116 struct usbd_xfer * const xfer = addr;
4081 struct xhci_softc * const sc = XHCI_XFER2SC(xfer); 4117 struct xhci_softc * const sc = XHCI_XFER2SC(xfer);
4082 4118
4083 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 
4084 
4085 mutex_enter(&sc->sc_lock); 4119 mutex_enter(&sc->sc_lock);
4086 xhci_abort_xfer(xfer, USBD_TIMEOUT); 4120 xhci_abort_xfer(xfer, USBD_TIMEOUT);
4087 mutex_exit(&sc->sc_lock); 4121 mutex_exit(&sc->sc_lock);
4088} 4122}

cvs diff -r1.4.8.1 -r1.4.8.2 src/sys/dev/usb/xhcivar.h (expand / switch to unified diff)

--- src/sys/dev/usb/xhcivar.h 2017/04/05 19:54:21 1.4.8.1
+++ src/sys/dev/usb/xhcivar.h 2018/08/25 14:57:35 1.4.8.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xhcivar.h,v 1.4.8.1 2017/04/05 19:54:21 snj Exp $ */ 1/* $NetBSD: xhcivar.h,v 1.4.8.2 2018/08/25 14:57:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2013 Jonathan A. Kollasch 4 * Copyright (c) 2013 Jonathan A. Kollasch
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -25,27 +25,26 @@ @@ -25,27 +25,26 @@
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#ifndef _DEV_USB_XHCIVAR_H_ 29#ifndef _DEV_USB_XHCIVAR_H_
30#define _DEV_USB_XHCIVAR_H_ 30#define _DEV_USB_XHCIVAR_H_
31 31
32#include <sys/pool.h> 32#include <sys/pool.h>
33 33
34#define XHCI_XFER_NTRB 20 34#define XHCI_XFER_NTRB 20
35 35
36struct xhci_xfer { 36struct xhci_xfer {
37 struct usbd_xfer xx_xfer; 37 struct usbd_xfer xx_xfer;
38 struct usb_task xx_abort_task; 
39 struct xhci_trb xx_trb[XHCI_XFER_NTRB]; 38 struct xhci_trb xx_trb[XHCI_XFER_NTRB];
40}; 39};
41 40
42#define XHCI_BUS2SC(bus) ((bus)->ub_hcpriv) 41#define XHCI_BUS2SC(bus) ((bus)->ub_hcpriv)
43#define XHCI_PIPE2SC(pipe) XHCI_BUS2SC((pipe)->up_dev->ud_bus) 42#define XHCI_PIPE2SC(pipe) XHCI_BUS2SC((pipe)->up_dev->ud_bus)
44#define XHCI_XFER2SC(xfer) XHCI_BUS2SC((xfer)->ux_bus) 43#define XHCI_XFER2SC(xfer) XHCI_BUS2SC((xfer)->ux_bus)
45#define XHCI_XFER2BUS(xfer) ((xfer)->ux_bus) 44#define XHCI_XFER2BUS(xfer) ((xfer)->ux_bus)
46#define XHCI_XPIPE2SC(d) XHCI_BUS2SC((d)->xp_pipe.up_dev->ud_bus) 45#define XHCI_XPIPE2SC(d) XHCI_BUS2SC((d)->xp_pipe.up_dev->ud_bus)
47 46
48#define XHCI_XFER2XXFER(xfer) ((struct xhci_xfer *)(xfer)) 47#define XHCI_XFER2XXFER(xfer) ((struct xhci_xfer *)(xfer))
49 48
50struct xhci_ring { 49struct xhci_ring {
51 usb_dma_t xr_dma; 50 usb_dma_t xr_dma;
@@ -75,27 +74,26 @@ struct xhci_softc { @@ -75,27 +74,26 @@ struct xhci_softc {
75 device_t sc_child2; 74 device_t sc_child2;
76 bus_size_t sc_ios; 75 bus_size_t sc_ios;
77 bus_space_tag_t sc_iot; 76 bus_space_tag_t sc_iot;
78 bus_space_handle_t sc_ioh; /* Base */ 77 bus_space_handle_t sc_ioh; /* Base */
79 bus_space_handle_t sc_cbh; /* Capability Base */ 78 bus_space_handle_t sc_cbh; /* Capability Base */
80 bus_space_handle_t sc_obh; /* Operational Base */ 79 bus_space_handle_t sc_obh; /* Operational Base */
81 bus_space_handle_t sc_rbh; /* Runtime Base */ 80 bus_space_handle_t sc_rbh; /* Runtime Base */
82 bus_space_handle_t sc_dbh; /* Doorbell Registers */ 81 bus_space_handle_t sc_dbh; /* Doorbell Registers */
83 struct usbd_bus sc_bus; /* USB 3 bus */ 82 struct usbd_bus sc_bus; /* USB 3 bus */
84 struct usbd_bus sc_bus2; /* USB 2 bus */ 83 struct usbd_bus sc_bus2; /* USB 2 bus */
85 84
86 kmutex_t sc_lock; 85 kmutex_t sc_lock;
87 kmutex_t sc_intr_lock; 86 kmutex_t sc_intr_lock;
88 kcondvar_t sc_softwake_cv; 
89 87
90 char sc_vendor[32]; /* vendor string for root hub */ 88 char sc_vendor[32]; /* vendor string for root hub */
91 int sc_id_vendor; /* vendor ID for root hub */ 89 int sc_id_vendor; /* vendor ID for root hub */
92 90
93 pool_cache_t sc_xferpool; 91 pool_cache_t sc_xferpool;
94 92
95 bus_size_t sc_pgsz; /* xHCI page size */ 93 bus_size_t sc_pgsz; /* xHCI page size */
96 uint32_t sc_ctxsz; 94 uint32_t sc_ctxsz;
97 int sc_maxslots; 95 int sc_maxslots;
98 int sc_maxintrs; 96 int sc_maxintrs;
99 int sc_maxspbuf; 97 int sc_maxspbuf;
100 98
101 /* 99 /*

cvs diff -r1.31.2.3 -r1.31.2.4 src/sys/external/bsd/dwc2/dwc2.c (expand / switch to unified diff)

--- src/sys/external/bsd/dwc2/dwc2.c 2018/01/03 20:02:37 1.31.2.3
+++ src/sys/external/bsd/dwc2/dwc2.c 2018/08/25 14:57:35 1.31.2.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: dwc2.c,v 1.31.2.3 2018/01/03 20:02:37 snj Exp $ */ 1/* $NetBSD: dwc2.c,v 1.31.2.4 2018/08/25 14:57:35 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2013 The NetBSD Foundation, Inc. 4 * Copyright (c) 2013 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 Nick Hudson 8 * by Nick Hudson
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.31.2.3 2018/01/03 20:02:37 snj Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.31.2.4 2018/08/25 14:57:35 martin Exp $");
34 34
35#include "opt_usb.h" 35#include "opt_usb.h"
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/kmem.h> 39#include <sys/kmem.h>
40#include <sys/kernel.h> 40#include <sys/kernel.h>
41#include <sys/device.h> 41#include <sys/device.h>
42#include <sys/select.h> 42#include <sys/select.h>
43#include <sys/proc.h> 43#include <sys/proc.h>
44#include <sys/queue.h> 44#include <sys/queue.h>
45#include <sys/cpu.h> 45#include <sys/cpu.h>
46 46
@@ -193,37 +193,42 @@ Static const struct usbd_pipe_methods dw @@ -193,37 +193,42 @@ Static const struct usbd_pipe_methods dw
193Static const struct usbd_pipe_methods dwc2_device_isoc_methods = { 193Static const struct usbd_pipe_methods dwc2_device_isoc_methods = {
194 .upm_transfer = dwc2_device_isoc_transfer, 194 .upm_transfer = dwc2_device_isoc_transfer,
195 .upm_abort = dwc2_device_isoc_abort, 195 .upm_abort = dwc2_device_isoc_abort,
196 .upm_close = dwc2_device_isoc_close, 196 .upm_close = dwc2_device_isoc_close,
197 .upm_cleartoggle = dwc2_noop, 197 .upm_cleartoggle = dwc2_noop,
198 .upm_done = dwc2_device_isoc_done, 198 .upm_done = dwc2_device_isoc_done,
199}; 199};
200 200
201struct usbd_xfer * 201struct usbd_xfer *
202dwc2_allocx(struct usbd_bus *bus, unsigned int nframes) 202dwc2_allocx(struct usbd_bus *bus, unsigned int nframes)
203{ 203{
204 struct dwc2_softc *sc = DWC2_BUS2SC(bus); 204 struct dwc2_softc *sc = DWC2_BUS2SC(bus);
205 struct dwc2_xfer *dxfer; 205 struct dwc2_xfer *dxfer;
 206 struct usbd_xfer *xfer;
206 207
207 DPRINTFN(10, "\n"); 208 DPRINTFN(10, "\n");
208 209
209 DWC2_EVCNT_INCR(sc->sc_ev_xferpoolget); 210 DWC2_EVCNT_INCR(sc->sc_ev_xferpoolget);
210 dxfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK); 211 dxfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK);
 212 xfer = (struct usbd_xfer *)dxfer;
211 if (dxfer != NULL) { 213 if (dxfer != NULL) {
212 memset(dxfer, 0, sizeof(*dxfer)); 214 memset(dxfer, 0, sizeof(*dxfer));
213 215
214 dxfer->urb = dwc2_hcd_urb_alloc(sc->sc_hsotg, 216 dxfer->urb = dwc2_hcd_urb_alloc(sc->sc_hsotg,
215 nframes, GFP_KERNEL); 217 nframes, GFP_KERNEL);
216 218
 219 /* Initialise this always so we can call remove on it. */
 220 usb_init_task(&xfer->ux_aborttask, dwc2_timeout_task, xfer,
 221 USB_TASKQ_MPSAFE);
217#ifdef DIAGNOSTIC 222#ifdef DIAGNOSTIC
218 dxfer->xfer.ux_state = XFER_BUSY; 223 dxfer->xfer.ux_state = XFER_BUSY;
219#endif 224#endif
220 } 225 }
221 return (struct usbd_xfer *)dxfer; 226 return (struct usbd_xfer *)dxfer;
222} 227}
223 228
224void 229void
225dwc2_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) 230dwc2_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
226{ 231{
227 struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer); 232 struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer);
228 struct dwc2_softc *sc = DWC2_BUS2SC(bus); 233 struct dwc2_softc *sc = DWC2_BUS2SC(bus);
229 234
@@ -288,62 +293,53 @@ dwc2_softintr(void *v) @@ -288,62 +293,53 @@ dwc2_softintr(void *v)
288 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 293 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
289 294
290 mutex_spin_enter(&hsotg->lock); 295 mutex_spin_enter(&hsotg->lock);
291 while ((dxfer = TAILQ_FIRST(&sc->sc_complete)) != NULL) { 296 while ((dxfer = TAILQ_FIRST(&sc->sc_complete)) != NULL) {
292 297
293 KASSERTMSG(!callout_pending(&dxfer->xfer.ux_callout), 298 KASSERTMSG(!callout_pending(&dxfer->xfer.ux_callout),
294 "xfer %p pipe %p\n", dxfer, dxfer->xfer.ux_pipe); 299 "xfer %p pipe %p\n", dxfer, dxfer->xfer.ux_pipe);
295 300
296 /* 301 /*
297 * dwc2_abort_xfer will remove this transfer from the 302 * dwc2_abort_xfer will remove this transfer from the
298 * sc_complete queue 303 * sc_complete queue
299 */ 304 */
300 /*XXXNH not tested */ 305 /*XXXNH not tested */
301 if (dxfer->xfer.ux_hcflags & UXFER_ABORTING) { 306 if (dxfer->xfer.ux_status == USBD_CANCELLED ||
302 cv_broadcast(&dxfer->xfer.ux_hccv); 307 dxfer->xfer.ux_status == USBD_TIMEOUT) {
303 continue; 308 continue;
304 } 309 }
305 310
306 TAILQ_REMOVE(&sc->sc_complete, dxfer, xnext); 311 TAILQ_REMOVE(&sc->sc_complete, dxfer, xnext);
307 312
308 mutex_spin_exit(&hsotg->lock); 313 mutex_spin_exit(&hsotg->lock);
309 usb_transfer_complete(&dxfer->xfer); 314 usb_transfer_complete(&dxfer->xfer);
310 mutex_spin_enter(&hsotg->lock); 315 mutex_spin_enter(&hsotg->lock);
311 } 316 }
312 mutex_spin_exit(&hsotg->lock); 317 mutex_spin_exit(&hsotg->lock);
313} 318}
314 319
315Static void 320Static void
316dwc2_timeout(void *addr) 321dwc2_timeout(void *addr)
317{ 322{
318 struct usbd_xfer *xfer = addr; 323 struct usbd_xfer *xfer = addr;
319 struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer); 
320// struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer); 
321 struct dwc2_softc *sc = DWC2_XFER2SC(xfer); 324 struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
 325 struct usbd_device *dev = xfer->ux_pipe->up_dev;
322 326
323 DPRINTF("dxfer=%p\n", dxfer); 327 DPRINTF("dxfer=%p\n", dxfer);
324 328
325 if (sc->sc_dying) { 329 mutex_enter(&sc->sc_lock);
326 mutex_enter(&sc->sc_lock); 330 if (!sc->sc_dying && xfer->ux_status == USBD_IN_PROGRESS)
327 dwc2_abort_xfer(&dxfer->xfer, USBD_TIMEOUT); 331 usb_add_task(dev, &xfer->ux_aborttask, USB_TASKQ_HC);
328 mutex_exit(&sc->sc_lock); 332 mutex_exit(&sc->sc_lock);
329 return; 
330 } 
331 
332 /* Execute the abort in a process context. */ 
333 usb_init_task(&dxfer->abort_task, dwc2_timeout_task, addr, 
334 USB_TASKQ_MPSAFE); 
335 usb_add_task(dxfer->xfer.ux_pipe->up_dev, &dxfer->abort_task, 
336 USB_TASKQ_HC); 
337} 333}
338 334
339Static void 335Static void
340dwc2_timeout_task(void *addr) 336dwc2_timeout_task(void *addr)
341{ 337{
342 struct usbd_xfer *xfer = addr; 338 struct usbd_xfer *xfer = addr;
343 struct dwc2_softc *sc = DWC2_XFER2SC(xfer); 339 struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
344 340
345 DPRINTF("xfer=%p\n", xfer); 341 DPRINTF("xfer=%p\n", xfer);
346 342
347 mutex_enter(&sc->sc_lock); 343 mutex_enter(&sc->sc_lock);
348 dwc2_abort_xfer(xfer, USBD_TIMEOUT); 344 dwc2_abort_xfer(xfer, USBD_TIMEOUT);
349 mutex_exit(&sc->sc_lock); 345 mutex_exit(&sc->sc_lock);
@@ -439,86 +435,103 @@ dwc2_close_pipe(struct usbd_pipe *pipe) @@ -439,86 +435,103 @@ dwc2_close_pipe(struct usbd_pipe *pipe)
439 KASSERT(mutex_owned(&sc->sc_lock)); 435 KASSERT(mutex_owned(&sc->sc_lock));
440} 436}
441 437
442/* 438/*
443 * Abort a device request. 439 * Abort a device request.
444 */ 440 */
445Static void 441Static void
446dwc2_abort_xfer(struct usbd_xfer *xfer, usbd_status status) 442dwc2_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
447{ 443{
448 struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer); 444 struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer);
449 struct dwc2_softc *sc = DWC2_XFER2SC(xfer); 445 struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
450 struct dwc2_hsotg *hsotg = sc->sc_hsotg; 446 struct dwc2_hsotg *hsotg = sc->sc_hsotg;
451 struct dwc2_xfer *d, *tmp; 447 struct dwc2_xfer *d, *tmp;
452 bool wake; 
453 int err; 448 int err;
454 449
455 DPRINTF("xfer=%p\n", xfer); 450 KASSERTMSG((status == USBD_CANCELLED || status == USBD_TIMEOUT),
 451 "invalid status for abort: %d", (int)status);
 452
 453 DPRINTF("xfer %pjx pipe %pjx status %jd", xfer, xfer->ux_pipe, status);
456 454
457 KASSERT(mutex_owned(&sc->sc_lock)); 455 KASSERT(mutex_owned(&sc->sc_lock));
458 KASSERT(!cpu_intr_p() && !cpu_softintr_p()); 456 ASSERT_SLEEPABLE();
459 457
460 if (sc->sc_dying) { 458 if (status == USBD_CANCELLED) {
461 xfer->ux_status = status; 459 /*
462 callout_stop(&xfer->ux_callout); 460 * We are synchronously aborting. Try to stop the
463 usb_transfer_complete(xfer); 461 * callout and task, but if we can't, wait for them to
464 return; 462 * complete.
 463 */
 464 callout_halt(&xfer->ux_callout, &sc->sc_lock);
 465 usb_rem_task_wait(xfer->ux_pipe->up_dev, &xfer->ux_aborttask,
 466 USB_TASKQ_HC, &sc->sc_lock);
 467 } else {
 468 /* Otherwise, we are timing out. */
 469 KASSERT(status == USBD_TIMEOUT);
465 } 470 }
466 471
467 /* 472 /*
468 * If an abort is already in progress then just wait for it to 473 * The xfer cannot have been cancelled already. It is the
469 * complete and return. 474 * responsibility of the caller of usbd_abort_pipe not to try
 475 * to abort a pipe multiple times, whether concurrently or
 476 * sequentially.
470 */ 477 */
471 if (xfer->ux_hcflags & UXFER_ABORTING) { 478 KASSERT(xfer->ux_status != USBD_CANCELLED);
472 xfer->ux_status = status; 479
473 xfer->ux_hcflags |= UXFER_ABORTWAIT; 480 /* Only the timeout, which runs only once, can time it out. */
474 while (xfer->ux_hcflags & UXFER_ABORTING) 481 KASSERT(xfer->ux_status != USBD_TIMEOUT);
475 cv_wait(&xfer->ux_hccv, &sc->sc_lock); 482
 483 /* If anyone else beat us, we're done. */
 484 if (xfer->ux_status != USBD_IN_PROGRESS)
476 return; 485 return;
 486
 487 /* We beat everyone else. Claim the status. */
 488 xfer->ux_status = status;
 489
 490 /*
 491 * If we're dying, skip the hardware action and just notify the
 492 * software that we're done.
 493 */
 494 if (sc->sc_dying) {
 495 DPRINTFN(4, "xfer %#jx dying %ju", (uintptr_t)xfer,
 496 xfer->ux_status, 0, 0);
 497 goto dying;
477 } 498 }
478 499
479 /* 500 /*
480 * Step 1: Make the stack ignore it and stop the callout. 501 * HC Step 1: Handle the hardware.
481 */ 502 */
482 mutex_spin_enter(&hsotg->lock); 503 mutex_spin_enter(&hsotg->lock);
483 xfer->ux_hcflags |= UXFER_ABORTING; 
484 
485 xfer->ux_status = status; /* make software ignore it */ 
486 callout_stop(&xfer->ux_callout); 
487 
488 /* XXXNH suboptimal */ 504 /* XXXNH suboptimal */
489 TAILQ_FOREACH_SAFE(d, &sc->sc_complete, xnext, tmp) { 505 TAILQ_FOREACH_SAFE(d, &sc->sc_complete, xnext, tmp) {
490 if (d == dxfer) { 506 if (d == dxfer) {
491 TAILQ_REMOVE(&sc->sc_complete, dxfer, xnext); 507 TAILQ_REMOVE(&sc->sc_complete, dxfer, xnext);
 508 break;
492 } 509 }
493 } 510 }
494 511
495 err = dwc2_hcd_urb_dequeue(hsotg, dxfer->urb); 512 err = dwc2_hcd_urb_dequeue(hsotg, dxfer->urb);
496 if (err) { 513 if (err) {
497 DPRINTF("dwc2_hcd_urb_dequeue failed\n"); 514 DPRINTF("dwc2_hcd_urb_dequeue failed\n");
498 } 515 }
499 516
500 mutex_spin_exit(&hsotg->lock); 517 mutex_spin_exit(&hsotg->lock);
501 518
502 /* 519 /*
503 * Step 2: Execute callback. 520 * Final Step: Notify completion to waiting xfers.
504 */ 521 */
505 wake = xfer->ux_hcflags & UXFER_ABORTWAIT; 522dying:
506 xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); 
507 
508 usb_transfer_complete(xfer); 523 usb_transfer_complete(xfer);
509 if (wake) { 524 KASSERT(mutex_owned(&sc->sc_lock));
510 cv_broadcast(&xfer->ux_hccv); 
511 } 
512} 525}
513 526
514Static void 527Static void
515dwc2_noop(struct usbd_pipe *pipe) 528dwc2_noop(struct usbd_pipe *pipe)
516{ 529{
517 530
518} 531}
519 532
520Static void 533Static void
521dwc2_device_clear_toggle(struct usbd_pipe *pipe) 534dwc2_device_clear_toggle(struct usbd_pipe *pipe)
522{ 535{
523 536
524 DPRINTF("toggle %d -> 0", pipe->up_endpoint->ue_toggle); 537 DPRINTF("toggle %d -> 0", pipe->up_endpoint->ue_toggle);
@@ -1108,27 +1121,27 @@ dwc2_device_start(struct usbd_xfer *xfer @@ -1108,27 +1121,27 @@ dwc2_device_start(struct usbd_xfer *xfer
1108 1121
1109 if (alloc_bandwidth) { 1122 if (alloc_bandwidth) {
1110 dwc2_allocate_bus_bandwidth(hsotg, 1123 dwc2_allocate_bus_bandwidth(hsotg,
1111 dwc2_hcd_get_ep_bandwidth(hsotg, dpipe), 1124 dwc2_hcd_get_ep_bandwidth(hsotg, dpipe),
1112 xfer); 1125 xfer);
1113 } 1126 }
1114 1127
1115 mutex_spin_exit(&hsotg->lock); 1128 mutex_spin_exit(&hsotg->lock);
1116// mutex_exit(&sc->sc_lock); 1129// mutex_exit(&sc->sc_lock);
1117 1130
1118 return USBD_IN_PROGRESS; 1131 return USBD_IN_PROGRESS;
1119 1132
1120fail2: 1133fail2:
1121 callout_stop(&xfer->ux_callout); 1134 callout_halt(&xfer->ux_callout, &hsotg->lock);
1122 dwc2_urb->priv = NULL; 1135 dwc2_urb->priv = NULL;
1123 mutex_spin_exit(&hsotg->lock); 1136 mutex_spin_exit(&hsotg->lock);
1124 pool_cache_put(sc->sc_qtdpool, qtd); 1137 pool_cache_put(sc->sc_qtdpool, qtd);
1125 1138
1126fail1: 1139fail1:
1127 if (qh_allocated) { 1140 if (qh_allocated) {
1128 dpipe->priv = NULL; 1141 dpipe->priv = NULL;
1129 dwc2_hcd_qh_free(hsotg, qh); 1142 dwc2_hcd_qh_free(hsotg, qh);
1130 } 1143 }
1131fail: 1144fail:
1132 1145
1133 switch (retval) { 1146 switch (retval) {
1134 case -EINVAL: 1147 case -EINVAL:
@@ -1416,26 +1429,45 @@ void dwc2_host_complete(struct dwc2_hsot @@ -1416,26 +1429,45 @@ void dwc2_host_complete(struct dwc2_hsot
1416 } 1429 }
1417 1430
1418 if (!qtd->urb) { 1431 if (!qtd->urb) {
1419 dev_dbg(hsotg->dev, "## %s: qtd->urb is NULL ##\n", __func__); 1432 dev_dbg(hsotg->dev, "## %s: qtd->urb is NULL ##\n", __func__);
1420 return; 1433 return;
1421 } 1434 }
1422 1435
1423 xfer = qtd->urb->priv; 1436 xfer = qtd->urb->priv;
1424 if (!xfer) { 1437 if (!xfer) {
1425 dev_dbg(hsotg->dev, "## %s: urb->priv is NULL ##\n", __func__); 1438 dev_dbg(hsotg->dev, "## %s: urb->priv is NULL ##\n", __func__);
1426 return; 1439 return;
1427 } 1440 }
1428 1441
 1442 /*
 1443 * If software has completed it, either by cancellation
 1444 * or timeout, drop it on the floor.
 1445 */
 1446 if (xfer->ux_status != USBD_IN_PROGRESS) {
 1447 KASSERT(xfer->ux_status == USBD_CANCELLED ||
 1448 xfer->ux_status == USBD_TIMEOUT);
 1449 return;
 1450 }
 1451
 1452 /*
 1453 * Cancel the timeout and the task, which have not yet
 1454 * run. If they have already fired, at worst they are
 1455 * waiting for the lock. They will see that the xfer
 1456 * is no longer in progress and give up.
 1457 */
 1458 callout_stop(&xfer->ux_callout);
 1459 usb_rem_task(xfer->ux_pipe->up_dev, &xfer->ux_aborttask);
 1460
1429 dxfer = DWC2_XFER2DXFER(xfer); 1461 dxfer = DWC2_XFER2DXFER(xfer);
1430 sc = DWC2_XFER2SC(xfer); 1462 sc = DWC2_XFER2SC(xfer);
1431 ed = xfer->ux_pipe->up_endpoint->ue_edesc; 1463 ed = xfer->ux_pipe->up_endpoint->ue_edesc;
1432 xfertype = UE_GET_XFERTYPE(ed->bmAttributes); 1464 xfertype = UE_GET_XFERTYPE(ed->bmAttributes);
1433 1465
1434 struct dwc2_hcd_urb *urb = qtd->urb; 1466 struct dwc2_hcd_urb *urb = qtd->urb;
1435 xfer->ux_actlen = dwc2_hcd_urb_get_actual_length(urb); 1467 xfer->ux_actlen = dwc2_hcd_urb_get_actual_length(urb);
1436 1468
1437 DPRINTFN(3, "xfer=%p actlen=%d\n", xfer, xfer->ux_actlen); 1469 DPRINTFN(3, "xfer=%p actlen=%d\n", xfer, xfer->ux_actlen);
1438 1470
1439 if (xfertype == UE_ISOCHRONOUS) { 1471 if (xfertype == UE_ISOCHRONOUS) {
1440 int i; 1472 int i;
1441 1473
@@ -1500,28 +1532,26 @@ void dwc2_host_complete(struct dwc2_hsot @@ -1500,28 +1532,26 @@ void dwc2_host_complete(struct dwc2_hsot
1500 } 1532 }
1501 } 1533 }
1502 1534
1503 if (xfertype == UE_ISOCHRONOUS || 1535 if (xfertype == UE_ISOCHRONOUS ||
1504 xfertype == UE_INTERRUPT) { 1536 xfertype == UE_INTERRUPT) {
1505 struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer); 1537 struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer);
1506 1538
1507 dwc2_free_bus_bandwidth(hsotg, 1539 dwc2_free_bus_bandwidth(hsotg,
1508 dwc2_hcd_get_ep_bandwidth(hsotg, dpipe), 1540 dwc2_hcd_get_ep_bandwidth(hsotg, dpipe),
1509 xfer); 1541 xfer);
1510 } 1542 }
1511 1543
1512 qtd->urb = NULL; 1544 qtd->urb = NULL;
1513 callout_stop(&xfer->ux_callout); 
1514 
1515 KASSERT(mutex_owned(&hsotg->lock)); 1545 KASSERT(mutex_owned(&hsotg->lock));
1516 1546
1517 TAILQ_INSERT_TAIL(&sc->sc_complete, dxfer, xnext); 1547 TAILQ_INSERT_TAIL(&sc->sc_complete, dxfer, xnext);
1518 1548
1519 mutex_spin_exit(&hsotg->lock); 1549 mutex_spin_exit(&hsotg->lock);
1520 usb_schedsoftintr(&sc->sc_bus); 1550 usb_schedsoftintr(&sc->sc_bus);
1521 mutex_spin_enter(&hsotg->lock); 1551 mutex_spin_enter(&hsotg->lock);
1522} 1552}
1523 1553
1524 1554
1525int 1555int
1526_dwc2_hcd_start(struct dwc2_hsotg *hsotg) 1556_dwc2_hcd_start(struct dwc2_hsotg *hsotg)
1527{ 1557{