Thu Mar 3 06:12:11 2022 UTC ()
usb: Hold pipe lock across upm_transfer and upm_start.

This simplifies the code and fixes races with abort.  Access to the
pipe's queue is now done exclusively while the pipe is locked.


(riastradh)
diff -r1.29 -r1.30 src/sys/arch/mips/adm5120/dev/ahci.c
diff -r1.109 -r1.110 src/sys/dev/ic/sl811hs.c
diff -r1.304 -r1.305 src/sys/dev/usb/ehci.c
diff -r1.39 -r1.40 src/sys/dev/usb/motg.c
diff -r1.320 -r1.321 src/sys/dev/usb/ohci.c
diff -r1.310 -r1.311 src/sys/dev/usb/uhci.c
diff -r1.230 -r1.231 src/sys/dev/usb/usbdi.c
diff -r1.133 -r1.134 src/sys/dev/usb/usbdivar.h
diff -r1.12 -r1.13 src/sys/dev/usb/usbroothub.c
diff -r1.24 -r1.25 src/sys/dev/usb/vhci.c
diff -r1.157 -r1.158 src/sys/dev/usb/xhci.c
diff -r1.79 -r1.80 src/sys/external/bsd/dwc2/dwc2.c
diff -r1.30 -r1.31 src/sys/rump/dev/lib/libugenhc/ugenhc.c

cvs diff -r1.29 -r1.30 src/sys/arch/mips/adm5120/dev/ahci.c (expand / switch to unified diff)

--- src/sys/arch/mips/adm5120/dev/ahci.c 2022/03/03 06:04:31 1.29
+++ src/sys/arch/mips/adm5120/dev/ahci.c 2022/03/03 06:12:11 1.30
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ahci.c,v 1.29 2022/03/03 06:04:31 riastradh Exp $ */ 1/* $NetBSD: ahci.c,v 1.30 2022/03/03 06:12:11 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko. 4 * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or 7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following 8 * without modification, are permitted provided that the following
9 * conditions are met: 9 * conditions 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 12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following 13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided 14 * disclaimer in the documentation and/or other materials provided
@@ -54,27 +54,27 @@ @@ -54,27 +54,27 @@
54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
56 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 56 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
57 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59 * POSSIBILITY OF SUCH DAMAGE. 59 * POSSIBILITY OF SUCH DAMAGE.
60 */ 60 */
61 61
62/* 62/*
63 * !! HIGHLY EXPERIMENTAL CODE !! 63 * !! HIGHLY EXPERIMENTAL CODE !!
64 */ 64 */
65 65
66#include <sys/cdefs.h> 66#include <sys/cdefs.h>
67__KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.29 2022/03/03 06:04:31 riastradh Exp $"); 67__KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.30 2022/03/03 06:12:11 riastradh Exp $");
68 68
69#include <sys/param.h> 69#include <sys/param.h>
70#include <sys/systm.h> 70#include <sys/systm.h>
71#include <sys/kernel.h> 71#include <sys/kernel.h>
72#include <sys/proc.h> 72#include <sys/proc.h>
73#include <sys/device.h> 73#include <sys/device.h>
74#include <sys/kmem.h> 74#include <sys/kmem.h>
75 75
76#include <sys/bus.h> 76#include <sys/bus.h>
77#include <machine/cpu.h> 77#include <machine/cpu.h>
78 78
79#include <dev/usb/usb.h> 79#include <dev/usb/usb.h>
80#include <dev/usb/usbdi.h> 80#include <dev/usb/usbdi.h>
@@ -559,26 +559,28 @@ ahci_noop(struct usbd_pipe *pipe) @@ -559,26 +559,28 @@ ahci_noop(struct usbd_pipe *pipe)
559 559
560static int 560static int
561ahci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 561ahci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
562 void *buf, int buflen) 562 void *buf, int buflen)
563{ 563{
564 struct ahci_softc *sc = AHCI_BUS2SC(bus); 564 struct ahci_softc *sc = AHCI_BUS2SC(bus);
565 uint16_t len, value, index; 565 uint16_t len, value, index;
566 usb_port_status_t ps; 566 usb_port_status_t ps;
567 int totlen = 0; 567 int totlen = 0;
568 int status; 568 int status;
569 569
570 DPRINTF(D_TRACE, ("SLRCstart ")); 570 DPRINTF(D_TRACE, ("SLRCstart "));
571 571
 572 KASSERT(bus->ub_polling || mutex_owned(bus->ub_lock));
 573
572 len = UGETW(req->wLength); 574 len = UGETW(req->wLength);
573 value = UGETW(req->wValue); 575 value = UGETW(req->wValue);
574 index = UGETW(req->wIndex); 576 index = UGETW(req->wIndex);
575 577
576#define C(x,y) ((x) | ((y) << 8)) 578#define C(x,y) ((x) | ((y) << 8))
577 switch (C(req->bRequest, req->bmRequestType)) { 579 switch (C(req->bRequest, req->bmRequestType)) {
578 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 580 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
579 switch (value) { 581 switch (value) {
580#define sd ((usb_string_descriptor_t *)buf) 582#define sd ((usb_string_descriptor_t *)buf)
581 case C(2, UDESC_STRING): 583 case C(2, UDESC_STRING):
582 /* Product */ 584 /* Product */
583 totlen = usb_makestrdesc(sd, len, "ADM5120 root hub"); 585 totlen = usb_makestrdesc(sd, len, "ADM5120 root hub");
584 break; 586 break;
@@ -733,33 +735,33 @@ ahci_root_intr_transfer(struct usbd_xfer @@ -733,33 +735,33 @@ ahci_root_intr_transfer(struct usbd_xfer
733 DPRINTF(D_TRACE, ("SLRItransfer ")); 735 DPRINTF(D_TRACE, ("SLRItransfer "));
734 736
735 /* Pipe isn't running, start first. */ 737 /* Pipe isn't running, start first. */
736 return ahci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 738 return ahci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
737} 739}
738 740
739static usbd_status 741static usbd_status
740ahci_root_intr_start(struct usbd_xfer *xfer) 742ahci_root_intr_start(struct usbd_xfer *xfer)
741{ 743{
742 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 744 struct ahci_softc *sc = AHCI_XFER2SC(xfer);
743 745
744 DPRINTF(D_TRACE, ("SLRIstart ")); 746 DPRINTF(D_TRACE, ("SLRIstart "));
745 747
746 mutex_enter(&sc->sc_lock); 748 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock);
 749
747 KASSERT(sc->sc_intr_xfer == NULL); 750 KASSERT(sc->sc_intr_xfer == NULL);
748 sc->sc_interval = MS_TO_TICKS(xfer->ux_pipe->up_endpoint->ue_edesc->bInterval); 751 sc->sc_interval = MS_TO_TICKS(xfer->ux_pipe->up_endpoint->ue_edesc->bInterval);
749 callout_schedule(&sc->sc_poll_handle, sc->sc_interval); 752 callout_schedule(&sc->sc_poll_handle, sc->sc_interval);
750 sc->sc_intr_xfer = xfer; 753 sc->sc_intr_xfer = xfer;
751 xfer->ux_status = USBD_IN_PROGRESS; 754 xfer->ux_status = USBD_IN_PROGRESS;
752 mutex_exit(&sc->sc_lock); 
753 755
754 return USBD_IN_PROGRESS; 756 return USBD_IN_PROGRESS;
755} 757}
756 758
757static void 759static void
758ahci_root_intr_abort(struct usbd_xfer *xfer) 760ahci_root_intr_abort(struct usbd_xfer *xfer)
759{ 761{
760 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 762 struct ahci_softc *sc = AHCI_XFER2SC(xfer);
761 763
762 DPRINTF(D_TRACE, ("SLRIabort ")); 764 DPRINTF(D_TRACE, ("SLRIabort "));
763 765
764 KASSERT(mutex_owned(&sc->sc_lock)); 766 KASSERT(mutex_owned(&sc->sc_lock));
765 KASSERT(xfer->ux_pipe->up_intrxfer == xfer); 767 KASSERT(xfer->ux_pipe->up_intrxfer == xfer);
@@ -824,31 +826,31 @@ ahci_device_ctrl_transfer(struct usbd_xf @@ -824,31 +826,31 @@ ahci_device_ctrl_transfer(struct usbd_xf
824static usbd_status 826static usbd_status
825ahci_device_ctrl_start(struct usbd_xfer *xfer) 827ahci_device_ctrl_start(struct usbd_xfer *xfer)
826{ 828{
827 usbd_status status = USBD_NORMAL_COMPLETION; 829 usbd_status status = USBD_NORMAL_COMPLETION;
828 int s, err; 830 int s, err;
829 static struct admhcd_ed ep_v __attribute__((aligned(16))), *ep; 831 static struct admhcd_ed ep_v __attribute__((aligned(16))), *ep;
830 static struct admhcd_td td_v[4] __attribute__((aligned(16))), *td, *td1, *td2, *td3; 832 static struct admhcd_td td_v[4] __attribute__((aligned(16))), *td, *td1, *td2, *td3;
831 static usb_dma_t reqdma; 833 static usb_dma_t reqdma;
832 struct usbd_pipe *pipe = xfer->ux_pipe; 834 struct usbd_pipe *pipe = xfer->ux_pipe;
833 usb_device_request_t *req = &xfer->ux_request; 835 usb_device_request_t *req = &xfer->ux_request;
834 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 836 struct ahci_softc *sc = AHCI_XFER2SC(xfer);
835 int len, isread; 837 int len, isread;
836 838
 839 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock);
837 840
838#if 0 841#if 0
839 struct ahci_pipe *apipe = (struct ahci_pipe *)xfer->ux_pipe; 842 struct ahci_pipe *apipe = (struct ahci_pipe *)xfer->ux_pipe;
840#endif 843#endif
841 mutex_enter(&sc->sc_lock); 
842/* printf("ctrl_start>>>\n"); */ 844/* printf("ctrl_start>>>\n"); */
843 845
844#ifdef DIAGNOSTIC 846#ifdef DIAGNOSTIC
845 if (!(xfer->ux_rqflags & URQ_REQUEST)) { 847 if (!(xfer->ux_rqflags & URQ_REQUEST)) {
846 /* XXX panic */ 848 /* XXX panic */
847 printf("ahci_device_ctrl_transfer: not a request\n"); 849 printf("ahci_device_ctrl_transfer: not a request\n");
848 return USBD_INVAL; 850 return USBD_INVAL;
849 } 851 }
850#endif 852#endif
851 853
852#define KSEG1ADDR(x) (0xa0000000 | (((uint32_t)x) & 0x1fffffff)) 854#define KSEG1ADDR(x) (0xa0000000 | (((uint32_t)x) & 0x1fffffff))
853 DPRINTF(D_TRACE, ("st ")); 855 DPRINTF(D_TRACE, ("st "));
854 if (!ep) { 856 if (!ep) {
@@ -958,27 +960,26 @@ ahci_device_ctrl_start(struct usbd_xfer  @@ -958,27 +960,26 @@ ahci_device_ctrl_start(struct usbd_xfer
958 }; 960 };
959 status = USBD_NORMAL_COMPLETION; 961 status = USBD_NORMAL_COMPLETION;
960 break; 962 break;
961 963
962 }; 964 };
963 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP); 965 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP);
964 966
965 xfer->ux_actlen = len; 967 xfer->ux_actlen = len;
966 xfer->ux_status = status; 968 xfer->ux_status = status;
967 969
968/* printf("ctrl_start<<<\n"); */ 970/* printf("ctrl_start<<<\n"); */
969 971
970 usb_transfer_complete(xfer); 972 usb_transfer_complete(xfer);
971 mutex_exit(&sc->sc_lock); 
972 973
973 usb_freemem(&reqdma); 974 usb_freemem(&reqdma);
974 975
975 return USBD_NORMAL_COMPLETION; 976 return USBD_NORMAL_COMPLETION;
976} 977}
977 978
978static void 979static void
979ahci_device_ctrl_abort(struct usbd_xfer *xfer) 980ahci_device_ctrl_abort(struct usbd_xfer *xfer)
980{ 981{
981 DPRINTF(D_TRACE, ("Cab ")); 982 DPRINTF(D_TRACE, ("Cab "));
982 usbd_xfer_abort(xfer); 983 usbd_xfer_abort(xfer);
983} 984}
984 985
@@ -996,31 +997,34 @@ ahci_device_ctrl_done(struct usbd_xfer * @@ -996,31 +997,34 @@ ahci_device_ctrl_done(struct usbd_xfer *
996 997
997static usbd_status 998static usbd_status
998ahci_device_intr_transfer(struct usbd_xfer *xfer) 999ahci_device_intr_transfer(struct usbd_xfer *xfer)
999{ 1000{
1000 1001
1001 DPRINTF(D_TRACE, ("INTRtrans ")); 1002 DPRINTF(D_TRACE, ("INTRtrans "));
1002 1003
1003 return ahci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 1004 return ahci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
1004} 1005}
1005 1006
1006static usbd_status 1007static usbd_status
1007ahci_device_intr_start(struct usbd_xfer *xfer) 1008ahci_device_intr_start(struct usbd_xfer *xfer)
1008{ 1009{
 1010 struct ahci_softc *sc = AHCI_XFER2SC(xfer);
1009 struct usbd_pipe *pipe = xfer->ux_pipe; 1011 struct usbd_pipe *pipe = xfer->ux_pipe;
1010 struct ahci_xfer *sx; 1012 struct ahci_xfer *sx;
1011 1013
1012 DPRINTF(D_TRACE, ("INTRstart ")); 1014 DPRINTF(D_TRACE, ("INTRstart "));
1013 1015
 1016 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock);
 1017
1014 sx = kmem_intr_alloc(sizeof(*sx), KM_NOSLEEP); 1018 sx = kmem_intr_alloc(sizeof(*sx), KM_NOSLEEP);
1015 if (sx == NULL) 1019 if (sx == NULL)
1016 goto reterr; 1020 goto reterr;
1017 memset(sx, 0, sizeof(*sx)); 1021 memset(sx, 0, sizeof(*sx));
1018 sx->sx_xfer = xfer; 1022 sx->sx_xfer = xfer;
1019 xfer->ux_hcpriv = sx; 1023 xfer->ux_hcpriv = sx;
1020 1024
1021 /* initialize callout */ 1025 /* initialize callout */
1022 callout_init(&sx->sx_callout_t, 0); 1026 callout_init(&sx->sx_callout_t, 0);
1023 callout_reset(&sx->sx_callout_t, 1027 callout_reset(&sx->sx_callout_t,
1024 MS_TO_TICKS(pipe->up_endpoint->ue_edesc->bInterval), 1028 MS_TO_TICKS(pipe->up_endpoint->ue_edesc->bInterval),
1025 ahci_poll_device, sx); 1029 ahci_poll_device, sx);
1026 1030
@@ -1146,35 +1150,36 @@ ahci_device_bulk_start(struct usbd_xfer  @@ -1146,35 +1150,36 @@ ahci_device_bulk_start(struct usbd_xfer
1146 static volatile int level = 0; 1150 static volatile int level = 0;
1147 usbd_status status = USBD_NORMAL_COMPLETION; 1151 usbd_status status = USBD_NORMAL_COMPLETION;
1148 int s, err; 1152 int s, err;
1149 static struct admhcd_ed ep_v __attribute__((aligned(16))), *ep; 1153 static struct admhcd_ed ep_v __attribute__((aligned(16))), *ep;
1150 static struct admhcd_td td_v[NBULK_TDS] __attribute__((aligned(16))), *td[NBULK_TDS]; 1154 static struct admhcd_td td_v[NBULK_TDS] __attribute__((aligned(16))), *td[NBULK_TDS];
1151 struct usbd_pipe *pipe = xfer->ux_pipe; 1155 struct usbd_pipe *pipe = xfer->ux_pipe;
1152 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 1156 struct ahci_softc *sc = AHCI_XFER2SC(xfer);
1153 int endpt, i, len, tlen, segs, offset, isread, toggle, short_ok; 1157 int endpt, i, len, tlen, segs, offset, isread, toggle, short_ok;
1154 struct ahci_pipe *apipe = (struct ahci_pipe *)xfer->ux_pipe; 1158 struct ahci_pipe *apipe = (struct ahci_pipe *)xfer->ux_pipe;
1155 1159
1156#define KSEG1ADDR(x) (0xa0000000 | (((uint32_t)x) & 0x1fffffff)) 1160#define KSEG1ADDR(x) (0xa0000000 | (((uint32_t)x) & 0x1fffffff))
1157 DPRINTF(D_TRACE, ("st ")); 1161 DPRINTF(D_TRACE, ("st "));
1158 1162
 1163 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock);
 1164
1159#ifdef DIAGNOSTIC 1165#ifdef DIAGNOSTIC
1160 if (xfer->ux_rqflags & URQ_REQUEST) { 1166 if (xfer->ux_rqflags & URQ_REQUEST) {
1161 /* XXX panic */ 1167 /* XXX panic */
1162 printf("ohci_device_bulk_start: a request\n"); 1168 printf("ohci_device_bulk_start: a request\n");
1163 return USBD_INVAL; 1169 return USBD_INVAL;
1164 } 1170 }
1165#endif 1171#endif
1166 1172
1167 mutex_enter(&sc->sc_lock); 
1168 level++; 1173 level++;
1169/* printf("bulk_start>>>\n"); */ 1174/* printf("bulk_start>>>\n"); */
1170 1175
1171 if (!ep) { 1176 if (!ep) {
1172 ep = (struct admhcd_ed *)KSEG1ADDR(&ep_v); 1177 ep = (struct admhcd_ed *)KSEG1ADDR(&ep_v);
1173 for (i=0; i<NBULK_TDS; i++) { 1178 for (i=0; i<NBULK_TDS; i++) {
1174 td[i] = (struct admhcd_td *)KSEG1ADDR(&td_v[i]); 1179 td[i] = (struct admhcd_td *)KSEG1ADDR(&td_v[i]);
1175 }; 1180 };
1176/* printf("ep: %p\n",ep);*/ 1181/* printf("ep: %p\n",ep);*/
1177 }; 1182 };
1178 if (apipe->toggle == 0) { 1183 if (apipe->toggle == 0) {
1179 toggle = ADMHCD_TD_DATA0; 1184 toggle = ADMHCD_TD_DATA0;
1180 } else { 1185 } else {
@@ -1281,27 +1286,26 @@ ahci_device_bulk_start(struct usbd_xfer  @@ -1281,27 +1286,26 @@ ahci_device_bulk_start(struct usbd_xfer
1281 status = USBD_NORMAL_COMPLETION; 1286 status = USBD_NORMAL_COMPLETION;
1282 }; 1287 };
1283 xfer->ux_actlen = len; 1288 xfer->ux_actlen = len;
1284 xfer->ux_status = status; 1289 xfer->ux_status = status;
1285 1290
1286 level--; 1291 level--;
1287/* printf("bulk_start<<<\n"); */ 1292/* printf("bulk_start<<<\n"); */
1288 1293
1289 if (xfer->ux_length) 1294 if (xfer->ux_length)
1290 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, 1295 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
1291 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1296 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1292 1297
1293 usb_transfer_complete(xfer); 1298 usb_transfer_complete(xfer);
1294 mutex_exit(&sc->sc_lock); 
1295 1299
1296 return USBD_NORMAL_COMPLETION; 1300 return USBD_NORMAL_COMPLETION;
1297} 1301}
1298 1302
1299static void 1303static void
1300ahci_device_bulk_abort(struct usbd_xfer *xfer) 1304ahci_device_bulk_abort(struct usbd_xfer *xfer)
1301{ 1305{
1302 DPRINTF(D_TRACE, ("Bab ")); 1306 DPRINTF(D_TRACE, ("Bab "));
1303 usbd_xfer_abort(xfer); 1307 usbd_xfer_abort(xfer);
1304} 1308}
1305 1309
1306static void 1310static void
1307ahci_device_bulk_close(struct usbd_pipe *pipe) 1311ahci_device_bulk_close(struct usbd_pipe *pipe)

cvs diff -r1.109 -r1.110 src/sys/dev/ic/sl811hs.c (expand / switch to unified diff)

--- src/sys/dev/ic/sl811hs.c 2022/03/03 06:04:31 1.109
+++ src/sys/dev/ic/sl811hs.c 2022/03/03 06:12:11 1.110
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sl811hs.c,v 1.109 2022/03/03 06:04:31 riastradh Exp $ */ 1/* $NetBSD: sl811hs.c,v 1.110 2022/03/03 06:12:11 riastradh Exp $ */
2 2
3/* 3/*
4 * Not (c) 2007 Matthew Orgass 4 * Not (c) 2007 Matthew Orgass
5 * This file is public domain, meaning anyone can make any use of part or all 5 * This file is public domain, meaning anyone can make any use of part or all
6 * of this file including copying into other works without credit. Any use, 6 * of this file including copying into other works without credit. Any use,
7 * modified or not, is solely the responsibility of the user. If this file is 7 * modified or not, is solely the responsibility of the user. If this file is
8 * part of a collection then use in the collection is governed by the terms of 8 * part of a collection then use in the collection is governed by the terms of
9 * the collection. 9 * the collection.
10 */ 10 */
11 11
12/* 12/*
13 * Cypress/ScanLogic SL811HS/T USB Host Controller 13 * Cypress/ScanLogic SL811HS/T USB Host Controller
14 * Datasheet, Errata, and App Note available at www.cypress.com 14 * Datasheet, Errata, and App Note available at www.cypress.com
@@ -58,27 +58,27 @@ @@ -58,27 +58,27 @@
58 */ 58 */
59 59
60/* 60/*
61 * XXX TODO: 61 * XXX TODO:
62 * copy next output packet while transfering 62 * copy next output packet while transfering
63 * usb suspend 63 * usb suspend
64 * could keep track of known values of all buffer space? 64 * could keep track of known values of all buffer space?
65 * combined print/log function for errors 65 * combined print/log function for errors
66 * 66 *
67 * ub_usepolling support is untested and may not work 67 * ub_usepolling support is untested and may not work
68 */ 68 */
69 69
70#include <sys/cdefs.h> 70#include <sys/cdefs.h>
71__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.109 2022/03/03 06:04:31 riastradh Exp $"); 71__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.110 2022/03/03 06:12:11 riastradh Exp $");
72 72
73#ifdef _KERNEL_OPT 73#ifdef _KERNEL_OPT
74#include "opt_slhci.h" 74#include "opt_slhci.h"
75#include "opt_usb.h" 75#include "opt_usb.h"
76#endif 76#endif
77 77
78#include <sys/param.h> 78#include <sys/param.h>
79 79
80#include <sys/bus.h> 80#include <sys/bus.h>
81#include <sys/cpu.h> 81#include <sys/cpu.h>
82#include <sys/device.h> 82#include <sys/device.h>
83#include <sys/gcq.h> 83#include <sys/gcq.h>
84#include <sys/intr.h> 84#include <sys/intr.h>
@@ -836,48 +836,44 @@ slhci_get_lock(struct usbd_bus *bus, kmu @@ -836,48 +836,44 @@ slhci_get_lock(struct usbd_bus *bus, kmu
836} 836}
837 837
838usbd_status 838usbd_status
839slhci_transfer(struct usbd_xfer *xfer) 839slhci_transfer(struct usbd_xfer *xfer)
840{ 840{
841 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 841 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
842 usbd_status error; 842 usbd_status error;
843 843
844 DLOG(D_TRACE, "transfer type %jd xfer %#jx spipe %#jx ", 844 DLOG(D_TRACE, "transfer type %jd xfer %#jx spipe %#jx ",
845 SLHCI_XFER_TYPE(xfer), (uintptr_t)xfer, (uintptr_t)xfer->ux_pipe, 845 SLHCI_XFER_TYPE(xfer), (uintptr_t)xfer, (uintptr_t)xfer->ux_pipe,
846 0); 846 0);
847 847
848 /* Pipe isn't running, so start it first. */ 848 /* Pipe isn't running, so start it first. */
849 
850 /* 
851 * Start will take the lock. 
852 */ 
853 error = xfer->ux_pipe->up_methods->upm_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 849 error = xfer->ux_pipe->up_methods->upm_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
854 850
855 return error; 851 return error;
856} 852}
857 853
858/* It is not safe for start to return anything other than USBD_INPROG. */ 854/* It is not safe for start to return anything other than USBD_INPROG. */
859usbd_status 855usbd_status
860slhci_start(struct usbd_xfer *xfer) 856slhci_start(struct usbd_xfer *xfer)
861{ 857{
862 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 858 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
863 struct slhci_softc *sc = SLHCI_XFER2SC(xfer); 859 struct slhci_softc *sc = SLHCI_XFER2SC(xfer);
864 struct usbd_pipe *pipe = xfer->ux_pipe; 860 struct usbd_pipe *pipe = xfer->ux_pipe;
865 struct slhci_pipe *spipe = SLHCI_PIPE2SPIPE(pipe); 861 struct slhci_pipe *spipe = SLHCI_PIPE2SPIPE(pipe);
866 struct slhci_transfers *t = &sc->sc_transfers; 862 struct slhci_transfers *t = &sc->sc_transfers;
867 usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; 863 usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
868 unsigned int max_packet; 864 unsigned int max_packet;
869 865
870 mutex_enter(&sc->sc_lock); 866 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
871 867
872 max_packet = UGETW(ed->wMaxPacketSize); 868 max_packet = UGETW(ed->wMaxPacketSize);
873 869
874 DLOG(D_TRACE, "transfer type %jd start xfer %#jx spipe %#jx length %jd", 870 DLOG(D_TRACE, "transfer type %jd start xfer %#jx spipe %#jx length %jd",
875 spipe->ptype, (uintptr_t)xfer, (uintptr_t)spipe, xfer->ux_length); 871 spipe->ptype, (uintptr_t)xfer, (uintptr_t)spipe, xfer->ux_length);
876 872
877 /* root transfers use slhci_root_start */ 873 /* root transfers use slhci_root_start */
878 874
879 KASSERT(spipe->xfer == NULL); /* not SLASSERT */ 875 KASSERT(spipe->xfer == NULL); /* not SLASSERT */
880 876
881 xfer->ux_actlen = 0; 877 xfer->ux_actlen = 0;
882 xfer->ux_status = USBD_IN_PROGRESS; 878 xfer->ux_status = USBD_IN_PROGRESS;
883 879
@@ -979,56 +975,54 @@ slhci_start(struct usbd_xfer *xfer) @@ -979,56 +975,54 @@ slhci_start(struct usbd_xfer *xfer)
979 xfer->ux_status = USBD_INVAL; 975 xfer->ux_status = USBD_INVAL;
980 } 976 }
981 977
982 /* 978 /*
983 * The datasheet incorrectly indicates that DIRECTION is for 979 * The datasheet incorrectly indicates that DIRECTION is for
984 * "transmit to host". It is for OUT and SETUP. The app note 980 * "transmit to host". It is for OUT and SETUP. The app note
985 * describes its use correctly. 981 * describes its use correctly.
986 */ 982 */
987 if ((spipe->tregs[PID] & SL11_PID_BITS) != SL11_PID_IN) 983 if ((spipe->tregs[PID] & SL11_PID_BITS) != SL11_PID_IN)
988 spipe->control |= SL11_EPCTRL_DIRECTION; 984 spipe->control |= SL11_EPCTRL_DIRECTION;
989 985
990 slhci_start_entry(sc, spipe); 986 slhci_start_entry(sc, spipe);
991 987
992 mutex_exit(&sc->sc_lock); 
993 
994 return USBD_IN_PROGRESS; 988 return USBD_IN_PROGRESS;
995} 989}
996 990
997usbd_status 991usbd_status
998slhci_root_start(struct usbd_xfer *xfer) 992slhci_root_start(struct usbd_xfer *xfer)
999{ 993{
1000 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 994 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
1001 struct slhci_softc *sc; 995 struct slhci_softc *sc;
1002 struct slhci_pipe *spipe __diagused; 996 struct slhci_pipe *spipe __diagused;
1003 997
1004 spipe = SLHCI_PIPE2SPIPE(xfer->ux_pipe); 998 spipe = SLHCI_PIPE2SPIPE(xfer->ux_pipe);
1005 sc = SLHCI_XFER2SC(xfer); 999 sc = SLHCI_XFER2SC(xfer);
1006 1000
1007 struct slhci_transfers *t = &sc->sc_transfers; 1001 struct slhci_transfers *t = &sc->sc_transfers;
1008 1002
1009 LK_SLASSERT(spipe != NULL && xfer != NULL, sc, spipe, xfer, return 1003 LK_SLASSERT(spipe != NULL && xfer != NULL, sc, spipe, xfer, return
1010 USBD_CANCELLED); 1004 USBD_CANCELLED);
1011 1005
1012 DLOG(D_TRACE, "transfer type %jd start", 1006 DLOG(D_TRACE, "transfer type %jd start",
1013 SLHCI_XFER_TYPE(xfer), 0, 0, 0); 1007 SLHCI_XFER_TYPE(xfer), 0, 0, 0);
1014 1008
 1009 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 1010
1015 KASSERT(spipe->ptype == PT_ROOT_INTR); 1011 KASSERT(spipe->ptype == PT_ROOT_INTR);
1016 1012
1017 mutex_enter(&sc->sc_intr_lock); 
1018 KASSERT(t->rootintr == NULL); 1013 KASSERT(t->rootintr == NULL);
1019 t->rootintr = xfer; 1014 t->rootintr = xfer;
1020 xfer->ux_status = USBD_IN_PROGRESS; 1015 xfer->ux_status = USBD_IN_PROGRESS;
1021 mutex_exit(&sc->sc_intr_lock); 
1022 1016
1023 return USBD_IN_PROGRESS; 1017 return USBD_IN_PROGRESS;
1024} 1018}
1025 1019
1026usbd_status 1020usbd_status
1027slhci_open(struct usbd_pipe *pipe) 1021slhci_open(struct usbd_pipe *pipe)
1028{ 1022{
1029 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 1023 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
1030 struct usbd_device *dev; 1024 struct usbd_device *dev;
1031 struct slhci_softc *sc; 1025 struct slhci_softc *sc;
1032 struct slhci_pipe *spipe; 1026 struct slhci_pipe *spipe;
1033 usb_endpoint_descriptor_t *ed; 1027 usb_endpoint_descriptor_t *ed;
1034 unsigned int max_packet, pmaxpkt; 1028 unsigned int max_packet, pmaxpkt;
@@ -3191,26 +3185,28 @@ slhci_get_status(struct slhci_softc *sc, @@ -3191,26 +3185,28 @@ slhci_get_status(struct slhci_softc *sc,
3191 3185
3192static int 3186static int
3193slhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 3187slhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
3194 void *buf, int buflen) 3188 void *buf, int buflen)
3195{ 3189{
3196 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 3190 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
3197 struct slhci_softc *sc = SLHCI_BUS2SC(bus); 3191 struct slhci_softc *sc = SLHCI_BUS2SC(bus);
3198 struct slhci_transfers *t = &sc->sc_transfers; 3192 struct slhci_transfers *t = &sc->sc_transfers;
3199 usbd_status error = USBD_IOERROR; /* XXX should be STALL */ 3193 usbd_status error = USBD_IOERROR; /* XXX should be STALL */
3200 uint16_t len, value, index; 3194 uint16_t len, value, index;
3201 uint8_t type; 3195 uint8_t type;
3202 int actlen = 0; 3196 int actlen = 0;
3203 3197
 3198 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
 3199
3204 len = UGETW(req->wLength); 3200 len = UGETW(req->wLength);
3205 value = UGETW(req->wValue); 3201 value = UGETW(req->wValue);
3206 index = UGETW(req->wIndex); 3202 index = UGETW(req->wIndex);
3207 3203
3208 type = req->bmRequestType; 3204 type = req->bmRequestType;
3209 3205
3210 SLHCI_DEXEC(D_TRACE, slhci_log_req(req)); 3206 SLHCI_DEXEC(D_TRACE, slhci_log_req(req));
3211 3207
3212 /* 3208 /*
3213 * USB requests for hubs have two basic types, standard and class. 3209 * USB requests for hubs have two basic types, standard and class.
3214 * Each could potentially have recipients of device, interface, 3210 * Each could potentially have recipients of device, interface,
3215 * endpoint, or other. For the hub class, CLASS_OTHER means the port 3211 * endpoint, or other. For the hub class, CLASS_OTHER means the port
3216 * and CLASS_DEVICE means the hub. For standard requests, OTHER 3212 * and CLASS_DEVICE means the hub. For standard requests, OTHER

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

--- src/sys/dev/usb/ehci.c 2022/03/03 06:08:50 1.304
+++ src/sys/dev/usb/ehci.c 2022/03/03 06:12:11 1.305
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ehci.c,v 1.304 2022/03/03 06:08:50 riastradh Exp $ */ 1/* $NetBSD: ehci.c,v 1.305 2022/03/03 06:12:11 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2004-2012,2016,2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 2004-2012,2016,2020 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). Matthew R. Green (mrg@eterna.com.au), and 10 * (jmcneill@invisible.ca). Matthew R. Green (mrg@eterna.com.au), and
11 * Nick Hudson . 11 * Nick Hudson .
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions 14 * modification, are permitted provided that the following conditions
@@ -44,27 +44,27 @@ @@ -44,27 +44,27 @@
44 44
45/* 45/*
46 * TODO: 46 * TODO:
47 * 1) hold off explorations by companion controllers until ehci has started. 47 * 1) hold off explorations by companion controllers until ehci has started.
48 * 48 *
49 * 2) The hub driver needs to handle and schedule the transaction translator, 49 * 2) The hub driver needs to handle and schedule the transaction translator,
50 * to assign place in frame where different devices get to go. See chapter 50 * to assign place in frame where different devices get to go. See chapter
51 * on hubs in USB 2.0 for details. 51 * on hubs in USB 2.0 for details.
52 * 52 *
53 * 3) Command failures are not recovered correctly. 53 * 3) Command failures are not recovered correctly.
54 */ 54 */
55 55
56#include <sys/cdefs.h> 56#include <sys/cdefs.h>
57__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.304 2022/03/03 06:08:50 riastradh Exp $"); 57__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.305 2022/03/03 06:12:11 riastradh Exp $");
58 58
59#include "ohci.h" 59#include "ohci.h"
60#include "uhci.h" 60#include "uhci.h"
61 61
62#ifdef _KERNEL_OPT 62#ifdef _KERNEL_OPT
63#include "opt_usb.h" 63#include "opt_usb.h"
64#endif 64#endif
65 65
66#include <sys/param.h> 66#include <sys/param.h>
67 67
68#include <sys/bus.h> 68#include <sys/bus.h>
69#include <sys/cpu.h> 69#include <sys/cpu.h>
70#include <sys/device.h> 70#include <sys/device.h>
@@ -2359,26 +2359,28 @@ Static int @@ -2359,26 +2359,28 @@ Static int
2359ehci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 2359ehci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
2360 void *buf, int buflen) 2360 void *buf, int buflen)
2361{ 2361{
2362 ehci_softc_t *sc = EHCI_BUS2SC(bus); 2362 ehci_softc_t *sc = EHCI_BUS2SC(bus);
2363 usb_hub_descriptor_t hubd; 2363 usb_hub_descriptor_t hubd;
2364 usb_port_status_t ps; 2364 usb_port_status_t ps;
2365 uint16_t len, value, index; 2365 uint16_t len, value, index;
2366 int l, totlen = 0; 2366 int l, totlen = 0;
2367 int port, i; 2367 int port, i;
2368 uint32_t v; 2368 uint32_t v;
2369 2369
2370 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 2370 EHCIHIST_FUNC(); EHCIHIST_CALLED();
2371 2371
 2372 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
 2373
2372 if (sc->sc_dying) 2374 if (sc->sc_dying)
2373 return -1; 2375 return -1;
2374 2376
2375 DPRINTF("type=0x%02jx request=%02jx", req->bmRequestType, req->bRequest, 2377 DPRINTF("type=0x%02jx request=%02jx", req->bmRequestType, req->bRequest,
2376 0, 0); 2378 0, 0);
2377 2379
2378 len = UGETW(req->wLength); 2380 len = UGETW(req->wLength);
2379 value = UGETW(req->wValue); 2381 value = UGETW(req->wValue);
2380 index = UGETW(req->wIndex); 2382 index = UGETW(req->wIndex);
2381 2383
2382#define C(x,y) ((x) | ((y) << 8)) 2384#define C(x,y) ((x) | ((y) << 8))
2383 switch (C(req->bRequest, req->bmRequestType)) { 2385 switch (C(req->bRequest, req->bmRequestType)) {
2384 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 2386 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
@@ -2747,38 +2749,35 @@ ehci_disown(ehci_softc_t *sc, int index, @@ -2747,38 +2749,35 @@ ehci_disown(ehci_softc_t *sc, int index,
2747 2749
2748Static usbd_status 2750Static usbd_status
2749ehci_root_intr_transfer(struct usbd_xfer *xfer) 2751ehci_root_intr_transfer(struct usbd_xfer *xfer)
2750{ 2752{
2751 2753
2752 /* Pipe isn't running, start first */ 2754 /* Pipe isn't running, start first */
2753 return ehci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 2755 return ehci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
2754} 2756}
2755 2757
2756Static usbd_status 2758Static usbd_status
2757ehci_root_intr_start(struct usbd_xfer *xfer) 2759ehci_root_intr_start(struct usbd_xfer *xfer)
2758{ 2760{
2759 ehci_softc_t *sc = EHCI_XFER2SC(xfer); 2761 ehci_softc_t *sc = EHCI_XFER2SC(xfer);
2760 const bool polling = sc->sc_bus.ub_usepolling; 2762
 2763 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
2761 2764
2762 if (sc->sc_dying) 2765 if (sc->sc_dying)
2763 return USBD_IOERROR; 2766 return USBD_IOERROR;
2764 2767
2765 if (!polling) 
2766 mutex_enter(&sc->sc_lock); 
2767 KASSERT(sc->sc_intrxfer == NULL); 2768 KASSERT(sc->sc_intrxfer == NULL);
2768 sc->sc_intrxfer = xfer; 2769 sc->sc_intrxfer = xfer;
2769 xfer->ux_status = USBD_IN_PROGRESS; 2770 xfer->ux_status = USBD_IN_PROGRESS;
2770 if (!polling) 
2771 mutex_exit(&sc->sc_lock); 
2772 2771
2773 return USBD_IN_PROGRESS; 2772 return USBD_IN_PROGRESS;
2774} 2773}
2775 2774
2776/* Abort a root interrupt request. */ 2775/* Abort a root interrupt request. */
2777Static void 2776Static void
2778ehci_root_intr_abort(struct usbd_xfer *xfer) 2777ehci_root_intr_abort(struct usbd_xfer *xfer)
2779{ 2778{
2780 ehci_softc_t *sc = EHCI_XFER2SC(xfer); 2779 ehci_softc_t *sc = EHCI_XFER2SC(xfer);
2781 2780
2782 KASSERT(mutex_owned(&sc->sc_lock)); 2781 KASSERT(mutex_owned(&sc->sc_lock));
2783 KASSERT(xfer->ux_pipe->up_intrxfer == xfer); 2782 KASSERT(xfer->ux_pipe->up_intrxfer == xfer);
2784 2783
@@ -3597,30 +3596,30 @@ ehci_device_ctrl_transfer(struct usbd_xf @@ -3597,30 +3596,30 @@ ehci_device_ctrl_transfer(struct usbd_xf
3597 /* Pipe isn't running, start first */ 3596 /* Pipe isn't running, start first */
3598 return ehci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 3597 return ehci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
3599} 3598}
3600 3599
3601Static usbd_status 3600Static usbd_status
3602ehci_device_ctrl_start(struct usbd_xfer *xfer) 3601ehci_device_ctrl_start(struct usbd_xfer *xfer)
3603{ 3602{
3604 struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); 3603 struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer);
3605 struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); 3604 struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer);
3606 usb_device_request_t *req = &xfer->ux_request; 3605 usb_device_request_t *req = &xfer->ux_request;
3607 ehci_softc_t *sc = EHCI_XFER2SC(xfer); 3606 ehci_softc_t *sc = EHCI_XFER2SC(xfer);
3608 ehci_soft_qtd_t *setup, *status, *next; 3607 ehci_soft_qtd_t *setup, *status, *next;
3609 ehci_soft_qh_t *sqh; 3608 ehci_soft_qh_t *sqh;
3610 const bool polling = sc->sc_bus.ub_usepolling; 
3611 3609
3612 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 3610 EHCIHIST_FUNC(); EHCIHIST_CALLED();
3613 3611
 3612 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
3614 KASSERT(xfer->ux_rqflags & URQ_REQUEST); 3613 KASSERT(xfer->ux_rqflags & URQ_REQUEST);
3615 3614
3616 if (sc->sc_dying) 3615 if (sc->sc_dying)
3617 return USBD_IOERROR; 3616 return USBD_IOERROR;
3618 3617
3619 const int isread = req->bmRequestType & UT_READ; 3618 const int isread = req->bmRequestType & UT_READ;
3620 const int len = UGETW(req->wLength); 3619 const int len = UGETW(req->wLength);
3621 3620
3622 DPRINTF("type=0x%02jx, request=0x%02jx, wValue=0x%04jx, wIndex=0x%04jx", 3621 DPRINTF("type=0x%02jx, request=0x%02jx, wValue=0x%04jx, wIndex=0x%04jx",
3623 req->bmRequestType, req->bRequest, UGETW(req->wValue), 3622 req->bmRequestType, req->bRequest, UGETW(req->wValue),
3624 UGETW(req->wIndex)); 3623 UGETW(req->wIndex));
3625 DPRINTF("len=%jd, addr=%jd, endpt=%jd", 3624 DPRINTF("len=%jd, addr=%jd, endpt=%jd",
3626 len, epipe->pipe.up_dev->ud_addr, 3625 len, epipe->pipe.up_dev->ud_addr,
@@ -3719,36 +3718,31 @@ ehci_device_ctrl_start(struct usbd_xfer  @@ -3719,36 +3718,31 @@ ehci_device_ctrl_start(struct usbd_xfer
3719 3718
3720 usb_syncmem(&status->dma, status->offs, sizeof(status->qtd), 3719 usb_syncmem(&status->dma, status->offs, sizeof(status->qtd),
3721 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3720 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3722 3721
3723 KASSERT(status->qtd.qtd_status & htole32(EHCI_QTD_TOGGLE_MASK)); 3722 KASSERT(status->qtd.qtd_status & htole32(EHCI_QTD_TOGGLE_MASK));
3724 3723
3725#ifdef EHCI_DEBUG 3724#ifdef EHCI_DEBUG
3726 DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); 3725 DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0);
3727 ehci_dump_sqh(sqh); 3726 ehci_dump_sqh(sqh);
3728 ehci_dump_sqtds(setup); 3727 ehci_dump_sqtds(setup);
3729 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); 3728 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0);
3730#endif 3729#endif
3731 3730
3732 if (!polling) 
3733 mutex_enter(&sc->sc_lock); 
3734 
3735 /* Insert qTD in QH list - also does usb_syncmem(sqh) */ 3731 /* Insert qTD in QH list - also does usb_syncmem(sqh) */
3736 ehci_set_qh_qtd(sqh, setup); 3732 ehci_set_qh_qtd(sqh, setup);
3737 usbd_xfer_schedule_timeout(xfer); 3733 usbd_xfer_schedule_timeout(xfer);
3738 ehci_add_intr_list(sc, exfer); 3734 ehci_add_intr_list(sc, exfer);
3739 xfer->ux_status = USBD_IN_PROGRESS; 3735 xfer->ux_status = USBD_IN_PROGRESS;
3740 if (!polling) 
3741 mutex_exit(&sc->sc_lock); 
3742 3736
3743#if 0 3737#if 0
3744#ifdef EHCI_DEBUG 3738#ifdef EHCI_DEBUG
3745 DPRINTFN(10, "status=%jx, dump:", EOREAD4(sc, EHCI_USBSTS), 0, 0, 0); 3739 DPRINTFN(10, "status=%jx, dump:", EOREAD4(sc, EHCI_USBSTS), 0, 0, 0);
3746// delay(10000); 3740// delay(10000);
3747 ehci_dump_regs(sc); 3741 ehci_dump_regs(sc);
3748 ehci_dump_sqh(sc->sc_async_head); 3742 ehci_dump_sqh(sc->sc_async_head);
3749 ehci_dump_sqh(sqh); 3743 ehci_dump_sqh(sqh);
3750 ehci_dump_sqtds(setup); 3744 ehci_dump_sqtds(setup);
3751#endif 3745#endif
3752#endif 3746#endif
3753 3747
3754 return USBD_IN_PROGRESS; 3748 return USBD_IN_PROGRESS;
@@ -3868,78 +3862,73 @@ ehci_device_bulk_transfer(struct usbd_xf @@ -3868,78 +3862,73 @@ ehci_device_bulk_transfer(struct usbd_xf
3868 /* Pipe isn't running, start first */ 3862 /* Pipe isn't running, start first */
3869 return ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 3863 return ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
3870} 3864}
3871 3865
3872Static usbd_status 3866Static usbd_status
3873ehci_device_bulk_start(struct usbd_xfer *xfer) 3867ehci_device_bulk_start(struct usbd_xfer *xfer)
3874{ 3868{
3875 struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); 3869 struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer);
3876 struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); 3870 struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer);
3877 ehci_softc_t *sc = EHCI_XFER2SC(xfer); 3871 ehci_softc_t *sc = EHCI_XFER2SC(xfer);
3878 ehci_soft_qh_t *sqh; 3872 ehci_soft_qh_t *sqh;
3879 ehci_soft_qtd_t *end; 3873 ehci_soft_qtd_t *end;
3880 int len, isread, endpt; 3874 int len, isread, endpt;
3881 const bool polling = sc->sc_bus.ub_usepolling; 
3882 3875
3883 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 3876 EHCIHIST_FUNC(); EHCIHIST_CALLED();
3884 3877
3885 DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length, 3878 DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length,
3886 xfer->ux_flags, 0); 3879 xfer->ux_flags, 0);
3887 3880
 3881 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 3882
3888 if (sc->sc_dying) 3883 if (sc->sc_dying)
3889 return USBD_IOERROR; 3884 return USBD_IOERROR;
3890 3885
3891 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 3886 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
3892 KASSERT(xfer->ux_length <= xfer->ux_bufsize); 3887 KASSERT(xfer->ux_length <= xfer->ux_bufsize);
3893 3888
3894 len = xfer->ux_length; 3889 len = xfer->ux_length;
3895 endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; 3890 endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
3896 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 3891 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3897 sqh = epipe->sqh; 3892 sqh = epipe->sqh;
3898 3893
3899 KASSERT(exfer->ex_isdone); 3894 KASSERT(exfer->ex_isdone);
3900#ifdef DIAGNOSTIC 3895#ifdef DIAGNOSTIC
3901 exfer->ex_isdone = false; 3896 exfer->ex_isdone = false;
3902#endif 3897#endif
3903 3898
3904 /* Take lock here to protect nexttoggle */ 
3905 if (!polling) 
3906 mutex_enter(&sc->sc_lock); 
3907 
3908 ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); 3899 ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end);
3909 3900
3910 exfer->ex_sqtdend = end; 3901 exfer->ex_sqtdend = end;
3911 end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); 3902 end->qtd.qtd_status |= htole32(EHCI_QTD_IOC);
3912 usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), 3903 usb_syncmem(&end->dma, end->offs, sizeof(end->qtd),
3913 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3904 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3914 3905
3915#ifdef EHCI_DEBUG 3906#ifdef EHCI_DEBUG
3916 DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); 3907 DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0);
3917 ehci_dump_sqh(sqh); 3908 ehci_dump_sqh(sqh);
3918 ehci_dump_sqtds(exfer->ex_sqtdstart); 3909 ehci_dump_sqtds(exfer->ex_sqtdstart);
3919 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); 3910 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0);
3920#endif 3911#endif
3921 3912
3922 if (xfer->ux_length) 3913 if (xfer->ux_length)
3923 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, 3914 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
3924 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 3915 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
3925 3916
3926 /* also does usb_syncmem(sqh) */ 3917 /* also does usb_syncmem(sqh) */
3927 ehci_set_qh_qtd(sqh, exfer->ex_sqtdstart); 3918 ehci_set_qh_qtd(sqh, exfer->ex_sqtdstart);
3928 usbd_xfer_schedule_timeout(xfer); 3919 usbd_xfer_schedule_timeout(xfer);
3929 ehci_add_intr_list(sc, exfer); 3920 ehci_add_intr_list(sc, exfer);
3930 xfer->ux_status = USBD_IN_PROGRESS; 3921 xfer->ux_status = USBD_IN_PROGRESS;
3931 if (!polling) 
3932 mutex_exit(&sc->sc_lock); 
3933 3922
3934#if 0 3923#if 0
3935#ifdef EHCI_DEBUG 3924#ifdef EHCI_DEBUG
3936 DPRINTFN(5, "data(2)", 0, 0, 0, 0); 3925 DPRINTFN(5, "data(2)", 0, 0, 0, 0);
3937// delay(10000); 3926// delay(10000);
3938 DPRINTFN(5, "data(3)", 0, 0, 0, 0); 3927 DPRINTFN(5, "data(3)", 0, 0, 0, 0);
3939 ehci_dump_regs(sc); 3928 ehci_dump_regs(sc);
3940#if 0 3929#if 0
3941 printf("async_head:\n"); 3930 printf("async_head:\n");
3942 ehci_dump_sqh(sc->sc_async_head); 3931 ehci_dump_sqh(sc->sc_async_head);
3943#endif 3932#endif
3944 DPRINTF("sqh:", 0, 0, 0, 0); 3933 DPRINTF("sqh:", 0, 0, 0, 0);
3945 ehci_dump_sqh(sqh); 3934 ehci_dump_sqh(sqh);
@@ -4072,78 +4061,73 @@ ehci_device_intr_transfer(struct usbd_xf @@ -4072,78 +4061,73 @@ ehci_device_intr_transfer(struct usbd_xf
4072 /* Pipe isn't running, so start it first. */ 4061 /* Pipe isn't running, so start it first. */
4073 return ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 4062 return ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
4074} 4063}
4075 4064
4076Static usbd_status 4065Static usbd_status
4077ehci_device_intr_start(struct usbd_xfer *xfer) 4066ehci_device_intr_start(struct usbd_xfer *xfer)
4078{ 4067{
4079 struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); 4068 struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer);
4080 struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); 4069 struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer);
4081 ehci_softc_t *sc = EHCI_XFER2SC(xfer); 4070 ehci_softc_t *sc = EHCI_XFER2SC(xfer);
4082 ehci_soft_qtd_t *end; 4071 ehci_soft_qtd_t *end;
4083 ehci_soft_qh_t *sqh; 4072 ehci_soft_qh_t *sqh;
4084 int len, isread, endpt; 4073 int len, isread, endpt;
4085 const bool polling = sc->sc_bus.ub_usepolling; 
4086 4074
4087 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 4075 EHCIHIST_FUNC(); EHCIHIST_CALLED();
4088 4076
4089 DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length, 4077 DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length,
4090 xfer->ux_flags, 0); 4078 xfer->ux_flags, 0);
4091 4079
 4080 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 4081
4092 if (sc->sc_dying) 4082 if (sc->sc_dying)
4093 return USBD_IOERROR; 4083 return USBD_IOERROR;
4094 4084
4095 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 4085 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
4096 KASSERT(xfer->ux_length <= xfer->ux_bufsize); 4086 KASSERT(xfer->ux_length <= xfer->ux_bufsize);
4097 4087
4098 len = xfer->ux_length; 4088 len = xfer->ux_length;
4099 endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; 4089 endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
4100 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 4090 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
4101 sqh = epipe->sqh; 4091 sqh = epipe->sqh;
4102 4092
4103 KASSERT(exfer->ex_isdone); 4093 KASSERT(exfer->ex_isdone);
4104#ifdef DIAGNOSTIC 4094#ifdef DIAGNOSTIC
4105 exfer->ex_isdone = false; 4095 exfer->ex_isdone = false;
4106#endif 4096#endif
4107 4097
4108 /* Take lock to protect nexttoggle */ 
4109 if (!polling) 
4110 mutex_enter(&sc->sc_lock); 
4111 
4112 ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); 4098 ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end);
4113 4099
4114 end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); 4100 end->qtd.qtd_status |= htole32(EHCI_QTD_IOC);
4115 usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), 4101 usb_syncmem(&end->dma, end->offs, sizeof(end->qtd),
4116 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 4102 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
4117 exfer->ex_sqtdend = end; 4103 exfer->ex_sqtdend = end;
4118 4104
4119#ifdef EHCI_DEBUG 4105#ifdef EHCI_DEBUG
4120 DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); 4106 DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0);
4121 ehci_dump_sqh(sqh); 4107 ehci_dump_sqh(sqh);
4122 ehci_dump_sqtds(exfer->ex_sqtdstart); 4108 ehci_dump_sqtds(exfer->ex_sqtdstart);
4123 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); 4109 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0);
4124#endif 4110#endif
4125 4111
4126 if (xfer->ux_length) 4112 if (xfer->ux_length)
4127 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, 4113 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
4128 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 4114 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
4129 4115
4130 /* also does usb_syncmem(sqh) */ 4116 /* also does usb_syncmem(sqh) */
4131 ehci_set_qh_qtd(sqh, exfer->ex_sqtdstart); 4117 ehci_set_qh_qtd(sqh, exfer->ex_sqtdstart);
4132 usbd_xfer_schedule_timeout(xfer); 4118 usbd_xfer_schedule_timeout(xfer);
4133 ehci_add_intr_list(sc, exfer); 4119 ehci_add_intr_list(sc, exfer);
4134 xfer->ux_status = USBD_IN_PROGRESS; 4120 xfer->ux_status = USBD_IN_PROGRESS;
4135 if (!polling) 
4136 mutex_exit(&sc->sc_lock); 
4137 4121
4138#if 0 4122#if 0
4139#ifdef EHCI_DEBUG 4123#ifdef EHCI_DEBUG
4140 DPRINTFN(5, "data(2)", 0, 0, 0, 0); 4124 DPRINTFN(5, "data(2)", 0, 0, 0, 0);
4141// delay(10000); 4125// delay(10000);
4142 DPRINTFN(5, "data(3)", 0, 0, 0, 0); 4126 DPRINTFN(5, "data(3)", 0, 0, 0, 0);
4143 ehci_dump_regs(sc); 4127 ehci_dump_regs(sc);
4144 DPRINTFN(5, "sqh:", 0, 0, 0, 0); 4128 DPRINTFN(5, "sqh:", 0, 0, 0, 0);
4145 ehci_dump_sqh(sqh); 4129 ehci_dump_sqh(sqh);
4146 ehci_dump_sqtds(exfer->ex_sqtdstart); 4130 ehci_dump_sqtds(exfer->ex_sqtdstart);
4147#endif 4131#endif
4148#endif 4132#endif
4149 4133
@@ -4315,26 +4299,28 @@ ehci_device_fs_isoc_transfer(struct usbd @@ -4315,26 +4299,28 @@ ehci_device_fs_isoc_transfer(struct usbd
4315 usb_dma_t *dma_buf; 4299 usb_dma_t *dma_buf;
4316 int i, j, k, frames; 4300 int i, j, k, frames;
4317 int offs; 4301 int offs;
4318 int frindex; 4302 int frindex;
4319 u_int dir; 4303 u_int dir;
4320 4304
4321 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 4305 EHCIHIST_FUNC(); EHCIHIST_CALLED();
4322 4306
4323 sitd = NULL; 4307 sitd = NULL;
4324 4308
4325 DPRINTF("xfer %#jx len %jd flags %jd", (uintptr_t)xfer, xfer->ux_length, 4309 DPRINTF("xfer %#jx len %jd flags %jd", (uintptr_t)xfer, xfer->ux_length,
4326 xfer->ux_flags, 0); 4310 xfer->ux_flags, 0);
4327 4311
 4312 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 4313
4328 if (sc->sc_dying) 4314 if (sc->sc_dying)
4329 return USBD_IOERROR; 4315 return USBD_IOERROR;
4330 4316
4331 /* 4317 /*
4332 * To avoid complication, don't allow a request right now that'll span 4318 * To avoid complication, don't allow a request right now that'll span
4333 * the entire frame table. To within 4 frames, to allow some leeway 4319 * the entire frame table. To within 4 frames, to allow some leeway
4334 * on either side of where the hc currently is. 4320 * on either side of where the hc currently is.
4335 */ 4321 */
4336 if (epipe->pipe.up_endpoint->ue_edesc->bInterval * 4322 if (epipe->pipe.up_endpoint->ue_edesc->bInterval *
4337 xfer->ux_nframes >= sc->sc_flsize - 4) { 4323 xfer->ux_nframes >= sc->sc_flsize - 4) {
4338 printf("ehci: isoc descriptor requested that spans the entire" 4324 printf("ehci: isoc descriptor requested that spans the entire"
4339 "frametable, too many frames\n"); 4325 "frametable, too many frames\n");
4340 return USBD_INVAL; 4326 return USBD_INVAL;
@@ -4448,28 +4434,26 @@ ehci_device_fs_isoc_transfer(struct usbd @@ -4448,28 +4434,26 @@ ehci_device_fs_isoc_transfer(struct usbd
4448 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 4434 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
4449 4435
4450 if (xfer->ux_length) 4436 if (xfer->ux_length)
4451 usb_syncmem(&exfer->ex_xfer.ux_dmabuf, 0, xfer->ux_length, 4437 usb_syncmem(&exfer->ex_xfer.ux_dmabuf, 0, xfer->ux_length,
4452 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 4438 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
4453 4439
4454 /* 4440 /*
4455 * Part 2: Transfer descriptors have now been set up, now they must 4441 * Part 2: Transfer descriptors have now been set up, now they must
4456 * be scheduled into the periodic frame list. Erk. Not wanting to 4442 * be scheduled into the periodic frame list. Erk. Not wanting to
4457 * complicate matters, transfer is denied if the transfer spans 4443 * complicate matters, transfer is denied if the transfer spans
4458 * more than the period frame list. 4444 * more than the period frame list.
4459 */ 4445 */
4460 4446
4461 mutex_enter(&sc->sc_lock); 
4462 
4463 /* Start inserting frames */ 4447 /* Start inserting frames */
4464 if (epipe->isoc.cur_xfers > 0) { 4448 if (epipe->isoc.cur_xfers > 0) {
4465 frindex = epipe->isoc.next_frame; 4449 frindex = epipe->isoc.next_frame;
4466 } else { 4450 } else {
4467 frindex = EOREAD4(sc, EHCI_FRINDEX); 4451 frindex = EOREAD4(sc, EHCI_FRINDEX);
4468 frindex = frindex >> 3; /* Erase microframe index */ 4452 frindex = frindex >> 3; /* Erase microframe index */
4469 frindex += 2; 4453 frindex += 2;
4470 } 4454 }
4471 4455
4472 if (frindex >= sc->sc_flsize) 4456 if (frindex >= sc->sc_flsize)
4473 frindex &= (sc->sc_flsize - 1); 4457 frindex &= (sc->sc_flsize - 1);
4474 4458
4475 /* Whats the frame interval? */ 4459 /* Whats the frame interval? */
@@ -4512,27 +4496,26 @@ ehci_device_fs_isoc_transfer(struct usbd @@ -4512,27 +4496,26 @@ ehci_device_fs_isoc_transfer(struct usbd
4512 sitd->slot = frindex; 4496 sitd->slot = frindex;
4513 sitd->frame_list.prev = NULL; 4497 sitd->frame_list.prev = NULL;
4514 4498
4515 frindex += i; 4499 frindex += i;
4516 if (frindex >= sc->sc_flsize) 4500 if (frindex >= sc->sc_flsize)
4517 frindex -= sc->sc_flsize; 4501 frindex -= sc->sc_flsize;
4518 } 4502 }
4519 4503
4520 epipe->isoc.cur_xfers++; 4504 epipe->isoc.cur_xfers++;
4521 epipe->isoc.next_frame = frindex; 4505 epipe->isoc.next_frame = frindex;
4522 4506
4523 ehci_add_intr_list(sc, exfer); 4507 ehci_add_intr_list(sc, exfer);
4524 xfer->ux_status = USBD_IN_PROGRESS; 4508 xfer->ux_status = USBD_IN_PROGRESS;
4525 mutex_exit(&sc->sc_lock); 
4526 4509
4527 return USBD_IN_PROGRESS; 4510 return USBD_IN_PROGRESS;
4528} 4511}
4529 4512
4530Static void 4513Static void
4531ehci_device_fs_isoc_abort(struct usbd_xfer *xfer) 4514ehci_device_fs_isoc_abort(struct usbd_xfer *xfer)
4532{ 4515{
4533 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 4516 EHCIHIST_FUNC(); EHCIHIST_CALLED();
4534 4517
4535 DPRINTF("xfer = %#jx", (uintptr_t)xfer, 0, 0, 0); 4518 DPRINTF("xfer = %#jx", (uintptr_t)xfer, 0, 0, 0);
4536 ehci_abort_isoc_xfer(xfer, USBD_CANCELLED); 4519 ehci_abort_isoc_xfer(xfer, USBD_CANCELLED);
4537} 4520}
4538 4521
@@ -4680,26 +4663,28 @@ ehci_device_isoc_transfer(struct usbd_xf @@ -4680,26 +4663,28 @@ ehci_device_isoc_transfer(struct usbd_xf
4680 int i, j; 4663 int i, j;
4681 int frames, uframes, ufrperframe; 4664 int frames, uframes, ufrperframe;
4682 int trans_count, offs; 4665 int trans_count, offs;
4683 int frindex; 4666 int frindex;
4684 4667
4685 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 4668 EHCIHIST_FUNC(); EHCIHIST_CALLED();
4686 4669
4687 prev = NULL; 4670 prev = NULL;
4688 itd = NULL; 4671 itd = NULL;
4689 trans_count = 0; 4672 trans_count = 0;
4690 4673
4691 DPRINTF("xfer %#jx flags %jd", (uintptr_t)xfer, xfer->ux_flags, 0, 0); 4674 DPRINTF("xfer %#jx flags %jd", (uintptr_t)xfer, xfer->ux_flags, 0, 0);
4692 4675
 4676 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 4677
4693 if (sc->sc_dying) 4678 if (sc->sc_dying)
4694 return USBD_IOERROR; 4679 return USBD_IOERROR;
4695 4680
4696 /* 4681 /*
4697 * To avoid complication, don't allow a request right now that'll span 4682 * To avoid complication, don't allow a request right now that'll span
4698 * the entire frame table. To within 4 frames, to allow some leeway 4683 * the entire frame table. To within 4 frames, to allow some leeway
4699 * on either side of where the hc currently is. 4684 * on either side of where the hc currently is.
4700 */ 4685 */
4701 if ((1 << (epipe->pipe.up_endpoint->ue_edesc->bInterval)) * 4686 if ((1 << (epipe->pipe.up_endpoint->ue_edesc->bInterval)) *
4702 xfer->ux_nframes >= (sc->sc_flsize - 4) * 8) { 4687 xfer->ux_nframes >= (sc->sc_flsize - 4) * 8) {
4703 DPRINTF( 4688 DPRINTF(
4704 "isoc descriptor spans entire frametable", 0, 0, 0, 0); 4689 "isoc descriptor spans entire frametable", 0, 0, 0, 0);
4705 printf("ehci: isoc descriptor requested that spans the entire frametable, too many frames\n"); 4690 printf("ehci: isoc descriptor requested that spans the entire frametable, too many frames\n");
@@ -4826,28 +4811,26 @@ ehci_device_isoc_transfer(struct usbd_xf @@ -4826,28 +4811,26 @@ ehci_device_isoc_transfer(struct usbd_xf
4826 } /* End of frame */ 4811 } /* End of frame */
4827 4812
4828 if (xfer->ux_length) 4813 if (xfer->ux_length)
4829 usb_syncmem(&exfer->ex_xfer.ux_dmabuf, 0, xfer->ux_length, 4814 usb_syncmem(&exfer->ex_xfer.ux_dmabuf, 0, xfer->ux_length,
4830 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 4815 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
4831 4816
4832 /* 4817 /*
4833 * Part 2: Transfer descriptors have now been set up, now they must 4818 * Part 2: Transfer descriptors have now been set up, now they must
4834 * be scheduled into the period frame list. Erk. Not wanting to 4819 * be scheduled into the period frame list. Erk. Not wanting to
4835 * complicate matters, transfer is denied if the transfer spans 4820 * complicate matters, transfer is denied if the transfer spans
4836 * more than the period frame list. 4821 * more than the period frame list.
4837 */ 4822 */
4838 4823
4839 mutex_enter(&sc->sc_lock); 
4840 
4841 /* Start inserting frames */ 4824 /* Start inserting frames */
4842 if (epipe->isoc.cur_xfers > 0) { 4825 if (epipe->isoc.cur_xfers > 0) {
4843 frindex = epipe->isoc.next_frame; 4826 frindex = epipe->isoc.next_frame;
4844 } else { 4827 } else {
4845 frindex = EOREAD4(sc, EHCI_FRINDEX); 4828 frindex = EOREAD4(sc, EHCI_FRINDEX);
4846 frindex = frindex >> 3; /* Erase microframe index */ 4829 frindex = frindex >> 3; /* Erase microframe index */
4847 frindex += 2; 4830 frindex += 2;
4848 } 4831 }
4849 4832
4850 if (frindex >= sc->sc_flsize) 4833 if (frindex >= sc->sc_flsize)
4851 frindex &= (sc->sc_flsize - 1); 4834 frindex &= (sc->sc_flsize - 1);
4852 4835
4853 /* What's the frame interval? */ 4836 /* What's the frame interval? */
@@ -4895,27 +4878,26 @@ ehci_device_isoc_transfer(struct usbd_xf @@ -4895,27 +4878,26 @@ ehci_device_isoc_transfer(struct usbd_xf
4895 4878
4896 frindex += i; 4879 frindex += i;
4897 if (frindex >= sc->sc_flsize) 4880 if (frindex >= sc->sc_flsize)
4898 frindex -= sc->sc_flsize; 4881 frindex -= sc->sc_flsize;
4899 4882
4900 itd = itd->xfer_next; 4883 itd = itd->xfer_next;
4901 } 4884 }
4902 4885
4903 epipe->isoc.cur_xfers++; 4886 epipe->isoc.cur_xfers++;
4904 epipe->isoc.next_frame = frindex; 4887 epipe->isoc.next_frame = frindex;
4905 4888
4906 ehci_add_intr_list(sc, exfer); 4889 ehci_add_intr_list(sc, exfer);
4907 xfer->ux_status = USBD_IN_PROGRESS; 4890 xfer->ux_status = USBD_IN_PROGRESS;
4908 mutex_exit(&sc->sc_lock); 
4909 4891
4910 return USBD_IN_PROGRESS; 4892 return USBD_IN_PROGRESS;
4911} 4893}
4912 4894
4913Static void 4895Static void
4914ehci_device_isoc_abort(struct usbd_xfer *xfer) 4896ehci_device_isoc_abort(struct usbd_xfer *xfer)
4915{ 4897{
4916 EHCIHIST_FUNC(); EHCIHIST_CALLED(); 4898 EHCIHIST_FUNC(); EHCIHIST_CALLED();
4917 4899
4918 DPRINTF("xfer = %#jx", (uintptr_t)xfer, 0, 0, 0); 4900 DPRINTF("xfer = %#jx", (uintptr_t)xfer, 0, 0, 0);
4919 ehci_abort_isoc_xfer(xfer, USBD_CANCELLED); 4901 ehci_abort_isoc_xfer(xfer, USBD_CANCELLED);
4920} 4902}
4921 4903

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

--- src/sys/dev/usb/motg.c 2022/03/03 06:08:50 1.39
+++ src/sys/dev/usb/motg.c 2022/03/03 06:12:11 1.40
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: motg.c,v 1.39 2022/03/03 06:08:50 riastradh Exp $ */ 1/* $NetBSD: motg.c,v 1.40 2022/03/03 06:12:11 riastradh 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.39 2022/03/03 06:08:50 riastradh Exp $"); 43__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.40 2022/03/03 06:12:11 riastradh Exp $");
44 44
45#ifdef _KERNEL_OPT 45#ifdef _KERNEL_OPT
46#include "opt_usb.h" 46#include "opt_usb.h"
47#endif 47#endif
48 48
49#include <sys/param.h> 49#include <sys/param.h>
50 50
51#include <sys/bus.h> 51#include <sys/bus.h>
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>
@@ -796,26 +796,28 @@ motg_get_lock(struct usbd_bus *bus, kmut @@ -796,26 +796,28 @@ motg_get_lock(struct usbd_bus *bus, kmut
796Static int 796Static int
797motg_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 797motg_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
798 void *buf, int buflen) 798 void *buf, int buflen)
799{ 799{
800 struct motg_softc *sc = MOTG_BUS2SC(bus); 800 struct motg_softc *sc = MOTG_BUS2SC(bus);
801 int status, change, totlen = 0; 801 int status, change, totlen = 0;
802 uint16_t len, value, index; 802 uint16_t len, value, index;
803 usb_port_status_t ps; 803 usb_port_status_t ps;
804 usbd_status err; 804 usbd_status err;
805 uint32_t val; 805 uint32_t val;
806 806
807 MOTGHIST_FUNC(); MOTGHIST_CALLED(); 807 MOTGHIST_FUNC(); MOTGHIST_CALLED();
808 808
 809 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
 810
809 if (sc->sc_dying) 811 if (sc->sc_dying)
810 return -1; 812 return -1;
811 813
812 DPRINTFN(MD_ROOT, "type=0x%02jx request=%02jx", req->bmRequestType, 814 DPRINTFN(MD_ROOT, "type=0x%02jx request=%02jx", req->bmRequestType,
813 req->bRequest, 0, 0); 815 req->bRequest, 0, 0);
814 816
815 len = UGETW(req->wLength); 817 len = UGETW(req->wLength);
816 value = UGETW(req->wValue); 818 value = UGETW(req->wValue);
817 index = UGETW(req->wIndex); 819 index = UGETW(req->wIndex);
818 820
819#define C(x,y) ((x) | ((y) << 8)) 821#define C(x,y) ((x) | ((y) << 8))
820 switch (C(req->bRequest, req->bmRequestType)) { 822 switch (C(req->bRequest, req->bmRequestType)) {
821 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 823 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
@@ -1010,43 +1012,40 @@ usbd_status @@ -1010,43 +1012,40 @@ usbd_status
1010motg_root_intr_transfer(struct usbd_xfer *xfer) 1012motg_root_intr_transfer(struct usbd_xfer *xfer)
1011{ 1013{
1012 1014
1013 /* Pipe isn't running, start first */ 1015 /* Pipe isn't running, start first */
1014 return motg_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 1016 return motg_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
1015} 1017}
1016 1018
1017/* Start a transfer on the root interrupt pipe */ 1019/* Start a transfer on the root interrupt pipe */
1018usbd_status 1020usbd_status
1019motg_root_intr_start(struct usbd_xfer *xfer) 1021motg_root_intr_start(struct usbd_xfer *xfer)
1020{ 1022{
1021 struct usbd_pipe *pipe = xfer->ux_pipe; 1023 struct usbd_pipe *pipe = xfer->ux_pipe;
1022 struct motg_softc *sc = MOTG_PIPE2SC(pipe); 1024 struct motg_softc *sc = MOTG_PIPE2SC(pipe);
1023 const bool polling = sc->sc_bus.ub_usepolling; 
1024 1025
1025 MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1026 MOTGHIST_FUNC(); MOTGHIST_CALLED();
1026 1027
1027 DPRINTFN(MD_ROOT, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, 1028 DPRINTFN(MD_ROOT, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer,
1028 xfer->ux_length, xfer->ux_flags, 0); 1029 xfer->ux_length, xfer->ux_flags, 0);
1029 1030
 1031 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 1032
1030 if (sc->sc_dying) 1033 if (sc->sc_dying)
1031 return USBD_IOERROR; 1034 return USBD_IOERROR;
1032 1035
1033 if (!polling) 
1034 mutex_enter(&sc->sc_lock); 
1035 KASSERT(sc->sc_intr_xfer == NULL); 1036 KASSERT(sc->sc_intr_xfer == NULL);
1036 sc->sc_intr_xfer = xfer; 1037 sc->sc_intr_xfer = xfer;
1037 xfer->ux_status = USBD_IN_PROGRESS; 1038 xfer->ux_status = USBD_IN_PROGRESS;
1038 if (!polling) 
1039 mutex_exit(&sc->sc_lock); 
1040 1039
1041 return USBD_IN_PROGRESS; 1040 return USBD_IN_PROGRESS;
1042} 1041}
1043 1042
1044/* Close the root interrupt pipe. */ 1043/* Close the root interrupt pipe. */
1045void 1044void
1046motg_root_intr_close(struct usbd_pipe *pipe) 1045motg_root_intr_close(struct usbd_pipe *pipe)
1047{ 1046{
1048 struct motg_softc *sc __diagused = MOTG_PIPE2SC(pipe); 1047 struct motg_softc *sc __diagused = MOTG_PIPE2SC(pipe);
1049 MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1048 MOTGHIST_FUNC(); MOTGHIST_CALLED();
1050 1049
1051 KASSERT(mutex_owned(&sc->sc_lock)); 1050 KASSERT(mutex_owned(&sc->sc_lock));
1052 1051
@@ -1266,31 +1265,30 @@ motg_setup_endpoint_rx(struct usbd_xfer  @@ -1266,31 +1265,30 @@ motg_setup_endpoint_rx(struct usbd_xfer
1266 1265
1267static usbd_status 1266static usbd_status
1268motg_device_ctrl_transfer(struct usbd_xfer *xfer) 1267motg_device_ctrl_transfer(struct usbd_xfer *xfer)
1269{ 1268{
1270 1269
1271 /* Pipe isn't running, so start it first. */ 1270 /* Pipe isn't running, so start it first. */
1272 return motg_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 1271 return motg_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
1273} 1272}
1274 1273
1275static usbd_status 1274static usbd_status
1276motg_device_ctrl_start(struct usbd_xfer *xfer) 1275motg_device_ctrl_start(struct usbd_xfer *xfer)
1277{ 1276{
1278 struct motg_softc *sc = MOTG_XFER2SC(xfer); 1277 struct motg_softc *sc = MOTG_XFER2SC(xfer);
1279 usbd_status err; 1278
1280 mutex_enter(&sc->sc_lock); 1279 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1281 err = motg_device_ctrl_start1(sc); 1280
1282 mutex_exit(&sc->sc_lock); 1281 return motg_device_ctrl_start1(sc);
1283 return err; 
1284} 1282}
1285 1283
1286static usbd_status 1284static usbd_status
1287motg_device_ctrl_start1(struct motg_softc *sc) 1285motg_device_ctrl_start1(struct motg_softc *sc)
1288{ 1286{
1289 struct motg_hw_ep *ep = &sc->sc_in_ep[0]; 1287 struct motg_hw_ep *ep = &sc->sc_in_ep[0];
1290 struct usbd_xfer *xfer = NULL; 1288 struct usbd_xfer *xfer = NULL;
1291 struct motg_pipe *otgpipe; 1289 struct motg_pipe *otgpipe;
1292 usbd_status err = 0; 1290 usbd_status err = 0;
1293 1291
1294 MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1292 MOTGHIST_FUNC(); MOTGHIST_CALLED();
1295 1293
1296 KASSERT(mutex_owned(&sc->sc_lock)); 1294 KASSERT(mutex_owned(&sc->sc_lock));
@@ -1707,35 +1705,34 @@ static usbd_status @@ -1707,35 +1705,34 @@ static usbd_status
1707motg_device_data_transfer(struct usbd_xfer *xfer) 1705motg_device_data_transfer(struct usbd_xfer *xfer)
1708{ 1706{
1709 MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1707 MOTGHIST_FUNC(); MOTGHIST_CALLED();
1710 1708
1711 /* Pipe isn't running, so start it first. */ 1709 /* Pipe isn't running, so start it first. */
1712 return motg_device_data_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 1710 return motg_device_data_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
1713} 1711}
1714 1712
1715static usbd_status 1713static usbd_status
1716motg_device_data_start(struct usbd_xfer *xfer) 1714motg_device_data_start(struct usbd_xfer *xfer)
1717{ 1715{
1718 struct motg_softc *sc = MOTG_XFER2SC(xfer); 1716 struct motg_softc *sc = MOTG_XFER2SC(xfer);
1719 struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 1717 struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe);
1720 usbd_status err; 
1721 1718
1722 MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1719 MOTGHIST_FUNC(); MOTGHIST_CALLED();
1723 1720
1724 mutex_enter(&sc->sc_lock); 
1725 DPRINTF("xfer %#jx status %jd", (uintptr_t)xfer, xfer->ux_status, 0, 0); 1721 DPRINTF("xfer %#jx status %jd", (uintptr_t)xfer, xfer->ux_status, 0, 0);
1726 err = motg_device_data_start1(sc, otgpipe->hw_ep); 1722
1727 mutex_exit(&sc->sc_lock); 1723 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1728 return err; 1724
 1725 return motg_device_data_start1(sc, otgpipe->hw_ep);
1729} 1726}
1730 1727
1731static usbd_status 1728static usbd_status
1732motg_device_data_start1(struct motg_softc *sc, struct motg_hw_ep *ep) 1729motg_device_data_start1(struct motg_softc *sc, struct motg_hw_ep *ep)
1733{ 1730{
1734 struct usbd_xfer *xfer = NULL; 1731 struct usbd_xfer *xfer = NULL;
1735 struct motg_pipe *otgpipe; 1732 struct motg_pipe *otgpipe;
1736 usbd_status err = 0; 1733 usbd_status err = 0;
1737 uint32_t val __diagused; 1734 uint32_t val __diagused;
1738 1735
1739 MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1736 MOTGHIST_FUNC(); MOTGHIST_CALLED();
1740 1737
1741 KASSERT(mutex_owned(&sc->sc_lock)); 1738 KASSERT(mutex_owned(&sc->sc_lock));

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

--- src/sys/dev/usb/ohci.c 2022/03/03 06:08:50 1.320
+++ src/sys/dev/usb/ohci.c 2022/03/03 06:12:11 1.321
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ohci.c,v 1.320 2022/03/03 06:08:50 riastradh Exp $ */ 1/* $NetBSD: ohci.c,v 1.321 2022/03/03 06:12:11 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2004, 2005, 2012, 2016, 2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2004, 2005, 2012, 2016, 2020 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 Nick Hudson. 10 * Matthew R. Green (mrg@eterna.com.au), and Nick Hudson.
11 * 11 *
12 * This code is derived from software contributed to The NetBSD Foundation 12 * This code is derived from software contributed to The NetBSD Foundation
13 * by Charles M. Hannum. 13 * by Charles M. Hannum.
14 * 14 *
@@ -32,27 +32,27 @@ @@ -32,27 +32,27 @@
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37/* 37/*
38 * USB Open Host Controller driver. 38 * USB Open Host Controller driver.
39 * 39 *
40 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html 40 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
41 * USB spec: http://www.usb.org/developers/docs/ 41 * USB spec: http://www.usb.org/developers/docs/
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.320 2022/03/03 06:08:50 riastradh Exp $"); 45__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.321 2022/03/03 06:12:11 riastradh 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/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>
57#include <sys/proc.h> 57#include <sys/proc.h>
58#include <sys/queue.h> 58#include <sys/queue.h>
@@ -2421,26 +2421,28 @@ dying: @@ -2421,26 +2421,28 @@ dying:
2421Static int 2421Static int
2422ohci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 2422ohci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
2423 void *buf, int buflen) 2423 void *buf, int buflen)
2424{ 2424{
2425 ohci_softc_t *sc = OHCI_BUS2SC(bus); 2425 ohci_softc_t *sc = OHCI_BUS2SC(bus);
2426 usb_port_status_t ps; 2426 usb_port_status_t ps;
2427 uint16_t len, value, index; 2427 uint16_t len, value, index;
2428 int l, totlen = 0; 2428 int l, totlen = 0;
2429 int port, i; 2429 int port, i;
2430 uint32_t v; 2430 uint32_t v;
2431 2431
2432 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 2432 OHCIHIST_FUNC(); OHCIHIST_CALLED();
2433 2433
 2434 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
 2435
2434 if (sc->sc_dying) 2436 if (sc->sc_dying)
2435 return -1; 2437 return -1;
2436 2438
2437 DPRINTFN(4, "type=0x%02jx request=%02jx", req->bmRequestType, 2439 DPRINTFN(4, "type=0x%02jx request=%02jx", req->bmRequestType,
2438 req->bRequest, 0, 0); 2440 req->bRequest, 0, 0);
2439 2441
2440 len = UGETW(req->wLength); 2442 len = UGETW(req->wLength);
2441 value = UGETW(req->wValue); 2443 value = UGETW(req->wValue);
2442 index = UGETW(req->wIndex); 2444 index = UGETW(req->wIndex);
2443 2445
2444#define C(x,y) ((x) | ((y) << 8)) 2446#define C(x,y) ((x) | ((y) << 8))
2445 switch (C(req->bRequest, req->bmRequestType)) { 2447 switch (C(req->bRequest, req->bmRequestType)) {
2446 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 2448 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
@@ -2610,38 +2612,35 @@ ohci_roothub_ctrl(struct usbd_bus *bus,  @@ -2610,38 +2612,35 @@ ohci_roothub_ctrl(struct usbd_bus *bus,
2610 2612
2611Static usbd_status 2613Static usbd_status
2612ohci_root_intr_transfer(struct usbd_xfer *xfer) 2614ohci_root_intr_transfer(struct usbd_xfer *xfer)
2613{ 2615{
2614 2616
2615 /* Pipe isn't running, start first */ 2617 /* Pipe isn't running, start first */
2616 return ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 2618 return ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
2617} 2619}
2618 2620
2619Static usbd_status 2621Static usbd_status
2620ohci_root_intr_start(struct usbd_xfer *xfer) 2622ohci_root_intr_start(struct usbd_xfer *xfer)
2621{ 2623{
2622 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 2624 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
2623 const bool polling = sc->sc_bus.ub_usepolling; 2625
 2626 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
2624 2627
2625 if (sc->sc_dying) 2628 if (sc->sc_dying)
2626 return USBD_IOERROR; 2629 return USBD_IOERROR;
2627 2630
2628 if (!polling) 
2629 mutex_enter(&sc->sc_lock); 
2630 KASSERT(sc->sc_intrxfer == NULL); 2631 KASSERT(sc->sc_intrxfer == NULL);
2631 sc->sc_intrxfer = xfer; 2632 sc->sc_intrxfer = xfer;
2632 xfer->ux_status = USBD_IN_PROGRESS; 2633 xfer->ux_status = USBD_IN_PROGRESS;
2633 if (!polling) 
2634 mutex_exit(&sc->sc_lock); 
2635 2634
2636 return USBD_IN_PROGRESS; 2635 return USBD_IN_PROGRESS;
2637} 2636}
2638 2637
2639/* Abort a root interrupt request. */ 2638/* Abort a root interrupt request. */
2640Static void 2639Static void
2641ohci_root_intr_abort(struct usbd_xfer *xfer) 2640ohci_root_intr_abort(struct usbd_xfer *xfer)
2642{ 2641{
2643 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 2642 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
2644 2643
2645 KASSERT(mutex_owned(&sc->sc_lock)); 2644 KASSERT(mutex_owned(&sc->sc_lock));
2646 KASSERT(xfer->ux_pipe->up_intrxfer == xfer); 2645 KASSERT(xfer->ux_pipe->up_intrxfer == xfer);
2647 2646
@@ -2767,48 +2766,45 @@ ohci_device_ctrl_transfer(struct usbd_xf @@ -2767,48 +2766,45 @@ ohci_device_ctrl_transfer(struct usbd_xf
2767 2766
2768Static usbd_status 2767Static usbd_status
2769ohci_device_ctrl_start(struct usbd_xfer *xfer) 2768ohci_device_ctrl_start(struct usbd_xfer *xfer)
2770{ 2769{
2771 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 2770 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
2772 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); 2771 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer);
2773 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); 2772 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe);
2774 usb_device_request_t *req = &xfer->ux_request; 2773 usb_device_request_t *req = &xfer->ux_request;
2775 struct usbd_device *dev __diagused = opipe->pipe.up_dev; 2774 struct usbd_device *dev __diagused = opipe->pipe.up_dev;
2776 ohci_soft_td_t *setup, *stat, *next, *tail; 2775 ohci_soft_td_t *setup, *stat, *next, *tail;
2777 ohci_soft_ed_t *sed; 2776 ohci_soft_ed_t *sed;
2778 int isread; 2777 int isread;
2779 int len; 2778 int len;
2780 const bool polling = sc->sc_bus.ub_usepolling; 
2781 2779
2782 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 2780 OHCIHIST_FUNC(); OHCIHIST_CALLED();
2783 2781
 2782 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 2783
2784 if (sc->sc_dying) 2784 if (sc->sc_dying)
2785 return USBD_IOERROR; 2785 return USBD_IOERROR;
2786 2786
2787 KASSERT(xfer->ux_rqflags & URQ_REQUEST); 2787 KASSERT(xfer->ux_rqflags & URQ_REQUEST);
2788 2788
2789 isread = req->bmRequestType & UT_READ; 2789 isread = req->bmRequestType & UT_READ;
2790 len = UGETW(req->wLength); 2790 len = UGETW(req->wLength);
2791 2791
2792 DPRINTF("xfer=%#jx len=%jd, addr=%jd, endpt=%jd", (uintptr_t)xfer, len, 2792 DPRINTF("xfer=%#jx len=%jd, addr=%jd, endpt=%jd", (uintptr_t)xfer, len,
2793 dev->ud_addr, opipe->pipe.up_endpoint->ue_edesc->bEndpointAddress); 2793 dev->ud_addr, opipe->pipe.up_endpoint->ue_edesc->bEndpointAddress);
2794 DPRINTF("type=0x%02jx, request=0x%02jx, wValue=0x%04jx, wIndex=0x%04jx", 2794 DPRINTF("type=0x%02jx, request=0x%02jx, wValue=0x%04jx, wIndex=0x%04jx",
2795 req->bmRequestType, req->bRequest, UGETW(req->wValue), 2795 req->bmRequestType, req->bRequest, UGETW(req->wValue),
2796 UGETW(req->wIndex)); 2796 UGETW(req->wIndex));
2797 2797
2798 /* Need to take lock here for pipe->tail.td */ 
2799 if (!polling) 
2800 mutex_enter(&sc->sc_lock); 
2801 
2802 /* 2798 /*
2803 * Use the pipe "tail" TD as our first and loan our first TD to the 2799 * Use the pipe "tail" TD as our first and loan our first TD to the
2804 * next transfer 2800 * next transfer
2805 */ 2801 */
2806 setup = opipe->tail.td; 2802 setup = opipe->tail.td;
2807 opipe->tail.td = ox->ox_setup; 2803 opipe->tail.td = ox->ox_setup;
2808 ox->ox_setup = setup; 2804 ox->ox_setup = setup;
2809 setup->held = &ox->ox_setup; 2805 setup->held = &ox->ox_setup;
2810 2806
2811 DPRINTFN(10, "xfer=%#jx new setup=%#jx held at %#jx", (uintptr_t)ox, 2807 DPRINTFN(10, "xfer=%#jx new setup=%#jx held at %#jx", (uintptr_t)ox,
2812 (uintptr_t)setup, (uintptr_t)setup->held, 0); 2808 (uintptr_t)setup, (uintptr_t)setup->held, 0);
2813 2809
2814 stat = ox->ox_stat; 2810 stat = ox->ox_stat;
@@ -2923,28 +2919,26 @@ ohci_device_ctrl_start(struct usbd_xfer  @@ -2923,28 +2919,26 @@ ohci_device_ctrl_start(struct usbd_xfer
2923 2919
2924 /* Insert ED in schedule */ 2920 /* Insert ED in schedule */
2925 sed->ed.ed_tailp = HTOO32(tail->physaddr); 2921 sed->ed.ed_tailp = HTOO32(tail->physaddr);
2926 usb_syncmem(&sed->dma, 2922 usb_syncmem(&sed->dma,
2927 sed->offs + offsetof(ohci_ed_t, ed_tailp), 2923 sed->offs + offsetof(ohci_ed_t, ed_tailp),
2928 sizeof(sed->ed.ed_tailp), 2924 sizeof(sed->ed.ed_tailp),
2929 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2925 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2930 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); 2926 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
2931 usbd_xfer_schedule_timeout(xfer); 2927 usbd_xfer_schedule_timeout(xfer);
2932 2928
2933 DPRINTF("done", 0, 0, 0, 0); 2929 DPRINTF("done", 0, 0, 0, 0);
2934 2930
2935 xfer->ux_status = USBD_IN_PROGRESS; 2931 xfer->ux_status = USBD_IN_PROGRESS;
2936 if (!polling) 
2937 mutex_exit(&sc->sc_lock); 
2938 2932
2939 return USBD_IN_PROGRESS; 2933 return USBD_IN_PROGRESS;
2940} 2934}
2941 2935
2942/* Abort a device control request. */ 2936/* Abort a device control request. */
2943Static void 2937Static void
2944ohci_device_ctrl_abort(struct usbd_xfer *xfer) 2938ohci_device_ctrl_abort(struct usbd_xfer *xfer)
2945{ 2939{
2946 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); 2940 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer);
2947 2941
2948 KASSERT(mutex_owned(&sc->sc_lock)); 2942 KASSERT(mutex_owned(&sc->sc_lock));
2949 2943
2950 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 2944 OHCIHIST_FUNC(); OHCIHIST_CALLED();
@@ -3044,47 +3038,45 @@ ohci_device_bulk_transfer(struct usbd_xf @@ -3044,47 +3038,45 @@ ohci_device_bulk_transfer(struct usbd_xf
3044 return ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 3038 return ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
3045} 3039}
3046 3040
3047Static usbd_status 3041Static usbd_status
3048ohci_device_bulk_start(struct usbd_xfer *xfer) 3042ohci_device_bulk_start(struct usbd_xfer *xfer)
3049{ 3043{
3050 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); 3044 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer);
3051 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); 3045 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe);
3052 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 3046 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
3053 ohci_soft_td_t *last; 3047 ohci_soft_td_t *last;
3054 ohci_soft_td_t *data, *tail, *tdp; 3048 ohci_soft_td_t *data, *tail, *tdp;
3055 ohci_soft_ed_t *sed; 3049 ohci_soft_ed_t *sed;
3056 int len, isread, endpt; 3050 int len, isread, endpt;
3057 const bool polling = sc->sc_bus.ub_usepolling; 
3058 3051
3059 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 3052 OHCIHIST_FUNC(); OHCIHIST_CALLED();
3060 3053
 3054 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 3055
3061 if (sc->sc_dying) 3056 if (sc->sc_dying)
3062 return USBD_IOERROR; 3057 return USBD_IOERROR;
3063 3058
3064 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 3059 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
3065 3060
3066 len = xfer->ux_length; 3061 len = xfer->ux_length;
3067 endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; 3062 endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress;
3068 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 3063 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3069 sed = opipe->sed; 3064 sed = opipe->sed;
3070 3065
3071 DPRINTFN(4, "xfer=%#jx len=%jd isread=%jd flags=%jd", (uintptr_t)xfer, 3066 DPRINTFN(4, "xfer=%#jx len=%jd isread=%jd flags=%jd", (uintptr_t)xfer,
3072 len, isread, xfer->ux_flags); 3067 len, isread, xfer->ux_flags);
3073 DPRINTFN(4, "endpt=%jd", endpt, 0, 0, 0); 3068 DPRINTFN(4, "endpt=%jd", endpt, 0, 0, 0);
3074 3069
3075 if (!polling) 
3076 mutex_enter(&sc->sc_lock); 
3077 
3078 /* 3070 /*
3079 * Use the pipe "tail" TD as our first and loan our first TD to the 3071 * Use the pipe "tail" TD as our first and loan our first TD to the
3080 * next transfer 3072 * next transfer
3081 */ 3073 */
3082 data = opipe->tail.td; 3074 data = opipe->tail.td;
3083 opipe->tail.td = ox->ox_stds[0]; 3075 opipe->tail.td = ox->ox_stds[0];
3084 ox->ox_stds[0] = data; 3076 ox->ox_stds[0] = data;
3085 data->held = &ox->ox_stds[0]; 3077 data->held = &ox->ox_stds[0];
3086 ohci_reset_std_chain(sc, xfer, len, isread, data, &last); 3078 ohci_reset_std_chain(sc, xfer, len, isread, data, &last);
3087 DPRINTFN(10, "xfer=%#jx new data=%#jx held at %#jx", 3079 DPRINTFN(10, "xfer=%#jx new data=%#jx held at %#jx",
3088 (uintptr_t)ox, (uintptr_t)data, (uintptr_t)data->held, 0); 3080 (uintptr_t)ox, (uintptr_t)data, (uintptr_t)data->held, 0);
3089 3081
3090 /* point at sentinel */ 3082 /* point at sentinel */
@@ -3131,28 +3123,26 @@ ohci_device_bulk_start(struct usbd_xfer  @@ -3131,28 +3123,26 @@ ohci_device_bulk_start(struct usbd_xfer
3131 /* Insert ED in schedule */ 3123 /* Insert ED in schedule */
3132 for (tdp = data; tdp != tail; tdp = tdp->nexttd) { 3124 for (tdp = data; tdp != tail; tdp = tdp->nexttd) {
3133 KASSERT(tdp->xfer == xfer); 3125 KASSERT(tdp->xfer == xfer);
3134 } 3126 }
3135 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3127 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3136 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3128 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3137 sed->ed.ed_tailp = HTOO32(tail->physaddr); 3129 sed->ed.ed_tailp = HTOO32(tail->physaddr);
3138 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3130 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3139 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3131 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3140 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3132 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3141 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF); 3133 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
3142 usbd_xfer_schedule_timeout(xfer); 3134 usbd_xfer_schedule_timeout(xfer);
3143 xfer->ux_status = USBD_IN_PROGRESS; 3135 xfer->ux_status = USBD_IN_PROGRESS;
3144 if (!polling) 
3145 mutex_exit(&sc->sc_lock); 
3146 3136
3147 return USBD_IN_PROGRESS; 3137 return USBD_IN_PROGRESS;
3148} 3138}
3149 3139
3150Static void 3140Static void
3151ohci_device_bulk_abort(struct usbd_xfer *xfer) 3141ohci_device_bulk_abort(struct usbd_xfer *xfer)
3152{ 3142{
3153 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); 3143 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer);
3154 3144
3155 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 3145 OHCIHIST_FUNC(); OHCIHIST_CALLED();
3156 3146
3157 KASSERT(mutex_owned(&sc->sc_lock)); 3147 KASSERT(mutex_owned(&sc->sc_lock));
3158 3148
@@ -3242,45 +3232,43 @@ ohci_device_intr_transfer(struct usbd_xf @@ -3242,45 +3232,43 @@ ohci_device_intr_transfer(struct usbd_xf
3242 /* Pipe isn't running, start first */ 3232 /* Pipe isn't running, start first */
3243 return ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 3233 return ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
3244} 3234}
3245 3235
3246Static usbd_status 3236Static usbd_status
3247ohci_device_intr_start(struct usbd_xfer *xfer) 3237ohci_device_intr_start(struct usbd_xfer *xfer)
3248{ 3238{
3249 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); 3239 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer);
3250 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); 3240 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe);
3251 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 3241 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
3252 ohci_soft_ed_t *sed = opipe->sed; 3242 ohci_soft_ed_t *sed = opipe->sed;
3253 ohci_soft_td_t *data, *last, *tail; 3243 ohci_soft_td_t *data, *last, *tail;
3254 int len, isread, endpt; 3244 int len, isread, endpt;
3255 const bool polling = sc->sc_bus.ub_usepolling; 
3256 3245
3257 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 3246 OHCIHIST_FUNC(); OHCIHIST_CALLED();
3258 3247
 3248 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 3249
3259 if (sc->sc_dying) 3250 if (sc->sc_dying)
3260 return USBD_IOERROR; 3251 return USBD_IOERROR;
3261 3252
3262 DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd priv=%#jx", (uintptr_t)xfer, 3253 DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd priv=%#jx", (uintptr_t)xfer,
3263 xfer->ux_length, xfer->ux_flags, (uintptr_t)xfer->ux_priv); 3254 xfer->ux_length, xfer->ux_flags, (uintptr_t)xfer->ux_priv);
3264 3255
3265 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 3256 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
3266 3257
3267 len = xfer->ux_length; 3258 len = xfer->ux_length;
3268 endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; 3259 endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress;
3269 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 3260 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3270 3261
3271 if (!polling) 
3272 mutex_enter(&sc->sc_lock); 
3273 
3274 /* 3262 /*
3275 * Use the pipe "tail" TD as our first and loan our first TD to the 3263 * Use the pipe "tail" TD as our first and loan our first TD to the
3276 * next transfer. 3264 * next transfer.
3277 */ 3265 */
3278 data = opipe->tail.td; 3266 data = opipe->tail.td;
3279 opipe->tail.td = ox->ox_stds[0]; 3267 opipe->tail.td = ox->ox_stds[0];
3280 ox->ox_stds[0] = data; 3268 ox->ox_stds[0] = data;
3281 data->held = &ox->ox_stds[0]; 3269 data->held = &ox->ox_stds[0];
3282 ohci_reset_std_chain(sc, xfer, len, isread, data, &last); 3270 ohci_reset_std_chain(sc, xfer, len, isread, data, &last);
3283 DPRINTFN(10, "xfer=%#jx new data=%#jx held at %#jx", 3271 DPRINTFN(10, "xfer=%#jx new data=%#jx held at %#jx",
3284 (uintptr_t)ox, (uintptr_t)data, (uintptr_t)data->held, 0); 3272 (uintptr_t)ox, (uintptr_t)data, (uintptr_t)data->held, 0);
3285 3273
3286 /* point at sentinel */ 3274 /* point at sentinel */
@@ -3317,28 +3305,26 @@ ohci_device_intr_start(struct usbd_xfer  @@ -3317,28 +3305,26 @@ ohci_device_intr_start(struct usbd_xfer
3317 } 3305 }
3318 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); 3306 DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0);
3319#endif 3307#endif
3320 3308
3321 /* Insert ED in schedule */ 3309 /* Insert ED in schedule */
3322 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3310 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3323 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3311 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3324 sed->ed.ed_tailp = HTOO32(tail->physaddr); 3312 sed->ed.ed_tailp = HTOO32(tail->physaddr);
3325 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3313 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3326 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3314 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3327 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3315 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3328 3316
3329 xfer->ux_status = USBD_IN_PROGRESS; 3317 xfer->ux_status = USBD_IN_PROGRESS;
3330 if (!polling) 
3331 mutex_exit(&sc->sc_lock); 
3332 3318
3333 return USBD_IN_PROGRESS; 3319 return USBD_IN_PROGRESS;
3334} 3320}
3335 3321
3336/* Abort a device interrupt request. */ 3322/* Abort a device interrupt request. */
3337Static void 3323Static void
3338ohci_device_intr_abort(struct usbd_xfer *xfer) 3324ohci_device_intr_abort(struct usbd_xfer *xfer)
3339{ 3325{
3340 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); 3326 ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer);
3341 3327
3342 KASSERT(mutex_owned(&sc->sc_lock)); 3328 KASSERT(mutex_owned(&sc->sc_lock));
3343 3329
3344 usbd_xfer_abort(xfer); 3330 usbd_xfer_abort(xfer);
@@ -3549,32 +3535,30 @@ ohci_device_isoc_enter(struct usbd_xfer  @@ -3549,32 +3535,30 @@ ohci_device_isoc_enter(struct usbd_xfer
3549{ 3535{
3550 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); 3536 struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer);
3551 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); 3537 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe);
3552 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 3538 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
3553 ohci_soft_ed_t *sed = opipe->sed; 3539 ohci_soft_ed_t *sed = opipe->sed;
3554 ohci_soft_itd_t *sitd, *nsitd, *tail; 3540 ohci_soft_itd_t *sitd, *nsitd, *tail;
3555 ohci_physaddr_t buf, offs, bp0, bp1; 3541 ohci_physaddr_t buf, offs, bp0, bp1;
3556 int i, ncur, nframes; 3542 int i, ncur, nframes;
3557 size_t boff, frlen; 3543 size_t boff, frlen;
3558 3544
3559 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 3545 OHCIHIST_FUNC(); OHCIHIST_CALLED();
3560 DPRINTFN(5, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0); 3546 DPRINTFN(5, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0);
3561 3547
3562 mutex_enter(&sc->sc_lock); 3548 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
3563 3549
3564 if (sc->sc_dying) { 3550 if (sc->sc_dying)
3565 mutex_exit(&sc->sc_lock); 
3566 return; 3551 return;
3567 } 
3568 3552
3569 struct isoc *isoc = &opipe->isoc; 3553 struct isoc *isoc = &opipe->isoc;
3570 3554
3571 DPRINTFN(1, "used=%jd next=%jd xfer=%#jx nframes=%jd", 3555 DPRINTFN(1, "used=%jd next=%jd xfer=%#jx nframes=%jd",
3572 isoc->inuse, isoc->next, (uintptr_t)xfer, xfer->ux_nframes); 3556 isoc->inuse, isoc->next, (uintptr_t)xfer, xfer->ux_nframes);
3573 3557
3574 int isread = 3558 int isread =
3575 (UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN); 3559 (UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN);
3576 3560
3577 if (xfer->ux_length) 3561 if (xfer->ux_length)
3578 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, 3562 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
3579 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 3563 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
3580 3564
@@ -3713,27 +3697,26 @@ ohci_device_isoc_enter(struct usbd_xfer  @@ -3713,27 +3697,26 @@ ohci_device_isoc_enter(struct usbd_xfer
3713 0, 0, 0); 3697 0, 0, 0);
3714 ohci_dump_itds(sc, xfer->ux_hcpriv); 3698 ohci_dump_itds(sc, xfer->ux_hcpriv);
3715 ohci_dump_ed(sc, sed); 3699 ohci_dump_ed(sc, sed);
3716 } 3700 }
3717#endif 3701#endif
3718 3702
3719 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3703 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3720 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3704 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3721 sed->ed.ed_tailp = HTOO32(tail->physaddr); 3705 sed->ed.ed_tailp = HTOO32(tail->physaddr);
3722 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3706 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3723 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 3707 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
3724 sizeof(sed->ed.ed_flags), 3708 sizeof(sed->ed.ed_flags),
3725 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3709 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3726 mutex_exit(&sc->sc_lock); 
3727} 3710}
3728 3711
3729void 3712void
3730ohci_device_isoc_abort(struct usbd_xfer *xfer) 3713ohci_device_isoc_abort(struct usbd_xfer *xfer)
3731{ 3714{
3732 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); 3715 struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe);
3733 ohci_softc_t *sc = OHCI_XFER2SC(xfer); 3716 ohci_softc_t *sc = OHCI_XFER2SC(xfer);
3734 ohci_soft_ed_t *sed; 3717 ohci_soft_ed_t *sed;
3735 ohci_soft_itd_t *sitd; 3718 ohci_soft_itd_t *sitd;
3736 3719
3737 OHCIHIST_FUNC(); OHCIHIST_CALLED(); 3720 OHCIHIST_FUNC(); OHCIHIST_CALLED();
3738 DPRINTFN(1, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0); 3721 DPRINTFN(1, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0);
3739 3722

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

--- src/sys/dev/usb/uhci.c 2022/03/03 06:08:50 1.310
+++ src/sys/dev/usb/uhci.c 2022/03/03 06:12:11 1.311
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: uhci.c,v 1.310 2022/03/03 06:08:50 riastradh Exp $ */ 1/* $NetBSD: uhci.c,v 1.311 2022/03/03 06:12:11 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2004, 2011, 2012, 2016, 2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2004, 2011, 2012, 2016, 2020 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 Nick Hudson. 10 * Matthew R. Green (mrg@eterna.com.au) 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:
@@ -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.310 2022/03/03 06:08:50 riastradh Exp $"); 45__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.311 2022/03/03 06:12:11 riastradh 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>
@@ -2261,50 +2261,47 @@ uhci_device_bulk_transfer(struct usbd_xf @@ -2261,50 +2261,47 @@ uhci_device_bulk_transfer(struct usbd_xf
2261 2261
2262 /* Pipe isn't running, so start it first. */ 2262 /* Pipe isn't running, so start it first. */
2263 return uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 2263 return uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
2264} 2264}
2265 2265
2266usbd_status 2266usbd_status
2267uhci_device_bulk_start(struct usbd_xfer *xfer) 2267uhci_device_bulk_start(struct usbd_xfer *xfer)
2268{ 2268{
2269 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2269 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2270 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2270 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2271 uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2271 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2272 uhci_soft_td_t *data, *dataend; 2272 uhci_soft_td_t *data, *dataend;
2273 uhci_soft_qh_t *sqh; 2273 uhci_soft_qh_t *sqh;
2274 const bool polling = sc->sc_bus.ub_usepolling; 
2275 int len; 2274 int len;
2276 int endpt; 2275 int endpt;
2277 int isread; 2276 int isread;
2278 2277
2279 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2278 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2280 DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, 2279 DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer,
2281 xfer->ux_length, xfer->ux_flags, 0); 2280 xfer->ux_length, xfer->ux_flags, 0);
2282 2281
 2282 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 2283
2283 if (sc->sc_dying) 2284 if (sc->sc_dying)
2284 return USBD_IOERROR; 2285 return USBD_IOERROR;
2285 2286
2286 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 2287 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
2287 KASSERT(xfer->ux_length <= xfer->ux_bufsize); 2288 KASSERT(xfer->ux_length <= xfer->ux_bufsize);
2288 2289
2289 len = xfer->ux_length; 2290 len = xfer->ux_length;
2290 endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; 2291 endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
2291 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 2292 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2292 sqh = upipe->bulk.sqh; 2293 sqh = upipe->bulk.sqh;
2293 2294
2294 /* Take lock here to protect nexttoggle */ 
2295 if (!polling) 
2296 mutex_enter(&sc->sc_lock); 
2297 
2298 uhci_reset_std_chain(sc, xfer, len, isread, &upipe->nexttoggle, 2295 uhci_reset_std_chain(sc, xfer, len, isread, &upipe->nexttoggle,
2299 &dataend); 2296 &dataend);
2300 2297
2301 data = ux->ux_stdstart; 2298 data = ux->ux_stdstart;
2302 ux->ux_stdend = dataend; 2299 ux->ux_stdend = dataend;
2303 dataend->td.td_status |= htole32(UHCI_TD_IOC); 2300 dataend->td.td_status |= htole32(UHCI_TD_IOC);
2304 usb_syncmem(&dataend->dma, 2301 usb_syncmem(&dataend->dma,
2305 dataend->offs + offsetof(uhci_td_t, td_status), 2302 dataend->offs + offsetof(uhci_td_t, td_status),
2306 sizeof(dataend->td.td_status), 2303 sizeof(dataend->td.td_status),
2307 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2304 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2308 2305
2309#ifdef UHCI_DEBUG 2306#ifdef UHCI_DEBUG
2310 if (uhcidebug >= 10) { 2307 if (uhcidebug >= 10) {
@@ -2318,28 +2315,26 @@ uhci_device_bulk_start(struct usbd_xfer  @@ -2318,28 +2315,26 @@ uhci_device_bulk_start(struct usbd_xfer
2318 KASSERT(ux->ux_isdone); 2315 KASSERT(ux->ux_isdone);
2319#ifdef DIAGNOSTIC 2316#ifdef DIAGNOSTIC
2320 ux->ux_isdone = false; 2317 ux->ux_isdone = false;
2321#endif 2318#endif
2322 2319
2323 sqh->elink = data; 2320 sqh->elink = data;
2324 sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD); 2321 sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD);
2325 /* uhci_add_bulk() will do usb_syncmem(sqh) */ 2322 /* uhci_add_bulk() will do usb_syncmem(sqh) */
2326 2323
2327 uhci_add_bulk(sc, sqh); 2324 uhci_add_bulk(sc, sqh);
2328 uhci_add_intr_list(sc, ux); 2325 uhci_add_intr_list(sc, ux);
2329 usbd_xfer_schedule_timeout(xfer); 2326 usbd_xfer_schedule_timeout(xfer);
2330 xfer->ux_status = USBD_IN_PROGRESS; 2327 xfer->ux_status = USBD_IN_PROGRESS;
2331 if (!polling) 
2332 mutex_exit(&sc->sc_lock); 
2333 2328
2334 return USBD_IN_PROGRESS; 2329 return USBD_IN_PROGRESS;
2335} 2330}
2336 2331
2337/* Abort a device bulk request. */ 2332/* Abort a device bulk request. */
2338void 2333void
2339uhci_device_bulk_abort(struct usbd_xfer *xfer) 2334uhci_device_bulk_abort(struct usbd_xfer *xfer)
2340{ 2335{
2341 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); 2336 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer);
2342 2337
2343 KASSERT(mutex_owned(&sc->sc_lock)); 2338 KASSERT(mutex_owned(&sc->sc_lock));
2344 2339
2345 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2340 UHCIHIST_FUNC(); UHCIHIST_CALLED();
@@ -2485,57 +2480,55 @@ uhci_device_ctrl_transfer(struct usbd_xf @@ -2485,57 +2480,55 @@ uhci_device_ctrl_transfer(struct usbd_xf
2485 2480
2486usbd_status 2481usbd_status
2487uhci_device_ctrl_start(struct usbd_xfer *xfer) 2482uhci_device_ctrl_start(struct usbd_xfer *xfer)
2488{ 2483{
2489 uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2484 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2490 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); 2485 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer);
2491 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2486 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2492 usb_device_request_t *req = &xfer->ux_request; 2487 usb_device_request_t *req = &xfer->ux_request;
2493 struct usbd_device *dev = upipe->pipe.up_dev; 2488 struct usbd_device *dev = upipe->pipe.up_dev;
2494 int addr = dev->ud_addr; 2489 int addr = dev->ud_addr;
2495 int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; 2490 int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
2496 uhci_soft_td_t *setup, *stat, *next, *dataend; 2491 uhci_soft_td_t *setup, *stat, *next, *dataend;
2497 uhci_soft_qh_t *sqh; 2492 uhci_soft_qh_t *sqh;
2498 const bool polling = sc->sc_bus.ub_usepolling; 
2499 int len; 2493 int len;
2500 int isread; 2494 int isread;
2501 2495
2502 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2496 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2503 2497
 2498 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 2499
2504 if (sc->sc_dying) 2500 if (sc->sc_dying)
2505 return USBD_IOERROR; 2501 return USBD_IOERROR;
2506 2502
2507 KASSERT(xfer->ux_rqflags & URQ_REQUEST); 2503 KASSERT(xfer->ux_rqflags & URQ_REQUEST);
2508 2504
2509 DPRINTFN(3, "type=0x%02jx, request=0x%02jx, " 2505 DPRINTFN(3, "type=0x%02jx, request=0x%02jx, "
2510 "wValue=0x%04jx, wIndex=0x%04jx", 2506 "wValue=0x%04jx, wIndex=0x%04jx",
2511 req->bmRequestType, req->bRequest, UGETW(req->wValue), 2507 req->bmRequestType, req->bRequest, UGETW(req->wValue),
2512 UGETW(req->wIndex)); 2508 UGETW(req->wIndex));
2513 DPRINTFN(3, "len=%jd, addr=%jd, endpt=%jd", 2509 DPRINTFN(3, "len=%jd, addr=%jd, endpt=%jd",
2514 UGETW(req->wLength), dev->ud_addr, endpt, 0); 2510 UGETW(req->wLength), dev->ud_addr, endpt, 0);
2515 2511
2516 isread = req->bmRequestType & UT_READ; 2512 isread = req->bmRequestType & UT_READ;
2517 len = UGETW(req->wLength); 2513 len = UGETW(req->wLength);
2518 2514
2519 setup = upipe->ctrl.setup; 2515 setup = upipe->ctrl.setup;
2520 stat = upipe->ctrl.stat; 2516 stat = upipe->ctrl.stat;
2521 sqh = upipe->ctrl.sqh; 2517 sqh = upipe->ctrl.sqh;
2522 2518
2523 memcpy(KERNADDR(&upipe->ctrl.reqdma, 0), req, sizeof(*req)); 2519 memcpy(KERNADDR(&upipe->ctrl.reqdma, 0), req, sizeof(*req));
2524 usb_syncmem(&upipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE); 2520 usb_syncmem(&upipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE);
2525 2521
2526 if (!polling) 
2527 mutex_enter(&sc->sc_lock); 
2528 
2529 /* Set up data transaction */ 2522 /* Set up data transaction */
2530 if (len != 0) { 2523 if (len != 0) {
2531 upipe->nexttoggle = 1; 2524 upipe->nexttoggle = 1;
2532 next = uxfer->ux_data; 2525 next = uxfer->ux_data;
2533 uhci_reset_std_chain(sc, xfer, len, isread, 2526 uhci_reset_std_chain(sc, xfer, len, isread,
2534 &upipe->nexttoggle, &dataend); 2527 &upipe->nexttoggle, &dataend);
2535 dataend->link.std = stat; 2528 dataend->link.std = stat;
2536 dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_TD); 2529 dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_TD);
2537 usb_syncmem(&dataend->dma, 2530 usb_syncmem(&dataend->dma,
2538 dataend->offs + offsetof(uhci_td_t, td_link), 2531 dataend->offs + offsetof(uhci_td_t, td_link),
2539 sizeof(dataend->td.td_link), 2532 sizeof(dataend->td.td_link),
2540 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2533 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2541 } else { 2534 } else {
@@ -2613,28 +2606,26 @@ uhci_device_ctrl_start(struct usbd_xfer  @@ -2613,28 +2606,26 @@ uhci_device_ctrl_start(struct usbd_xfer
2613 xqh != NULL; 2606 xqh != NULL;
2614 xqh = (maxqh++ == 5 || xqh->hlink == sxqh || 2607 xqh = (maxqh++ == 5 || xqh->hlink == sxqh ||
2615 xqh->hlink == xqh ? NULL : xqh->hlink)) { 2608 xqh->hlink == xqh ? NULL : xqh->hlink)) {
2616 uhci_dump_qh(xqh); 2609 uhci_dump_qh(xqh);
2617 } 2610 }
2618 DPRINTFN(12, "Enqueued QH:", 0, 0, 0, 0); 2611 DPRINTFN(12, "Enqueued QH:", 0, 0, 0, 0);
2619 uhci_dump_qh(sqh); 2612 uhci_dump_qh(sqh);
2620 uhci_dump_tds(sqh->elink); 2613 uhci_dump_tds(sqh->elink);
2621 DPRINTF("--- dump end ---", 0, 0, 0, 0); 2614 DPRINTF("--- dump end ---", 0, 0, 0, 0);
2622 } 2615 }
2623#endif 2616#endif
2624 usbd_xfer_schedule_timeout(xfer); 2617 usbd_xfer_schedule_timeout(xfer);
2625 xfer->ux_status = USBD_IN_PROGRESS; 2618 xfer->ux_status = USBD_IN_PROGRESS;
2626 if (!polling) 
2627 mutex_exit(&sc->sc_lock); 
2628 2619
2629 return USBD_IN_PROGRESS; 2620 return USBD_IN_PROGRESS;
2630} 2621}
2631 2622
2632int 2623int
2633uhci_device_intr_init(struct usbd_xfer *xfer) 2624uhci_device_intr_init(struct usbd_xfer *xfer)
2634{ 2625{
2635 uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2626 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2636 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2627 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2637 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; 2628 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc;
2638 int endpt = ed->bEndpointAddress; 2629 int endpt = ed->bEndpointAddress;
2639 int isread = UE_GET_DIR(endpt) == UE_DIR_IN; 2630 int isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2640 int len = xfer->ux_bufsize; 2631 int len = xfer->ux_bufsize;
@@ -2675,54 +2666,53 @@ uhci_device_intr_transfer(struct usbd_xf @@ -2675,54 +2666,53 @@ uhci_device_intr_transfer(struct usbd_xf
2675 2666
2676 /* Pipe isn't running, so start it first. */ 2667 /* Pipe isn't running, so start it first. */
2677 return uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 2668 return uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
2678} 2669}
2679 2670
2680usbd_status 2671usbd_status
2681uhci_device_intr_start(struct usbd_xfer *xfer) 2672uhci_device_intr_start(struct usbd_xfer *xfer)
2682{ 2673{
2683 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2674 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2684 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2675 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2685 uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2676 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2686 uhci_soft_td_t *data, *dataend; 2677 uhci_soft_td_t *data, *dataend;
2687 uhci_soft_qh_t *sqh; 2678 uhci_soft_qh_t *sqh;
2688 const bool polling = sc->sc_bus.ub_usepolling; 
2689 int isread, endpt; 2679 int isread, endpt;
2690 int i; 2680 int i;
2691 2681
2692 if (sc->sc_dying) 
2693 return USBD_IOERROR; 
2694 
2695 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2682 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2696 2683
2697 DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, 2684 DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer,
2698 xfer->ux_length, xfer->ux_flags, 0); 2685 xfer->ux_length, xfer->ux_flags, 0);
2699 2686
 2687 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 2688
 2689 if (sc->sc_dying)
 2690 return USBD_IOERROR;
 2691
2700 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 2692 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
2701 KASSERT(xfer->ux_length <= xfer->ux_bufsize); 2693 KASSERT(xfer->ux_length <= xfer->ux_bufsize);
2702 2694
2703 endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; 2695 endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
2704 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 2696 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2705 2697
2706 data = ux->ux_stdstart; 2698 data = ux->ux_stdstart;
2707 2699
2708 KASSERT(ux->ux_isdone); 2700 KASSERT(ux->ux_isdone);
2709#ifdef DIAGNOSTIC 2701#ifdef DIAGNOSTIC
2710 ux->ux_isdone = false; 2702 ux->ux_isdone = false;
2711#endif 2703#endif
2712 2704
2713 /* Take lock to protect nexttoggle */ 2705 /* Take lock to protect nexttoggle */
2714 if (!polling) 
2715 mutex_enter(&sc->sc_lock); 
2716 uhci_reset_std_chain(sc, xfer, xfer->ux_length, isread, 2706 uhci_reset_std_chain(sc, xfer, xfer->ux_length, isread,
2717 &upipe->nexttoggle, &dataend); 2707 &upipe->nexttoggle, &dataend);
2718 2708
2719 dataend->td.td_status |= htole32(UHCI_TD_IOC); 2709 dataend->td.td_status |= htole32(UHCI_TD_IOC);
2720 usb_syncmem(&dataend->dma, 2710 usb_syncmem(&dataend->dma,
2721 dataend->offs + offsetof(uhci_td_t, td_status), 2711 dataend->offs + offsetof(uhci_td_t, td_status),
2722 sizeof(dataend->td.td_status), 2712 sizeof(dataend->td.td_status),
2723 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2713 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2724 ux->ux_stdend = dataend; 2714 ux->ux_stdend = dataend;
2725 2715
2726#ifdef UHCI_DEBUG 2716#ifdef UHCI_DEBUG
2727 if (uhcidebug >= 10) { 2717 if (uhcidebug >= 10) {
2728 DPRINTF("--- dump start ---", 0, 0, 0, 0); 2718 DPRINTF("--- dump start ---", 0, 0, 0, 0);
@@ -2734,28 +2724,26 @@ uhci_device_intr_start(struct usbd_xfer  @@ -2734,28 +2724,26 @@ uhci_device_intr_start(struct usbd_xfer
2734 2724
2735 DPRINTFN(10, "qhs[0]=%#jx", (uintptr_t)upipe->intr.qhs[0], 0, 0, 0); 2725 DPRINTFN(10, "qhs[0]=%#jx", (uintptr_t)upipe->intr.qhs[0], 0, 0, 0);
2736 for (i = 0; i < upipe->intr.npoll; i++) { 2726 for (i = 0; i < upipe->intr.npoll; i++) {
2737 sqh = upipe->intr.qhs[i]; 2727 sqh = upipe->intr.qhs[i];
2738 sqh->elink = data; 2728 sqh->elink = data;
2739 sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD); 2729 sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD);
2740 usb_syncmem(&sqh->dma, 2730 usb_syncmem(&sqh->dma,
2741 sqh->offs + offsetof(uhci_qh_t, qh_elink), 2731 sqh->offs + offsetof(uhci_qh_t, qh_elink),
2742 sizeof(sqh->qh.qh_elink), 2732 sizeof(sqh->qh.qh_elink),
2743 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2733 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2744 } 2734 }
2745 uhci_add_intr_list(sc, ux); 2735 uhci_add_intr_list(sc, ux);
2746 xfer->ux_status = USBD_IN_PROGRESS; 2736 xfer->ux_status = USBD_IN_PROGRESS;
2747 if (!polling) 
2748 mutex_exit(&sc->sc_lock); 
2749 2737
2750#ifdef UHCI_DEBUG 2738#ifdef UHCI_DEBUG
2751 if (uhcidebug >= 10) { 2739 if (uhcidebug >= 10) {
2752 DPRINTF("--- dump start ---", 0, 0, 0, 0); 2740 DPRINTF("--- dump start ---", 0, 0, 0, 0);
2753 uhci_dump_tds(data); 2741 uhci_dump_tds(data);
2754 uhci_dump_qh(upipe->intr.qhs[0]); 2742 uhci_dump_qh(upipe->intr.qhs[0]);
2755 DPRINTF("--- dump end ---", 0, 0, 0, 0); 2743 DPRINTF("--- dump end ---", 0, 0, 0, 0);
2756 } 2744 }
2757#endif 2745#endif
2758 2746
2759 return USBD_IN_PROGRESS; 2747 return USBD_IN_PROGRESS;
2760} 2748}
2761 2749
@@ -2844,26 +2832,28 @@ uhci_device_isoc_fini(struct usbd_xfer * @@ -2844,26 +2832,28 @@ uhci_device_isoc_fini(struct usbd_xfer *
2844 struct uhci_xfer *ux __diagused = UHCI_XFER2UXFER(xfer); 2832 struct uhci_xfer *ux __diagused = UHCI_XFER2UXFER(xfer);
2845 2833
2846 KASSERT(ux->ux_type == UX_ISOC); 2834 KASSERT(ux->ux_type == UX_ISOC);
2847} 2835}
2848 2836
2849usbd_status 2837usbd_status
2850uhci_device_isoc_transfer(struct usbd_xfer *xfer) 2838uhci_device_isoc_transfer(struct usbd_xfer *xfer)
2851{ 2839{
2852 uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2840 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2853 2841
2854 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2842 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2855 DPRINTFN(5, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0); 2843 DPRINTFN(5, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0);
2856 2844
 2845 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 2846
2857 /* insert into schedule, */ 2847 /* insert into schedule, */
2858 2848
2859 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2849 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2860 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2850 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2861 struct isoc *isoc = &upipe->isoc; 2851 struct isoc *isoc = &upipe->isoc;
2862 uhci_soft_td_t *std = NULL; 2852 uhci_soft_td_t *std = NULL;
2863 uint32_t buf, len, status, offs; 2853 uint32_t buf, len, status, offs;
2864 int i, next, nframes; 2854 int i, next, nframes;
2865 int rd = UE_GET_DIR(upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN; 2855 int rd = UE_GET_DIR(upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN;
2866 2856
2867 DPRINTFN(5, "used=%jd next=%jd xfer=%#jx nframes=%jd", 2857 DPRINTFN(5, "used=%jd next=%jd xfer=%#jx nframes=%jd",
2868 isoc->inuse, isoc->next, (uintptr_t)xfer, xfer->ux_nframes); 2858 isoc->inuse, isoc->next, (uintptr_t)xfer, xfer->ux_nframes);
2869 2859
@@ -2877,27 +2867,26 @@ uhci_device_isoc_transfer(struct usbd_xf @@ -2877,27 +2867,26 @@ uhci_device_isoc_transfer(struct usbd_xf
2877 } 2867 }
2878 2868
2879#ifdef DIAGNOSTIC 2869#ifdef DIAGNOSTIC
2880 if (isoc->inuse >= UHCI_VFRAMELIST_COUNT) 2870 if (isoc->inuse >= UHCI_VFRAMELIST_COUNT)
2881 printf("%s: overflow!\n", __func__); 2871 printf("%s: overflow!\n", __func__);
2882#endif 2872#endif
2883 2873
2884 KASSERT(xfer->ux_nframes != 0); 2874 KASSERT(xfer->ux_nframes != 0);
2885 2875
2886 if (xfer->ux_length) 2876 if (xfer->ux_length)
2887 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, 2877 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
2888 rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 2878 rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
2889 2879
2890 mutex_enter(&sc->sc_lock); 
2891 next = isoc->next; 2880 next = isoc->next;
2892 if (next == -1) { 2881 if (next == -1) {
2893 /* Not in use yet, schedule it a few frames ahead. */ 2882 /* Not in use yet, schedule it a few frames ahead. */
2894 next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT; 2883 next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT;
2895 DPRINTFN(2, "start next=%jd", next, 0, 0, 0); 2884 DPRINTFN(2, "start next=%jd", next, 0, 0, 0);
2896 } 2885 }
2897 2886
2898 xfer->ux_status = USBD_IN_PROGRESS; 2887 xfer->ux_status = USBD_IN_PROGRESS;
2899 ux->ux_curframe = next; 2888 ux->ux_curframe = next;
2900 2889
2901 offs = 0; 2890 offs = 0;
2902 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) | 2891 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) |
2903 UHCI_TD_ACTIVE | 2892 UHCI_TD_ACTIVE |
@@ -2939,28 +2928,26 @@ uhci_device_isoc_transfer(struct usbd_xf @@ -2939,28 +2928,26 @@ uhci_device_isoc_transfer(struct usbd_xf
2939 isoc->next = next; 2928 isoc->next = next;
2940 isoc->inuse += xfer->ux_nframes; 2929 isoc->inuse += xfer->ux_nframes;
2941 2930
2942 /* Set up interrupt info. */ 2931 /* Set up interrupt info. */
2943 ux->ux_stdstart = std; 2932 ux->ux_stdstart = std;
2944 ux->ux_stdend = std; 2933 ux->ux_stdend = std;
2945 2934
2946 KASSERT(ux->ux_isdone); 2935 KASSERT(ux->ux_isdone);
2947#ifdef DIAGNOSTIC 2936#ifdef DIAGNOSTIC
2948 ux->ux_isdone = false; 2937 ux->ux_isdone = false;
2949#endif 2938#endif
2950 uhci_add_intr_list(sc, ux); 2939 uhci_add_intr_list(sc, ux);
2951 2940
2952 mutex_exit(&sc->sc_lock); 
2953 
2954 return USBD_IN_PROGRESS; 2941 return USBD_IN_PROGRESS;
2955} 2942}
2956 2943
2957void 2944void
2958uhci_device_isoc_abort(struct usbd_xfer *xfer) 2945uhci_device_isoc_abort(struct usbd_xfer *xfer)
2959{ 2946{
2960 uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2947 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2961 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2948 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2962 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2949 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2963 uhci_soft_td_t **stds = upipe->isoc.stds; 2950 uhci_soft_td_t **stds = upipe->isoc.stds;
2964 uhci_soft_td_t *std; 2951 uhci_soft_td_t *std;
2965 int i, n, nframes, maxlen, len; 2952 int i, n, nframes, maxlen, len;
2966 2953
@@ -3592,26 +3579,28 @@ uhci_portreset(uhci_softc_t *sc, int ind @@ -3592,26 +3579,28 @@ uhci_portreset(uhci_softc_t *sc, int ind
3592Static int 3579Static int
3593uhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 3580uhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
3594 void *buf, int buflen) 3581 void *buf, int buflen)
3595{ 3582{
3596 uhci_softc_t *sc = UHCI_BUS2SC(bus); 3583 uhci_softc_t *sc = UHCI_BUS2SC(bus);
3597 int port, x; 3584 int port, x;
3598 int status, change, totlen = 0; 3585 int status, change, totlen = 0;
3599 uint16_t len, value, index; 3586 uint16_t len, value, index;
3600 usb_port_status_t ps; 3587 usb_port_status_t ps;
3601 usbd_status err; 3588 usbd_status err;
3602 3589
3603 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3590 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3604 3591
 3592 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
 3593
3605 if (sc->sc_dying) 3594 if (sc->sc_dying)
3606 return -1; 3595 return -1;
3607 3596
3608 DPRINTF("type=0x%02jx request=%02jx", req->bmRequestType, 3597 DPRINTF("type=0x%02jx request=%02jx", req->bmRequestType,
3609 req->bRequest, 0, 0); 3598 req->bRequest, 0, 0);
3610 3599
3611 len = UGETW(req->wLength); 3600 len = UGETW(req->wLength);
3612 value = UGETW(req->wValue); 3601 value = UGETW(req->wValue);
3613 index = UGETW(req->wIndex); 3602 index = UGETW(req->wIndex);
3614 3603
3615#define C(x,y) ((x) | ((y) << 8)) 3604#define C(x,y) ((x) | ((y) << 8))
3616 switch (C(req->bRequest, req->bmRequestType)) { 3605 switch (C(req->bRequest, req->bmRequestType)) {
3617 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 3606 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
@@ -3843,50 +3832,45 @@ uhci_root_intr_transfer(struct usbd_xfer @@ -3843,50 +3832,45 @@ uhci_root_intr_transfer(struct usbd_xfer
3843{ 3832{
3844 3833
3845 /* Pipe isn't running, start first */ 3834 /* Pipe isn't running, start first */
3846 return uhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 3835 return uhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
3847} 3836}
3848 3837
3849/* Start a transfer on the root interrupt pipe */ 3838/* Start a transfer on the root interrupt pipe */
3850usbd_status 3839usbd_status
3851uhci_root_intr_start(struct usbd_xfer *xfer) 3840uhci_root_intr_start(struct usbd_xfer *xfer)
3852{ 3841{
3853 struct usbd_pipe *pipe = xfer->ux_pipe; 3842 struct usbd_pipe *pipe = xfer->ux_pipe;
3854 uhci_softc_t *sc = UHCI_PIPE2SC(pipe); 3843 uhci_softc_t *sc = UHCI_PIPE2SC(pipe);
3855 unsigned int ival; 3844 unsigned int ival;
3856 const bool polling = sc->sc_bus.ub_usepolling; 
3857 3845
3858 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3846 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3859 DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length, 3847 DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length,
3860 xfer->ux_flags, 0); 3848 xfer->ux_flags, 0);
3861 3849
 3850 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 3851
3862 if (sc->sc_dying) 3852 if (sc->sc_dying)
3863 return USBD_IOERROR; 3853 return USBD_IOERROR;
3864 3854
3865 if (!polling) 
3866 mutex_enter(&sc->sc_lock); 
3867 
3868 KASSERT(sc->sc_intr_xfer == NULL); 3855 KASSERT(sc->sc_intr_xfer == NULL);
3869 3856
3870 /* XXX temporary variable needed to avoid gcc3 warning */ 3857 /* XXX temporary variable needed to avoid gcc3 warning */
3871 ival = xfer->ux_pipe->up_endpoint->ue_edesc->bInterval; 3858 ival = xfer->ux_pipe->up_endpoint->ue_edesc->bInterval;
3872 sc->sc_ival = mstohz(ival); 3859 sc->sc_ival = mstohz(ival);
3873 callout_schedule(&sc->sc_poll_handle, sc->sc_ival); 3860 callout_schedule(&sc->sc_poll_handle, sc->sc_ival);
3874 sc->sc_intr_xfer = xfer; 3861 sc->sc_intr_xfer = xfer;
3875 xfer->ux_status = USBD_IN_PROGRESS; 3862 xfer->ux_status = USBD_IN_PROGRESS;
3876 3863
3877 if (!polling) 
3878 mutex_exit(&sc->sc_lock); 
3879 
3880 return USBD_IN_PROGRESS; 3864 return USBD_IN_PROGRESS;
3881} 3865}
3882 3866
3883/* Close the root interrupt pipe. */ 3867/* Close the root interrupt pipe. */
3884void 3868void
3885uhci_root_intr_close(struct usbd_pipe *pipe) 3869uhci_root_intr_close(struct usbd_pipe *pipe)
3886{ 3870{
3887 uhci_softc_t *sc __diagused = UHCI_PIPE2SC(pipe); 3871 uhci_softc_t *sc __diagused = UHCI_PIPE2SC(pipe);
3888 UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3872 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3889 3873
3890 KASSERT(mutex_owned(&sc->sc_lock)); 3874 KASSERT(mutex_owned(&sc->sc_lock));
3891 3875
3892 /* 3876 /*

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

--- src/sys/dev/usb/usbdi.c 2022/03/03 06:09:57 1.230
+++ src/sys/dev/usb/usbdi.c 2022/03/03 06:12:11 1.231
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: usbdi.c,v 1.230 2022/03/03 06:09:57 riastradh Exp $ */ 1/* $NetBSD: usbdi.c,v 1.231 2022/03/03 06:12:11 riastradh 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.230 2022/03/03 06:09:57 riastradh Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.231 2022/03/03 06:12:11 riastradh 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>
@@ -412,33 +412,34 @@ usbd_transfer(struct usbd_xfer *xfer) @@ -412,33 +412,34 @@ usbd_transfer(struct usbd_xfer *xfer)
412 /* xfer is not valid after the transfer method unless synchronous */ 412 /* xfer is not valid after the transfer method unless synchronous */
413 SDT_PROBE2(usb, device, pipe, transfer__start, pipe, xfer); 413 SDT_PROBE2(usb, device, pipe, transfer__start, pipe, xfer);
414 do { 414 do {
415#ifdef DIAGNOSTIC 415#ifdef DIAGNOSTIC
416 xfer->ux_state = XFER_ONQU; 416 xfer->ux_state = XFER_ONQU;
417#endif 417#endif
418 SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next); 418 SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next);
419 if (pipe->up_running && pipe->up_serialise) { 419 if (pipe->up_running && pipe->up_serialise) {
420 err = USBD_IN_PROGRESS; 420 err = USBD_IN_PROGRESS;
421 } else { 421 } else {
422 pipe->up_running = 1; 422 pipe->up_running = 1;
423 err = USBD_NORMAL_COMPLETION; 423 err = USBD_NORMAL_COMPLETION;
424 } 424 }
425 usbd_unlock_pipe(pipe); 
426 if (err) 425 if (err)
427 break; 426 break;
428 err = pipe->up_methods->upm_transfer(xfer); 427 err = pipe->up_methods->upm_transfer(xfer);
429 } while (0); 428 } while (0);
430 SDT_PROBE3(usb, device, pipe, transfer__done, pipe, xfer, err); 429 SDT_PROBE3(usb, device, pipe, transfer__done, pipe, xfer, err);
431 430
 431 usbd_unlock_pipe(pipe);
 432
432 if (err != USBD_IN_PROGRESS && err) { 433 if (err != USBD_IN_PROGRESS && err) {
433 /* 434 /*
434 * The transfer made it onto the pipe queue, but didn't get 435 * The transfer made it onto the pipe queue, but didn't get
435 * accepted by the HCD for some reason. It needs removing 436 * accepted by the HCD for some reason. It needs removing
436 * from the pipe queue. 437 * from the pipe queue.
437 */ 438 */
438 USBHIST_LOG(usbdebug, "xfer failed: %jd, reinserting", 439 USBHIST_LOG(usbdebug, "xfer failed: %jd, reinserting",
439 err, 0, 0, 0); 440 err, 0, 0, 0);
440 usbd_lock_pipe(pipe); 441 usbd_lock_pipe(pipe);
441 SDT_PROBE1(usb, device, xfer, preabort, xfer); 442 SDT_PROBE1(usb, device, xfer, preabort, xfer);
442#ifdef DIAGNOSTIC 443#ifdef DIAGNOSTIC
443 xfer->ux_state = XFER_BUSY; 444 xfer->ux_state = XFER_BUSY;
444#endif 445#endif
@@ -1180,32 +1181,28 @@ usbd_start_next(struct usbd_pipe *pipe) @@ -1180,32 +1181,28 @@ usbd_start_next(struct usbd_pipe *pipe)
1180 KASSERT(pipe->up_methods->upm_start != NULL); 1181 KASSERT(pipe->up_methods->upm_start != NULL);
1181 KASSERT(pipe->up_serialise == true); 1182 KASSERT(pipe->up_serialise == true);
1182 1183
1183 int polling = pipe->up_dev->ud_bus->ub_usepolling; 1184 int polling = pipe->up_dev->ud_bus->ub_usepolling;
1184 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 1185 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1185 1186
1186 /* Get next request in queue. */ 1187 /* Get next request in queue. */
1187 xfer = SIMPLEQ_FIRST(&pipe->up_queue); 1188 xfer = SIMPLEQ_FIRST(&pipe->up_queue);
1188 USBHIST_CALLARGS(usbdebug, "pipe = %#jx, xfer = %#jx", (uintptr_t)pipe, 1189 USBHIST_CALLARGS(usbdebug, "pipe = %#jx, xfer = %#jx", (uintptr_t)pipe,
1189 (uintptr_t)xfer, 0, 0); 1190 (uintptr_t)xfer, 0, 0);
1190 if (xfer == NULL) { 1191 if (xfer == NULL) {
1191 pipe->up_running = 0; 1192 pipe->up_running = 0;
1192 } else { 1193 } else {
1193 if (!polling) 
1194 mutex_exit(pipe->up_dev->ud_bus->ub_lock); 
1195 SDT_PROBE2(usb, device, pipe, start, pipe, xfer); 1194 SDT_PROBE2(usb, device, pipe, start, pipe, xfer);
1196 err = pipe->up_methods->upm_start(xfer); 1195 err = pipe->up_methods->upm_start(xfer);
1197 if (!polling) 
1198 mutex_enter(pipe->up_dev->ud_bus->ub_lock); 
1199 1196
1200 if (err != USBD_IN_PROGRESS) { 1197 if (err != USBD_IN_PROGRESS) {
1201 USBHIST_LOG(usbdebug, "error = %jd", err, 0, 0, 0); 1198 USBHIST_LOG(usbdebug, "error = %jd", err, 0, 0, 0);
1202 pipe->up_running = 0; 1199 pipe->up_running = 0;
1203 /* XXX do what? */ 1200 /* XXX do what? */
1204 } 1201 }
1205 } 1202 }
1206 1203
1207 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 1204 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1208} 1205}
1209 1206
1210usbd_status 1207usbd_status
1211usbd_do_request(struct usbd_device *dev, usb_device_request_t *req, void *data) 1208usbd_do_request(struct usbd_device *dev, usb_device_request_t *req, void *data)

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

--- src/sys/dev/usb/usbdivar.h 2022/03/03 06:09:20 1.133
+++ src/sys/dev/usb/usbdivar.h 2022/03/03 06:12:11 1.134
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: usbdivar.h,v 1.133 2022/03/03 06:09:20 riastradh Exp $ */ 1/* $NetBSD: usbdivar.h,v 1.134 2022/03/03 06:12:11 riastradh 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
@@ -41,34 +41,34 @@ @@ -41,34 +41,34 @@
41 * List of hardware interface methods, and whether the lock is held 41 * List of hardware interface methods, and whether the lock is held
42 * when each is called by this module: 42 * when each is called by this module:
43 * 43 *
44 * BUS METHOD LOCK NOTES 44 * BUS METHOD LOCK NOTES
45 * ----------------------- ------- ------------------------- 45 * ----------------------- ------- -------------------------
46 * ubm_open - might want to take lock? 46 * ubm_open - might want to take lock?
47 * ubm_softint x may release/reacquire lock 47 * ubm_softint x may release/reacquire lock
48 * ubm_dopoll - might want to take lock? 48 * ubm_dopoll - might want to take lock?
49 * ubm_allocx - 49 * ubm_allocx -
50 * ubm_freex - 50 * ubm_freex -
51 * ubm_abortx x must not release/reacquire lock 51 * ubm_abortx x must not release/reacquire lock
52 * ubm_getlock - Called at attach time 52 * ubm_getlock - Called at attach time
53 * ubm_newdev - Will take lock 53 * ubm_newdev - Will take lock
54 * ubm_rhctrl 54 * ubm_rhctrl x
55 * 55 *
56 * PIPE METHOD LOCK NOTES 56 * PIPE METHOD LOCK NOTES
57 * ----------------------- ------- ------------------------- 57 * ----------------------- ------- -------------------------
58 * upm_init - 58 * upm_init -
59 * upm_fini - 59 * upm_fini -
60 * upm_transfer - 60 * upm_transfer x
61 * upm_start - might want to take lock? 61 * upm_start x
62 * upm_abort x 62 * upm_abort x
63 * upm_close x 63 * upm_close x
64 * upm_cleartoggle - 64 * upm_cleartoggle -
65 * upm_done x 65 * upm_done x
66 * 66 *
67 * The above semantics are likely to change. Little performance 67 * The above semantics are likely to change. Little performance
68 * evaluation has been done on this code and the locking strategy. 68 * evaluation has been done on this code and the locking strategy.
69 * 69 *
70 * USB functions known to expect the lock taken include (this list is 70 * USB functions known to expect the lock taken include (this list is
71 * probably not exhaustive): 71 * probably not exhaustive):
72 * usb_transfer_complete() 72 * usb_transfer_complete()
73 * usb_start_next() 73 * usb_start_next()
74 * 74 *

cvs diff -r1.12 -r1.13 src/sys/dev/usb/usbroothub.c (expand / switch to unified diff)

--- src/sys/dev/usb/usbroothub.c 2022/03/03 06:04:31 1.12
+++ src/sys/dev/usb/usbroothub.c 2022/03/03 06:12:11 1.13
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: usbroothub.c,v 1.12 2022/03/03 06:04:31 riastradh Exp $ */ 1/* $NetBSD: usbroothub.c,v 1.13 2022/03/03 06:12:11 riastradh 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 * Matthew R. Green (mrg@eterna.com.au) and Nick Hudson. 10 * Matthew R. Green (mrg@eterna.com.au) 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:
@@ -48,27 +48,27 @@ @@ -48,27 +48,27 @@
48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 50 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
51 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 51 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 55 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
56 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 * 57 *
58 */ 58 */
59 59
60#include <sys/cdefs.h> 60#include <sys/cdefs.h>
61__KERNEL_RCSID(0, "$NetBSD: usbroothub.c,v 1.12 2022/03/03 06:04:31 riastradh Exp $"); 61__KERNEL_RCSID(0, "$NetBSD: usbroothub.c,v 1.13 2022/03/03 06:12:11 riastradh Exp $");
62 62
63#include <sys/param.h> 63#include <sys/param.h>
64#include <sys/systm.h> /* for ostype */ 64#include <sys/systm.h> /* for ostype */
65 65
66#include <dev/usb/usb.h> 66#include <dev/usb/usb.h>
67#include <dev/usb/usbdi.h> 67#include <dev/usb/usbdi.h>
68#include <dev/usb/usbdivar.h> 68#include <dev/usb/usbdivar.h>
69#include <dev/usb/usbroothub.h> 69#include <dev/usb/usbroothub.h>
70#include <dev/usb/usbhist.h> 70#include <dev/usb/usbhist.h>
71 71
72/* helper functions for USB root hub emulation */ 72/* helper functions for USB root hub emulation */
73 73
74static usbd_status roothub_ctrl_transfer(struct usbd_xfer *); 74static usbd_status roothub_ctrl_transfer(struct usbd_xfer *);
@@ -351,26 +351,33 @@ roothub_ctrl_transfer(struct usbd_xfer * @@ -351,26 +351,33 @@ roothub_ctrl_transfer(struct usbd_xfer *
351static usbd_status 351static usbd_status
352roothub_ctrl_start(struct usbd_xfer *xfer) 352roothub_ctrl_start(struct usbd_xfer *xfer)
353{ 353{
354 struct usbd_pipe *pipe = xfer->ux_pipe; 354 struct usbd_pipe *pipe = xfer->ux_pipe;
355 struct usbd_bus *bus = pipe->up_dev->ud_bus; 355 struct usbd_bus *bus = pipe->up_dev->ud_bus;
356 usb_device_request_t *req; 356 usb_device_request_t *req;
357 usbd_status err = USBD_IOERROR; /* XXX STALL? */ 357 usbd_status err = USBD_IOERROR; /* XXX STALL? */
358 uint16_t len, value; 358 uint16_t len, value;
359 int buflen, actlen = -1; 359 int buflen, actlen = -1;
360 void *buf; 360 void *buf;
361 361
362 USBHIST_FUNC(); 362 USBHIST_FUNC();
363 363
 364 /*
 365 * XXX Should really assert pipe lock, in case ever have
 366 * per-pipe locking instead of using the bus lock for all
 367 * pipes.
 368 */
 369 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
 370
364 KASSERT(xfer->ux_rqflags & URQ_REQUEST); 371 KASSERT(xfer->ux_rqflags & URQ_REQUEST);
365 req = &xfer->ux_request; 372 req = &xfer->ux_request;
366 373
367 len = UGETW(req->wLength); 374 len = UGETW(req->wLength);
368 value = UGETW(req->wValue); 375 value = UGETW(req->wValue);
369 376
370 USBHIST_CALLARGS(usbdebug, "type=%#jx request=%#jx len=%#jx value=%#jx", 377 USBHIST_CALLARGS(usbdebug, "type=%#jx request=%#jx len=%#jx value=%#jx",
371 req->bmRequestType, req->bRequest, len, value); 378 req->bmRequestType, req->bRequest, len, value);
372 379
373 buf = len ? usbd_get_buffer(xfer) : NULL; 380 buf = len ? usbd_get_buffer(xfer) : NULL;
374 buflen = 0; 381 buflen = 0;
375 382
376#define C(x,y) ((x) | ((y) << 8)) 383#define C(x,y) ((x) | ((y) << 8))
@@ -544,29 +551,27 @@ roothub_ctrl_start(struct usbd_xfer *xfe @@ -544,29 +551,27 @@ roothub_ctrl_start(struct usbd_xfer *xfe
544 551
545 actlen = bus->ub_methods->ubm_rhctrl(bus, req, buf, buflen); 552 actlen = bus->ub_methods->ubm_rhctrl(bus, req, buf, buflen);
546 if (actlen < 0) 553 if (actlen < 0)
547 goto fail; 554 goto fail;
548 555
549 xfer->ux_actlen = actlen; 556 xfer->ux_actlen = actlen;
550 err = USBD_NORMAL_COMPLETION; 557 err = USBD_NORMAL_COMPLETION;
551 558
552 fail: 559 fail:
553 USBHIST_LOG(usbdebug, "xfer %#jx buflen %jd actlen %jd err %jd", 560 USBHIST_LOG(usbdebug, "xfer %#jx buflen %jd actlen %jd err %jd",
554 (uintptr_t)xfer, buflen, actlen, err); 561 (uintptr_t)xfer, buflen, actlen, err);
555 562
556 xfer->ux_status = err; 563 xfer->ux_status = err;
557 mutex_enter(bus->ub_lock); 
558 usb_transfer_complete(xfer); 564 usb_transfer_complete(xfer);
559 mutex_exit(bus->ub_lock); 
560 565
561 return USBD_NORMAL_COMPLETION; 566 return USBD_NORMAL_COMPLETION;
562} 567}
563 568
564/* Abort a root control request. */ 569/* Abort a root control request. */
565Static void 570Static void
566roothub_ctrl_abort(struct usbd_xfer *xfer) 571roothub_ctrl_abort(struct usbd_xfer *xfer)
567{ 572{
568 573
569 /* Nothing to do, all transfers are synchronous. */ 574 /* Nothing to do, all transfers are synchronous. */
570} 575}
571 576
572/* Close the root pipe. */ 577/* Close the root pipe. */

cvs diff -r1.24 -r1.25 src/sys/dev/usb/vhci.c (expand / switch to unified diff)

--- src/sys/dev/usb/vhci.c 2022/03/03 06:04:31 1.24
+++ src/sys/dev/usb/vhci.c 2022/03/03 06:12:11 1.25
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vhci.c,v 1.24 2022/03/03 06:04:31 riastradh Exp $ */ 1/* $NetBSD: vhci.c,v 1.25 2022/03/03 06:12:11 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2019-2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 2019-2020 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 Maxime Villard. 8 * by Maxime Villard.
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: vhci.c,v 1.24 2022/03/03 06:04:31 riastradh Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: vhci.c,v 1.25 2022/03/03 06:12:11 riastradh Exp $");
34 34
35#ifdef _KERNEL_OPT 35#ifdef _KERNEL_OPT
36#include "opt_usb.h" 36#include "opt_usb.h"
37#endif 37#endif
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40 40
41#include <sys/bus.h> 41#include <sys/bus.h>
42#include <sys/cpu.h> 42#include <sys/cpu.h>
43#include <sys/conf.h> 43#include <sys/conf.h>
44#include <sys/device.h> 44#include <sys/device.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/kmem.h> 46#include <sys/kmem.h>
@@ -595,60 +595,55 @@ vhci_device_ctrl_transfer(struct usbd_xf @@ -595,60 +595,55 @@ vhci_device_ctrl_transfer(struct usbd_xf
595 595
596 /* Pipe isn't running, start first */ 596 /* Pipe isn't running, start first */
597 return vhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 597 return vhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
598} 598}
599 599
600static usbd_status 600static usbd_status
601vhci_device_ctrl_start(struct usbd_xfer *xfer) 601vhci_device_ctrl_start(struct usbd_xfer *xfer)
602{ 602{
603 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; 603 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc;
604 usb_device_request_t *req = &xfer->ux_request; 604 usb_device_request_t *req = &xfer->ux_request;
605 struct usbd_device *dev = xfer->ux_pipe->up_dev; 605 struct usbd_device *dev = xfer->ux_pipe->up_dev;
606 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 606 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
607 vhci_port_t *port; 607 vhci_port_t *port;
608 bool polling = sc->sc_bus.ub_usepolling; 
609 bool isread = (req->bmRequestType & UT_READ) != 0; 608 bool isread = (req->bmRequestType & UT_READ) != 0;
610 uint8_t addr = UE_GET_ADDR(ed->bEndpointAddress); 609 uint8_t addr = UE_GET_ADDR(ed->bEndpointAddress);
611 int portno, ret; 610 int portno, ret;
612 611
613 KASSERT(addr == 0); 612 KASSERT(addr == 0);
614 KASSERT(xfer->ux_rqflags & URQ_REQUEST); 613 KASSERT(xfer->ux_rqflags & URQ_REQUEST);
615 KASSERT(dev->ud_myhsport != NULL); 614 KASSERT(dev->ud_myhsport != NULL);
616 portno = dev->ud_myhsport->up_portno; 615 portno = dev->ud_myhsport->up_portno;
617 616
618 DPRINTF("%s: type=0x%02x, len=%d, isread=%d, portno=%d\n", 617 DPRINTF("%s: type=0x%02x, len=%d, isread=%d, portno=%d\n",
619 __func__, req->bmRequestType, UGETW(req->wLength), isread, portno); 618 __func__, req->bmRequestType, UGETW(req->wLength), isread, portno);
620 619
 620 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 621
621 if (sc->sc_dying) 622 if (sc->sc_dying)
622 return USBD_IOERROR; 623 return USBD_IOERROR;
623 624
624 port = &sc->sc_port[portno]; 625 port = &sc->sc_port[portno];
625 626
626 if (!polling) 
627 mutex_enter(&sc->sc_lock); 
628 
629 mutex_enter(&port->lock); 627 mutex_enter(&port->lock);
630 if (port->status & UPS_PORT_ENABLED) { 628 if (port->status & UPS_PORT_ENABLED) {
631 xfer->ux_status = USBD_IN_PROGRESS; 629 xfer->ux_status = USBD_IN_PROGRESS;
632 vhci_pkt_ctrl_create(port, xfer, isread, addr); 630 vhci_pkt_ctrl_create(port, xfer, isread, addr);
633 ret = USBD_IN_PROGRESS; 631 ret = USBD_IN_PROGRESS;
634 } else { 632 } else {
635 ret = USBD_IOERROR; 633 ret = USBD_IOERROR;
636 } 634 }
637 mutex_exit(&port->lock); 635 mutex_exit(&port->lock);
638 636
639 if (!polling) 
640 mutex_exit(&sc->sc_lock); 
641 
642 return ret; 637 return ret;
643} 638}
644 639
645static void 640static void
646vhci_device_ctrl_abort(struct usbd_xfer *xfer) 641vhci_device_ctrl_abort(struct usbd_xfer *xfer)
647{ 642{
648 vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer; 643 vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer;
649 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 644 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
650 vhci_port_t *port = vxfer->port; 645 vhci_port_t *port = vxfer->port;
651 vhci_packet_t *pkt; 646 vhci_packet_t *pkt;
652 647
653 DPRINTF("%s: called\n", __func__); 648 DPRINTF("%s: called\n", __func__);
654 649
@@ -699,40 +694,37 @@ static usbd_status @@ -699,40 +694,37 @@ static usbd_status
699vhci_root_intr_transfer(struct usbd_xfer *xfer) 694vhci_root_intr_transfer(struct usbd_xfer *xfer)
700{ 695{
701 696
702 DPRINTF("%s: called\n", __func__); 697 DPRINTF("%s: called\n", __func__);
703 698
704 /* Pipe isn't running, start first */ 699 /* Pipe isn't running, start first */
705 return vhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 700 return vhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
706} 701}
707 702
708static usbd_status 703static usbd_status
709vhci_root_intr_start(struct usbd_xfer *xfer) 704vhci_root_intr_start(struct usbd_xfer *xfer)
710{ 705{
711 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 706 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
712 const bool polling = sc->sc_bus.ub_usepolling; 
713 707
714 DPRINTF("%s: called, len=%zu\n", __func__, (size_t)xfer->ux_length); 708 DPRINTF("%s: called, len=%zu\n", __func__, (size_t)xfer->ux_length);
715 709
 710 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 711
716 if (sc->sc_dying) 712 if (sc->sc_dying)
717 return USBD_IOERROR; 713 return USBD_IOERROR;
718 714
719 if (!polling) 
720 mutex_enter(&sc->sc_lock); 
721 KASSERT(sc->sc_intrxfer == NULL); 715 KASSERT(sc->sc_intrxfer == NULL);
722 sc->sc_intrxfer = xfer; 716 sc->sc_intrxfer = xfer;
723 xfer->ux_status = USBD_IN_PROGRESS; 717 xfer->ux_status = USBD_IN_PROGRESS;
724 if (!polling) 
725 mutex_exit(&sc->sc_lock); 
726 718
727 return USBD_IN_PROGRESS; 719 return USBD_IN_PROGRESS;
728} 720}
729 721
730static void 722static void
731vhci_root_intr_abort(struct usbd_xfer *xfer) 723vhci_root_intr_abort(struct usbd_xfer *xfer)
732{ 724{
733 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 725 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
734 726
735 DPRINTF("%s: called\n", __func__); 727 DPRINTF("%s: called\n", __func__);
736 728
737 KASSERT(mutex_owned(&sc->sc_lock)); 729 KASSERT(mutex_owned(&sc->sc_lock));
738 KASSERT(xfer->ux_pipe->up_intrxfer == xfer); 730 KASSERT(xfer->ux_pipe->up_intrxfer == xfer);

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

--- src/sys/dev/usb/xhci.c 2022/03/03 06:08:50 1.157
+++ src/sys/dev/usb/xhci.c 2022/03/03 06:12:11 1.158
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xhci.c,v 1.157 2022/03/03 06:08:50 riastradh Exp $ */ 1/* $NetBSD: xhci.c,v 1.158 2022/03/03 06:12:11 riastradh 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.157 2022/03/03 06:08:50 riastradh Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.158 2022/03/03 06:12:11 riastradh 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>
@@ -2176,27 +2176,26 @@ xhci_host_dequeue(struct xhci_ring * con @@ -2176,27 +2176,26 @@ xhci_host_dequeue(struct xhci_ring * con
2176 * Issue RESET_EP to recover halt condition and SET_TR_DEQUEUE to remove 2176 * Issue RESET_EP to recover halt condition and SET_TR_DEQUEUE to remove
2177 * all transfers on transfer ring. 2177 * all transfers on transfer ring.
2178 * These are done in thread context asynchronously. 2178 * These are done in thread context asynchronously.
2179 */ 2179 */
2180static void 2180static void
2181xhci_pipe_async_task(void *cookie) 2181xhci_pipe_async_task(void *cookie)
2182{ 2182{
2183 struct xhci_pipe * const xp = cookie; 2183 struct xhci_pipe * const xp = cookie;
2184 struct usbd_pipe * const pipe = &xp->xp_pipe; 2184 struct usbd_pipe * const pipe = &xp->xp_pipe;
2185 struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); 2185 struct xhci_softc * const sc = XHCI_PIPE2SC(pipe);
2186 struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; 2186 struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv;
2187 const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); 2187 const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc);
2188 struct xhci_ring * const tr = xs->xs_xr[dci]; 2188 struct xhci_ring * const tr = xs->xs_xr[dci];
2189 bool restart = false; 
2190 2189
2191 XHCIHIST_FUNC(); 2190 XHCIHIST_FUNC();
2192 XHCIHIST_CALLARGS("pipe %#jx slot %ju dci %ju", 2191 XHCIHIST_CALLARGS("pipe %#jx slot %ju dci %ju",
2193 (uintptr_t)pipe, xs->xs_idx, dci, 0); 2192 (uintptr_t)pipe, xs->xs_idx, dci, 0);
2194 2193
2195 mutex_enter(&sc->sc_lock); 2194 mutex_enter(&sc->sc_lock);
2196 2195
2197 /* 2196 /*
2198 * - If the endpoint is halted, indicating a stall, reset it. 2197 * - If the endpoint is halted, indicating a stall, reset it.
2199 * - If the endpoint is stopped, we're already good. 2198 * - If the endpoint is stopped, we're already good.
2200 * - Otherwise, someone wanted to abort the pipe, so stop the 2199 * - Otherwise, someone wanted to abort the pipe, so stop the
2201 * endpoint. 2200 * endpoint.
2202 * 2201 *
@@ -2217,51 +2216,38 @@ xhci_pipe_async_task(void *cookie) @@ -2217,51 +2216,38 @@ xhci_pipe_async_task(void *cookie)
2217 break; 2216 break;
2218 case XHCI_EPSTATE_ERROR: 2217 case XHCI_EPSTATE_ERROR:
2219 device_printf(sc->sc_dev, "endpoint 0x%x error\n", 2218 device_printf(sc->sc_dev, "endpoint 0x%x error\n",
2220 pipe->up_endpoint->ue_edesc->bEndpointAddress); 2219 pipe->up_endpoint->ue_edesc->bEndpointAddress);
2221 break; 2220 break;
2222 default: 2221 default:
2223 device_printf(sc->sc_dev, "endpoint 0x%x failed to stop\n", 2222 device_printf(sc->sc_dev, "endpoint 0x%x failed to stop\n",
2224 pipe->up_endpoint->ue_edesc->bEndpointAddress); 2223 pipe->up_endpoint->ue_edesc->bEndpointAddress);
2225 } 2224 }
2226 xhci_set_dequeue(pipe); 2225 xhci_set_dequeue(pipe);
2227 2226
2228 /* 2227 /*
2229 * If we halted our own queue because it stalled, mark it no 2228 * If we halted our own queue because it stalled, mark it no
2230 * longer halted and arrange to start it up again. 2229 * longer halted and start issuing queued transfers again.
2231 */ 2230 */
2232 if (tr->is_halted) { 2231 if (tr->is_halted) {
 2232 struct usbd_xfer *xfer = SIMPLEQ_FIRST(&pipe->up_queue);
 2233
2233 tr->is_halted = false; 2234 tr->is_halted = false;
2234 if (!SIMPLEQ_EMPTY(&pipe->up_queue)) 2235 if (xfer)
2235 restart = true; 2236 (*pipe->up_methods->upm_start)(xfer);
2236 } 2237 }
2237 2238
2238 mutex_exit(&sc->sc_lock); 2239 mutex_exit(&sc->sc_lock);
2239 2240
2240 /* 
2241 * If the endpoint was stalled, start issuing queued transfers 
2242 * again. 
2243 */ 
2244 if (restart) { 
2245 /* 
2246 * XXX Shouldn't touch the queue unlocked -- upm_start 
2247 * should be called with the lock held instead. The 
2248 * pipe could be aborted at this point, and the xfer 
2249 * freed. 
2250 */ 
2251 struct usbd_xfer *xfer = SIMPLEQ_FIRST(&pipe->up_queue); 
2252 (*pipe->up_methods->upm_start)(xfer); 
2253 } 
2254 
2255 DPRINTFN(4, "ends", 0, 0, 0, 0); 2241 DPRINTFN(4, "ends", 0, 0, 0, 0);
2256} 2242}
2257 2243
2258static void 2244static void
2259xhci_pipe_restart(struct usbd_pipe *pipe) 2245xhci_pipe_restart(struct usbd_pipe *pipe)
2260{ 2246{
2261 struct xhci_pipe * const xp = 2247 struct xhci_pipe * const xp =
2262 container_of(pipe, struct xhci_pipe, xp_pipe); 2248 container_of(pipe, struct xhci_pipe, xp_pipe);
2263 2249
2264 XHCIHIST_FUNC(); 2250 XHCIHIST_FUNC();
2265 XHCIHIST_CALLARGS("pipe %#jx", (uintptr_t)pipe, 0, 0, 0); 2251 XHCIHIST_CALLARGS("pipe %#jx", (uintptr_t)pipe, 0, 0, 0);
2266 2252
2267 usb_add_task(pipe->up_dev, &xp->xp_async_task, USB_TASKQ_HC); 2253 usb_add_task(pipe->up_dev, &xp->xp_async_task, USB_TASKQ_HC);
@@ -3860,26 +3846,28 @@ xhci_noop(struct usbd_pipe *pipe) @@ -3860,26 +3846,28 @@ xhci_noop(struct usbd_pipe *pipe)
3860static int 3846static int
3861xhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 3847xhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
3862 void *buf, int buflen) 3848 void *buf, int buflen)
3863{ 3849{
3864 struct xhci_softc * const sc = XHCI_BUS2SC(bus); 3850 struct xhci_softc * const sc = XHCI_BUS2SC(bus);
3865 usb_port_status_t ps; 3851 usb_port_status_t ps;
3866 int l, totlen = 0; 3852 int l, totlen = 0;
3867 uint16_t len, value, index; 3853 uint16_t len, value, index;
3868 int port, i; 3854 int port, i;
3869 uint32_t v; 3855 uint32_t v;
3870 3856
3871 XHCIHIST_FUNC(); 3857 XHCIHIST_FUNC();
3872 3858
 3859 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
 3860
3873 if (sc->sc_dying) 3861 if (sc->sc_dying)
3874 return -1; 3862 return -1;
3875 3863
3876 size_t bn = bus == &sc->sc_bus ? 0 : 1; 3864 size_t bn = bus == &sc->sc_bus ? 0 : 1;
3877 3865
3878 len = UGETW(req->wLength); 3866 len = UGETW(req->wLength);
3879 value = UGETW(req->wValue); 3867 value = UGETW(req->wValue);
3880 index = UGETW(req->wIndex); 3868 index = UGETW(req->wIndex);
3881 3869
3882 XHCIHIST_CALLARGS("rhreq: %04jx %04jx %04jx %04jx", 3870 XHCIHIST_CALLARGS("rhreq: %04jx %04jx %04jx %04jx",
3883 req->bmRequestType | (req->bRequest << 8), value, index, len); 3871 req->bmRequestType | (req->bRequest << 8), value, index, len);
3884 3872
3885#define C(x,y) ((x) | ((y) << 8)) 3873#define C(x,y) ((x) | ((y) << 8))
@@ -4129,40 +4117,37 @@ xhci_root_intr_transfer(struct usbd_xfer @@ -4129,40 +4117,37 @@ xhci_root_intr_transfer(struct usbd_xfer
4129{ 4117{
4130 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 4118 XHCIHIST_FUNC(); XHCIHIST_CALLED();
4131 4119
4132 /* Pipe isn't running, start first */ 4120 /* Pipe isn't running, start first */
4133 return xhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 4121 return xhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
4134} 4122}
4135 4123
4136/* Wait for roothub port status/change */ 4124/* Wait for roothub port status/change */
4137static usbd_status 4125static usbd_status
4138xhci_root_intr_start(struct usbd_xfer *xfer) 4126xhci_root_intr_start(struct usbd_xfer *xfer)
4139{ 4127{
4140 struct xhci_softc * const sc = XHCI_XFER2SC(xfer); 4128 struct xhci_softc * const sc = XHCI_XFER2SC(xfer);
4141 const size_t bn = XHCI_XFER2BUS(xfer) == &sc->sc_bus ? 0 : 1; 4129 const size_t bn = XHCI_XFER2BUS(xfer) == &sc->sc_bus ? 0 : 1;
4142 const bool polling = xhci_polling_p(sc); 
4143 4130
4144 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 4131 XHCIHIST_FUNC(); XHCIHIST_CALLED();
4145 4132
 4133 KASSERT(xhci_polling_p(sc) || mutex_owned(&sc->sc_lock));
 4134
4146 if (sc->sc_dying) 4135 if (sc->sc_dying)
4147 return USBD_IOERROR; 4136 return USBD_IOERROR;
4148 4137
4149 if (!polling) 
4150 mutex_enter(&sc->sc_lock); 
4151 KASSERT(sc->sc_intrxfer[bn] == NULL); 4138 KASSERT(sc->sc_intrxfer[bn] == NULL);
4152 sc->sc_intrxfer[bn] = xfer; 4139 sc->sc_intrxfer[bn] = xfer;
4153 xfer->ux_status = USBD_IN_PROGRESS; 4140 xfer->ux_status = USBD_IN_PROGRESS;
4154 if (!polling) 
4155 mutex_exit(&sc->sc_lock); 
4156 4141
4157 return USBD_IN_PROGRESS; 4142 return USBD_IN_PROGRESS;
4158} 4143}
4159 4144
4160static void 4145static void
4161xhci_root_intr_abort(struct usbd_xfer *xfer) 4146xhci_root_intr_abort(struct usbd_xfer *xfer)
4162{ 4147{
4163 struct xhci_softc * const sc = XHCI_XFER2SC(xfer); 4148 struct xhci_softc * const sc = XHCI_XFER2SC(xfer);
4164 const size_t bn = XHCI_XFER2BUS(xfer) == &sc->sc_bus ? 0 : 1; 4149 const size_t bn = XHCI_XFER2BUS(xfer) == &sc->sc_bus ? 0 : 1;
4165 4150
4166 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 4151 XHCIHIST_FUNC(); XHCIHIST_CALLED();
4167 4152
4168 KASSERT(mutex_owned(&sc->sc_lock)); 4153 KASSERT(mutex_owned(&sc->sc_lock));
@@ -4240,34 +4225,34 @@ xhci_device_ctrl_start(struct usbd_xfer  @@ -4240,34 +4225,34 @@ xhci_device_ctrl_start(struct usbd_xfer
4240 const uint32_t len = UGETW(req->wLength); 4225 const uint32_t len = UGETW(req->wLength);
4241 usb_dma_t * const dma = &xfer->ux_dmabuf; 4226 usb_dma_t * const dma = &xfer->ux_dmabuf;
4242 uint64_t parameter; 4227 uint64_t parameter;
4243 uint32_t status; 4228 uint32_t status;
4244 uint32_t control; 4229 uint32_t control;
4245 u_int i; 4230 u_int i;
4246 const bool polling = xhci_polling_p(sc); 4231 const bool polling = xhci_polling_p(sc);
4247 4232
4248 XHCIHIST_FUNC(); 4233 XHCIHIST_FUNC();
4249 XHCIHIST_CALLARGS("req: %04jx %04jx %04jx %04jx", 4234 XHCIHIST_CALLARGS("req: %04jx %04jx %04jx %04jx",
4250 req->bmRequestType | (req->bRequest << 8), UGETW(req->wValue), 4235 req->bmRequestType | (req->bRequest << 8), UGETW(req->wValue),
4251 UGETW(req->wIndex), UGETW(req->wLength)); 4236 UGETW(req->wIndex), UGETW(req->wLength));
4252 4237
 4238 KASSERT(polling || mutex_owned(&sc->sc_lock));
 4239
4253 /* we rely on the bottom bits for extra info */ 4240 /* we rely on the bottom bits for extra info */
4254 KASSERTMSG(((uintptr_t)xfer & 0x3) == 0x0, "xfer %zx", 4241 KASSERTMSG(((uintptr_t)xfer & 0x3) == 0x0, "xfer %zx",
4255 (uintptr_t) xfer); 4242 (uintptr_t) xfer);
4256 4243
4257 KASSERT((xfer->ux_rqflags & URQ_REQUEST) != 0); 4244 KASSERT((xfer->ux_rqflags & URQ_REQUEST) != 0);
4258 4245
4259 if (!polling) 
4260 mutex_enter(&sc->sc_lock); 
4261 if (tr->is_halted) 4246 if (tr->is_halted)
4262 goto out; 4247 goto out;
4263 4248
4264 i = 0; 4249 i = 0;
4265 4250
4266 /* setup phase */ 4251 /* setup phase */
4267 parameter = le64dec(req); /* to keep USB endian after xhci_trb_put() */ 4252 parameter = le64dec(req); /* to keep USB endian after xhci_trb_put() */
4268 status = XHCI_TRB_2_IRQ_SET(0) | XHCI_TRB_2_BYTES_SET(sizeof(*req)); 4253 status = XHCI_TRB_2_IRQ_SET(0) | XHCI_TRB_2_BYTES_SET(sizeof(*req));
4269 control = ((len == 0) ? XHCI_TRB_3_TRT_NONE : 4254 control = ((len == 0) ? XHCI_TRB_3_TRT_NONE :
4270 (isread ? XHCI_TRB_3_TRT_IN : XHCI_TRB_3_TRT_OUT)) | 4255 (isread ? XHCI_TRB_3_TRT_IN : XHCI_TRB_3_TRT_OUT)) |
4271 XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_SETUP_STAGE) | 4256 XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_SETUP_STAGE) |
4272 XHCI_TRB_3_IDT_BIT; 4257 XHCI_TRB_3_IDT_BIT;
4273 xhci_xfer_put_trb(xx, i++, parameter, status, control); 4258 xhci_xfer_put_trb(xx, i++, parameter, status, control);
@@ -4305,28 +4290,26 @@ xhci_device_ctrl_start(struct usbd_xfer  @@ -4305,28 +4290,26 @@ xhci_device_ctrl_start(struct usbd_xfer
4305 4290
4306 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); 4291 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci);
4307 4292
4308out: if (xfer->ux_status == USBD_NOT_STARTED) { 4293out: if (xfer->ux_status == USBD_NOT_STARTED) {
4309 usbd_xfer_schedule_timeout(xfer); 4294 usbd_xfer_schedule_timeout(xfer);
4310 xfer->ux_status = USBD_IN_PROGRESS; 4295 xfer->ux_status = USBD_IN_PROGRESS;
4311 } else { 4296 } else {
4312 /* 4297 /*
4313 * We must be coming from xhci_pipe_restart -- timeout 4298 * We must be coming from xhci_pipe_restart -- timeout
4314 * already set up, nothing to do. 4299 * already set up, nothing to do.
4315 */ 4300 */
4316 } 4301 }
4317 KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 4302 KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
4318 if (!polling) 
4319 mutex_exit(&sc->sc_lock); 
4320 4303
4321 return USBD_IN_PROGRESS; 4304 return USBD_IN_PROGRESS;
4322} 4305}
4323 4306
4324static void 4307static void
4325xhci_device_ctrl_done(struct usbd_xfer *xfer) 4308xhci_device_ctrl_done(struct usbd_xfer *xfer)
4326{ 4309{
4327 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 4310 XHCIHIST_FUNC(); XHCIHIST_CALLED();
4328 usb_device_request_t *req = &xfer->ux_request; 4311 usb_device_request_t *req = &xfer->ux_request;
4329 int len = UGETW(req->wLength); 4312 int len = UGETW(req->wLength);
4330 int rd = req->bmRequestType & UT_READ; 4313 int rd = req->bmRequestType & UT_READ;
4331 4314
4332 if (len) 4315 if (len)
@@ -4378,26 +4361,28 @@ xhci_device_isoc_enter(struct usbd_xfer  @@ -4378,26 +4361,28 @@ xhci_device_isoc_enter(struct usbd_xfer
4378 uint32_t mfindex; 4361 uint32_t mfindex;
4379 uint32_t offs; 4362 uint32_t offs;
4380 int i, ival; 4363 int i, ival;
4381 const bool polling = xhci_polling_p(sc); 4364 const bool polling = xhci_polling_p(sc);
4382 const uint16_t MPS = UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize); 4365 const uint16_t MPS = UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize);
4383 const uint16_t mps = UE_GET_SIZE(MPS); 4366 const uint16_t mps = UE_GET_SIZE(MPS);
4384 const uint8_t maxb = xpipe->xp_maxb; 4367 const uint8_t maxb = xpipe->xp_maxb;
4385 u_int tdpc, tbc, tlbpc; 4368 u_int tdpc, tbc, tlbpc;
4386 4369
4387 XHCIHIST_FUNC(); 4370 XHCIHIST_FUNC();
4388 XHCIHIST_CALLARGS("%#jx slot %ju dci %ju", 4371 XHCIHIST_CALLARGS("%#jx slot %ju dci %ju",
4389 (uintptr_t)xfer, xs->xs_idx, dci, 0); 4372 (uintptr_t)xfer, xs->xs_idx, dci, 0);
4390 4373
 4374 KASSERT(polling || mutex_owned(&sc->sc_lock));
 4375
4391 if (sc->sc_dying) 4376 if (sc->sc_dying)
4392 return USBD_IOERROR; 4377 return USBD_IOERROR;
4393 4378
4394 KASSERT(xfer->ux_nframes != 0 && xfer->ux_frlengths); 4379 KASSERT(xfer->ux_nframes != 0 && xfer->ux_frlengths);
4395 KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0); 4380 KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0);
4396 4381
4397 const bool isread = usbd_xfer_isread(xfer); 4382 const bool isread = usbd_xfer_isread(xfer);
4398 if (xfer->ux_length) 4383 if (xfer->ux_length)
4399 usb_syncmem(dma, 0, xfer->ux_length, 4384 usb_syncmem(dma, 0, xfer->ux_length,
4400 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 4385 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
4401 4386
4402 ival = xfer->ux_pipe->up_endpoint->ue_edesc->bInterval; 4387 ival = xfer->ux_pipe->up_endpoint->ue_edesc->bInterval;
4403 if (ival >= 1 && ival <= 16) 4388 if (ival >= 1 && ival <= 16)
@@ -4450,33 +4435,29 @@ xhci_device_isoc_enter(struct usbd_xfer  @@ -4450,33 +4435,29 @@ xhci_device_isoc_enter(struct usbd_xfer
4450 4435
4451 xpipe->xp_isoc_next += ival; 4436 xpipe->xp_isoc_next += ival;
4452 offs += len; 4437 offs += len;
4453 } 4438 }
4454 4439
4455 xx->xx_isoc_done = 0; 4440 xx->xx_isoc_done = 0;
4456 4441
4457 if (!polling) 4442 if (!polling)
4458 mutex_enter(&tr->xr_lock); 4443 mutex_enter(&tr->xr_lock);
4459 xhci_ring_put_xfer(sc, tr, xx, i); 4444 xhci_ring_put_xfer(sc, tr, xx, i);
4460 if (!polling) 4445 if (!polling)
4461 mutex_exit(&tr->xr_lock); 4446 mutex_exit(&tr->xr_lock);
4462 4447
4463 if (!polling) 
4464 mutex_enter(&sc->sc_lock); 
4465 xfer->ux_status = USBD_IN_PROGRESS; 4448 xfer->ux_status = USBD_IN_PROGRESS;
4466 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); 4449 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci);
4467 usbd_xfer_schedule_timeout(xfer); 4450 usbd_xfer_schedule_timeout(xfer);
4468 if (!polling) 
4469 mutex_exit(&sc->sc_lock); 
4470 4451
4471 return USBD_IN_PROGRESS; 4452 return USBD_IN_PROGRESS;
4472} 4453}
4473 4454
4474static void 4455static void
4475xhci_device_isoc_abort(struct usbd_xfer *xfer) 4456xhci_device_isoc_abort(struct usbd_xfer *xfer)
4476{ 4457{
4477 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 4458 XHCIHIST_FUNC(); XHCIHIST_CALLED();
4478 4459
4479 usbd_xfer_abort(xfer); 4460 usbd_xfer_abort(xfer);
4480} 4461}
4481 4462
4482static void 4463static void
@@ -4526,33 +4507,33 @@ xhci_device_bulk_start(struct usbd_xfer  @@ -4526,33 +4507,33 @@ xhci_device_bulk_start(struct usbd_xfer
4526 struct xhci_xfer * const xx = XHCI_XFER2XXFER(xfer); 4507 struct xhci_xfer * const xx = XHCI_XFER2XXFER(xfer);
4527 const uint32_t len = xfer->ux_length; 4508 const uint32_t len = xfer->ux_length;
4528 usb_dma_t * const dma = &xfer->ux_dmabuf; 4509 usb_dma_t * const dma = &xfer->ux_dmabuf;
4529 uint64_t parameter; 4510 uint64_t parameter;
4530 uint32_t status; 4511 uint32_t status;
4531 uint32_t control; 4512 uint32_t control;
4532 u_int i = 0; 4513 u_int i = 0;
4533 const bool polling = xhci_polling_p(sc); 4514 const bool polling = xhci_polling_p(sc);
4534 4515
4535 XHCIHIST_FUNC(); 4516 XHCIHIST_FUNC();
4536 XHCIHIST_CALLARGS("%#jx slot %ju dci %ju", 4517 XHCIHIST_CALLARGS("%#jx slot %ju dci %ju",
4537 (uintptr_t)xfer, xs->xs_idx, dci, 0); 4518 (uintptr_t)xfer, xs->xs_idx, dci, 0);
4538 4519
 4520 KASSERT(polling || mutex_owned(&sc->sc_lock));
 4521
4539 if (sc->sc_dying) 4522 if (sc->sc_dying)
4540 return USBD_IOERROR; 4523 return USBD_IOERROR;
4541 4524
4542 KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0); 4525 KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0);
4543 4526
4544 if (!polling) 
4545 mutex_enter(&sc->sc_lock); 
4546 if (tr->is_halted) 4527 if (tr->is_halted)
4547 goto out; 4528 goto out;
4548 4529
4549 parameter = DMAADDR(dma, 0); 4530 parameter = DMAADDR(dma, 0);
4550 const bool isread = usbd_xfer_isread(xfer); 4531 const bool isread = usbd_xfer_isread(xfer);
4551 if (len) 4532 if (len)
4552 usb_syncmem(dma, 0, len, 4533 usb_syncmem(dma, 0, len,
4553 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 4534 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
4554 4535
4555 /* 4536 /*
4556 * XXX: (dsl) The physical buffer must not cross a 64k boundary. 4537 * XXX: (dsl) The physical buffer must not cross a 64k boundary.
4557 * If the user supplied buffer crosses such a boundary then 2 4538 * If the user supplied buffer crosses such a boundary then 2
4558 * (or more) TRB should be used. 4539 * (or more) TRB should be used.
@@ -4580,28 +4561,26 @@ xhci_device_bulk_start(struct usbd_xfer  @@ -4580,28 +4561,26 @@ xhci_device_bulk_start(struct usbd_xfer
4580 4561
4581 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); 4562 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci);
4582 4563
4583out: if (xfer->ux_status == USBD_NOT_STARTED) { 4564out: if (xfer->ux_status == USBD_NOT_STARTED) {
4584 xfer->ux_status = USBD_IN_PROGRESS; 4565 xfer->ux_status = USBD_IN_PROGRESS;
4585 usbd_xfer_schedule_timeout(xfer); 4566 usbd_xfer_schedule_timeout(xfer);
4586 } else { 4567 } else {
4587 /* 4568 /*
4588 * We must be coming from xhci_pipe_restart -- timeout 4569 * We must be coming from xhci_pipe_restart -- timeout
4589 * already set up, nothing to do. 4570 * already set up, nothing to do.
4590 */ 4571 */
4591 } 4572 }
4592 KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 4573 KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
4593 if (!polling) 
4594 mutex_exit(&sc->sc_lock); 
4595 4574
4596 return USBD_IN_PROGRESS; 4575 return USBD_IN_PROGRESS;
4597} 4576}
4598 4577
4599static void 4578static void
4600xhci_device_bulk_done(struct usbd_xfer *xfer) 4579xhci_device_bulk_done(struct usbd_xfer *xfer)
4601{ 4580{
4602#ifdef USB_DEBUG 4581#ifdef USB_DEBUG
4603 struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; 4582 struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv;
4604 const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); 4583 const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc);
4605#endif 4584#endif
4606 const bool isread = usbd_xfer_isread(xfer); 4585 const bool isread = usbd_xfer_isread(xfer);
4607 4586
@@ -4651,31 +4630,31 @@ xhci_device_intr_start(struct usbd_xfer  @@ -4651,31 +4630,31 @@ xhci_device_intr_start(struct usbd_xfer
4651 struct xhci_xfer * const xx = XHCI_XFER2XXFER(xfer); 4630 struct xhci_xfer * const xx = XHCI_XFER2XXFER(xfer);
4652 const uint32_t len = xfer->ux_length; 4631 const uint32_t len = xfer->ux_length;
4653 const bool polling = xhci_polling_p(sc); 4632 const bool polling = xhci_polling_p(sc);
4654 usb_dma_t * const dma = &xfer->ux_dmabuf; 4633 usb_dma_t * const dma = &xfer->ux_dmabuf;
4655 uint64_t parameter; 4634 uint64_t parameter;
4656 uint32_t status; 4635 uint32_t status;
4657 uint32_t control; 4636 uint32_t control;
4658 u_int i = 0; 4637 u_int i = 0;
4659 4638
4660 XHCIHIST_FUNC(); 4639 XHCIHIST_FUNC();
4661 XHCIHIST_CALLARGS("%#jx slot %ju dci %ju", 4640 XHCIHIST_CALLARGS("%#jx slot %ju dci %ju",
4662 (uintptr_t)xfer, xs->xs_idx, dci, 0); 4641 (uintptr_t)xfer, xs->xs_idx, dci, 0);
4663 4642
 4643 KASSERT(polling || mutex_owned(&sc->sc_lock));
 4644
4664 if (sc->sc_dying) 4645 if (sc->sc_dying)
4665 return USBD_IOERROR; 4646 return USBD_IOERROR;
4666 4647
4667 if (!polling) 
4668 mutex_enter(&sc->sc_lock); 
4669 if (tr->is_halted) 4648 if (tr->is_halted)
4670 goto out; 4649 goto out;
4671 4650
4672 KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0); 4651 KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0);
4673 4652
4674 const bool isread = usbd_xfer_isread(xfer); 4653 const bool isread = usbd_xfer_isread(xfer);
4675 if (len) 4654 if (len)
4676 usb_syncmem(dma, 0, len, 4655 usb_syncmem(dma, 0, len,
4677 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 4656 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
4678 4657
4679 parameter = DMAADDR(dma, 0); 4658 parameter = DMAADDR(dma, 0);
4680 KASSERTMSG(len <= 0x10000, "len %d", len); 4659 KASSERTMSG(len <= 0x10000, "len %d", len);
4681 status = XHCI_TRB_2_IRQ_SET(0) | 4660 status = XHCI_TRB_2_IRQ_SET(0) |
@@ -4693,28 +4672,26 @@ xhci_device_intr_start(struct usbd_xfer  @@ -4693,28 +4672,26 @@ xhci_device_intr_start(struct usbd_xfer
4693 4672
4694 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); 4673 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci);
4695 4674
4696out: if (xfer->ux_status == USBD_NOT_STARTED) { 4675out: if (xfer->ux_status == USBD_NOT_STARTED) {
4697 xfer->ux_status = USBD_IN_PROGRESS; 4676 xfer->ux_status = USBD_IN_PROGRESS;
4698 usbd_xfer_schedule_timeout(xfer); 4677 usbd_xfer_schedule_timeout(xfer);
4699 } else { 4678 } else {
4700 /* 4679 /*
4701 * We must be coming from xhci_pipe_restart -- timeout 4680 * We must be coming from xhci_pipe_restart -- timeout
4702 * already set up, nothing to do. 4681 * already set up, nothing to do.
4703 */ 4682 */
4704 } 4683 }
4705 KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 4684 KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
4706 if (!polling) 
4707 mutex_exit(&sc->sc_lock); 
4708 4685
4709 return USBD_IN_PROGRESS; 4686 return USBD_IN_PROGRESS;
4710} 4687}
4711 4688
4712static void 4689static void
4713xhci_device_intr_done(struct usbd_xfer *xfer) 4690xhci_device_intr_done(struct usbd_xfer *xfer)
4714{ 4691{
4715 struct xhci_softc * const sc __diagused = XHCI_XFER2SC(xfer); 4692 struct xhci_softc * const sc __diagused = XHCI_XFER2SC(xfer);
4716#ifdef USB_DEBUG 4693#ifdef USB_DEBUG
4717 struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; 4694 struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv;
4718 const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); 4695 const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc);
4719#endif 4696#endif
4720 const bool isread = usbd_xfer_isread(xfer); 4697 const bool isread = usbd_xfer_isread(xfer);

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

--- src/sys/external/bsd/dwc2/dwc2.c 2022/03/03 06:08:50 1.79
+++ src/sys/external/bsd/dwc2/dwc2.c 2022/03/03 06:12:11 1.80
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: dwc2.c,v 1.79 2022/03/03 06:08:50 riastradh Exp $ */ 1/* $NetBSD: dwc2.c,v 1.80 2022/03/03 06:12:11 riastradh 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.79 2022/03/03 06:08:50 riastradh Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.80 2022/03/03 06:12:11 riastradh 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 38
39#include <sys/cpu.h> 39#include <sys/cpu.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/kernel.h> 41#include <sys/kernel.h>
42#include <sys/kmem.h> 42#include <sys/kmem.h>
43#include <sys/proc.h> 43#include <sys/proc.h>
44#include <sys/queue.h> 44#include <sys/queue.h>
45#include <sys/select.h> 45#include <sys/select.h>
46#include <sys/sysctl.h> 46#include <sys/sysctl.h>
@@ -610,40 +610,37 @@ Static usbd_status @@ -610,40 +610,37 @@ Static usbd_status
610dwc2_root_intr_transfer(struct usbd_xfer *xfer) 610dwc2_root_intr_transfer(struct usbd_xfer *xfer)
611{ 611{
612 612
613 DPRINTF("\n"); 613 DPRINTF("\n");
614 614
615 /* Pipe isn't running, start first */ 615 /* Pipe isn't running, start first */
616 return dwc2_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 616 return dwc2_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
617} 617}
618 618
619Static usbd_status 619Static usbd_status
620dwc2_root_intr_start(struct usbd_xfer *xfer) 620dwc2_root_intr_start(struct usbd_xfer *xfer)
621{ 621{
622 struct dwc2_softc *sc = DWC2_XFER2SC(xfer); 622 struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
623 const bool polling = sc->sc_bus.ub_usepolling; 
624 623
625 DPRINTF("\n"); 624 DPRINTF("\n");
626 625
 626 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 627
627 if (sc->sc_dying) 628 if (sc->sc_dying)
628 return USBD_IOERROR; 629 return USBD_IOERROR;
629 630
630 if (!polling) 
631 mutex_enter(&sc->sc_lock); 
632 KASSERT(sc->sc_intrxfer == NULL); 631 KASSERT(sc->sc_intrxfer == NULL);
633 sc->sc_intrxfer = xfer; 632 sc->sc_intrxfer = xfer;
634 xfer->ux_status = USBD_IN_PROGRESS; 633 xfer->ux_status = USBD_IN_PROGRESS;
635 if (!polling) 
636 mutex_exit(&sc->sc_lock); 
637 634
638 return USBD_IN_PROGRESS; 635 return USBD_IN_PROGRESS;
639} 636}
640 637
641/* Abort a root interrupt request. */ 638/* Abort a root interrupt request. */
642Static void 639Static void
643dwc2_root_intr_abort(struct usbd_xfer *xfer) 640dwc2_root_intr_abort(struct usbd_xfer *xfer)
644{ 641{
645 struct dwc2_softc *sc __diagused = DWC2_XFER2SC(xfer); 642 struct dwc2_softc *sc __diagused = DWC2_XFER2SC(xfer);
646 643
647 DPRINTF("xfer=%p\n", xfer); 644 DPRINTF("xfer=%p\n", xfer);
648 645
649 KASSERT(mutex_owned(&sc->sc_lock)); 646 KASSERT(mutex_owned(&sc->sc_lock));
@@ -699,37 +696,33 @@ dwc2_device_ctrl_transfer(struct usbd_xf @@ -699,37 +696,33 @@ dwc2_device_ctrl_transfer(struct usbd_xf
699{ 696{
700 697
701 DPRINTF("\n"); 698 DPRINTF("\n");
702 699
703 /* Pipe isn't running, start first */ 700 /* Pipe isn't running, start first */
704 return dwc2_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 701 return dwc2_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
705} 702}
706 703
707Static usbd_status 704Static usbd_status
708dwc2_device_ctrl_start(struct usbd_xfer *xfer) 705dwc2_device_ctrl_start(struct usbd_xfer *xfer)
709{ 706{
710 struct dwc2_softc *sc = DWC2_XFER2SC(xfer); 707 struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
711 usbd_status err; 708 usbd_status err;
712 const bool polling = sc->sc_bus.ub_usepolling; 
713 709
714 DPRINTF("\n"); 710 DPRINTF("\n");
715 711
716 if (!polling) 712 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
717 mutex_enter(&sc->sc_lock); 713
718 xfer->ux_status = USBD_IN_PROGRESS; 714 xfer->ux_status = USBD_IN_PROGRESS;
719 err = dwc2_device_start(xfer); 715 err = dwc2_device_start(xfer);
720 if (!polling) 
721 mutex_exit(&sc->sc_lock); 
722 
723 if (err) 716 if (err)
724 return err; 717 return err;
725 718
726 return USBD_IN_PROGRESS; 719 return USBD_IN_PROGRESS;
727} 720}
728 721
729Static void 722Static void
730dwc2_device_ctrl_abort(struct usbd_xfer *xfer) 723dwc2_device_ctrl_abort(struct usbd_xfer *xfer)
731{ 724{
732 struct dwc2_softc *sc __diagused = DWC2_XFER2SC(xfer); 725 struct dwc2_softc *sc __diagused = DWC2_XFER2SC(xfer);
733 726
734 KASSERT(mutex_owned(&sc->sc_lock)); 727 KASSERT(mutex_owned(&sc->sc_lock));
735 728
@@ -750,38 +743,32 @@ dwc2_device_ctrl_close(struct usbd_pipe  @@ -750,38 +743,32 @@ dwc2_device_ctrl_close(struct usbd_pipe
750 743
751Static void 744Static void
752dwc2_device_ctrl_done(struct usbd_xfer *xfer) 745dwc2_device_ctrl_done(struct usbd_xfer *xfer)
753{ 746{
754 747
755 DPRINTF("xfer=%p\n", xfer); 748 DPRINTF("xfer=%p\n", xfer);
756} 749}
757 750
758/***********************************************************************/ 751/***********************************************************************/
759 752
760Static usbd_status 753Static usbd_status
761dwc2_device_bulk_transfer(struct usbd_xfer *xfer) 754dwc2_device_bulk_transfer(struct usbd_xfer *xfer)
762{ 755{
763 struct dwc2_softc *sc = DWC2_XFER2SC(xfer); 
764 usbd_status err; 
765 756
766 DPRINTF("xfer=%p\n", xfer); 757 DPRINTF("xfer=%p\n", xfer);
767 758
768 mutex_enter(&sc->sc_lock); 
769 KASSERT(xfer->ux_status == USBD_NOT_STARTED); 759 KASSERT(xfer->ux_status == USBD_NOT_STARTED);
770 xfer->ux_status = USBD_IN_PROGRESS; 760 xfer->ux_status = USBD_IN_PROGRESS;
771 err = dwc2_device_start(xfer); 761 return dwc2_device_start(xfer);
772 mutex_exit(&sc->sc_lock); 
773 
774 return err; 
775} 762}
776 763
777Static void 764Static void
778dwc2_device_bulk_abort(struct usbd_xfer *xfer) 765dwc2_device_bulk_abort(struct usbd_xfer *xfer)
779{ 766{
780 struct dwc2_softc *sc __diagused = DWC2_XFER2SC(xfer); 767 struct dwc2_softc *sc __diagused = DWC2_XFER2SC(xfer);
781 768
782 KASSERT(mutex_owned(&sc->sc_lock)); 769 KASSERT(mutex_owned(&sc->sc_lock));
783 770
784 DPRINTF("xfer=%p\n", xfer); 771 DPRINTF("xfer=%p\n", xfer);
785 usbd_xfer_abort(xfer); 772 usbd_xfer_abort(xfer);
786} 773}
787 774
@@ -810,35 +797,31 @@ dwc2_device_intr_transfer(struct usbd_xf @@ -810,35 +797,31 @@ dwc2_device_intr_transfer(struct usbd_xf
810 DPRINTF("xfer=%p\n", xfer); 797 DPRINTF("xfer=%p\n", xfer);
811 798
812 /* Pipe isn't running, start first */ 799 /* Pipe isn't running, start first */
813 return dwc2_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 800 return dwc2_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
814} 801}
815 802
816Static usbd_status 803Static usbd_status
817dwc2_device_intr_start(struct usbd_xfer *xfer) 804dwc2_device_intr_start(struct usbd_xfer *xfer)
818{ 805{
819 struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer) 806 struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer)
820 struct usbd_device *dev = dpipe->pipe.up_dev; 807 struct usbd_device *dev = dpipe->pipe.up_dev;
821 struct dwc2_softc *sc = dev->ud_bus->ub_hcpriv; 808 struct dwc2_softc *sc = dev->ud_bus->ub_hcpriv;
822 usbd_status err; 809 usbd_status err;
823 const bool polling = sc->sc_bus.ub_usepolling; 
824 810
825 if (!polling) 811 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
826 mutex_enter(&sc->sc_lock); 812
827 xfer->ux_status = USBD_IN_PROGRESS; 813 xfer->ux_status = USBD_IN_PROGRESS;
828 err = dwc2_device_start(xfer); 814 err = dwc2_device_start(xfer);
829 if (!polling) 
830 mutex_exit(&sc->sc_lock); 
831 
832 if (err) 815 if (err)
833 return err; 816 return err;
834 817
835 return USBD_IN_PROGRESS; 818 return USBD_IN_PROGRESS;
836} 819}
837 820
838/* Abort a device interrupt request. */ 821/* Abort a device interrupt request. */
839Static void 822Static void
840dwc2_device_intr_abort(struct usbd_xfer *xfer) 823dwc2_device_intr_abort(struct usbd_xfer *xfer)
841{ 824{
842 struct dwc2_softc *sc __diagused = DWC2_XFER2SC(xfer); 825 struct dwc2_softc *sc __diagused = DWC2_XFER2SC(xfer);
843 826
844 KASSERT(mutex_owned(&sc->sc_lock)); 827 KASSERT(mutex_owned(&sc->sc_lock));
@@ -858,38 +841,32 @@ dwc2_device_intr_close(struct usbd_pipe  @@ -858,38 +841,32 @@ dwc2_device_intr_close(struct usbd_pipe
858 841
859Static void 842Static void
860dwc2_device_intr_done(struct usbd_xfer *xfer) 843dwc2_device_intr_done(struct usbd_xfer *xfer)
861{ 844{
862 845
863 DPRINTF("\n"); 846 DPRINTF("\n");
864} 847}
865 848
866/***********************************************************************/ 849/***********************************************************************/
867 850
868usbd_status 851usbd_status
869dwc2_device_isoc_transfer(struct usbd_xfer *xfer) 852dwc2_device_isoc_transfer(struct usbd_xfer *xfer)
870{ 853{
871 struct dwc2_softc *sc = DWC2_XFER2SC(xfer); 
872 usbd_status err; 
873 854
874 DPRINTF("xfer=%p\n", xfer); 855 DPRINTF("xfer=%p\n", xfer);
875 856
876 mutex_enter(&sc->sc_lock); 
877 KASSERT(xfer->ux_status == USBD_NOT_STARTED); 857 KASSERT(xfer->ux_status == USBD_NOT_STARTED);
878 xfer->ux_status = USBD_IN_PROGRESS; 858 xfer->ux_status = USBD_IN_PROGRESS;
879 err = dwc2_device_start(xfer); 859 return dwc2_device_start(xfer);
880 mutex_exit(&sc->sc_lock); 
881 
882 return err; 
883} 860}
884 861
885void 862void
886dwc2_device_isoc_abort(struct usbd_xfer *xfer) 863dwc2_device_isoc_abort(struct usbd_xfer *xfer)
887{ 864{
888 struct dwc2_softc *sc __diagused = DWC2_XFER2SC(xfer); 865 struct dwc2_softc *sc __diagused = DWC2_XFER2SC(xfer);
889 KASSERT(mutex_owned(&sc->sc_lock)); 866 KASSERT(mutex_owned(&sc->sc_lock));
890 867
891 DPRINTF("xfer=%p\n", xfer); 868 DPRINTF("xfer=%p\n", xfer);
892 usbd_xfer_abort(xfer); 869 usbd_xfer_abort(xfer);
893} 870}
894 871
895void 872void
@@ -923,26 +900,28 @@ dwc2_device_start(struct usbd_xfer *xfer @@ -923,26 +900,28 @@ dwc2_device_start(struct usbd_xfer *xfer
923 uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); 900 uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes);
924 uint8_t epnum = UE_GET_ADDR(ed->bEndpointAddress); 901 uint8_t epnum = UE_GET_ADDR(ed->bEndpointAddress);
925 uint8_t dir = UE_GET_DIR(ed->bEndpointAddress); 902 uint8_t dir = UE_GET_DIR(ed->bEndpointAddress);
926 uint16_t mps = UE_GET_SIZE(UGETW(ed->wMaxPacketSize)); 903 uint16_t mps = UE_GET_SIZE(UGETW(ed->wMaxPacketSize));
927 uint32_t len; 904 uint32_t len;
928 905
929 uint32_t flags = 0; 906 uint32_t flags = 0;
930 uint32_t off = 0; 907 uint32_t off = 0;
931 int retval, err; 908 int retval, err;
932 int alloc_bandwidth = 0; 909 int alloc_bandwidth = 0;
933 910
934 DPRINTFN(1, "xfer=%p pipe=%p\n", xfer, xfer->ux_pipe); 911 DPRINTFN(1, "xfer=%p pipe=%p\n", xfer, xfer->ux_pipe);
935 912
 913 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 914
936 if (xfertype == UE_ISOCHRONOUS || 915 if (xfertype == UE_ISOCHRONOUS ||
937 xfertype == UE_INTERRUPT) { 916 xfertype == UE_INTERRUPT) {
938 mutex_spin_enter(&hsotg->lock); 917 mutex_spin_enter(&hsotg->lock);
939 if (!dwc2_hcd_is_bandwidth_allocated(hsotg, xfer)) 918 if (!dwc2_hcd_is_bandwidth_allocated(hsotg, xfer))
940 alloc_bandwidth = 1; 919 alloc_bandwidth = 1;
941 mutex_spin_exit(&hsotg->lock); 920 mutex_spin_exit(&hsotg->lock);
942 } 921 }
943 922
944 /* 923 /*
945 * For Control pipe the direction is from the request, all other 924 * For Control pipe the direction is from the request, all other
946 * transfers have been set correctly at pipe open time. 925 * transfers have been set correctly at pipe open time.
947 */ 926 */
948 if (xfertype == UE_CONTROL) { 927 if (xfertype == UE_CONTROL) {
@@ -1111,29 +1090,27 @@ dwc2_device_start(struct usbd_xfer *xfer @@ -1111,29 +1090,27 @@ dwc2_device_start(struct usbd_xfer *xfer
1111 /* might need to check cpu_intr_p */ 1090 /* might need to check cpu_intr_p */
1112 mutex_spin_enter(&hsotg->lock); 1091 mutex_spin_enter(&hsotg->lock);
1113 retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, qh, qtd); 1092 retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, qh, qtd);
1114 if (retval) 1093 if (retval)
1115 goto fail2; 1094 goto fail2;
1116 usbd_xfer_schedule_timeout(xfer); 1095 usbd_xfer_schedule_timeout(xfer);
1117 xfer->ux_status = USBD_IN_PROGRESS; 1096 xfer->ux_status = USBD_IN_PROGRESS;
1118 1097
1119 if (alloc_bandwidth) { 1098 if (alloc_bandwidth) {
1120 dwc2_allocate_bus_bandwidth(hsotg, 1099 dwc2_allocate_bus_bandwidth(hsotg,
1121 dwc2_hcd_get_ep_bandwidth(hsotg, dpipe), 1100 dwc2_hcd_get_ep_bandwidth(hsotg, dpipe),
1122 xfer); 1101 xfer);
1123 } 1102 }
1124 
1125 mutex_spin_exit(&hsotg->lock); 1103 mutex_spin_exit(&hsotg->lock);
1126// mutex_exit(&sc->sc_lock); 
1127 1104
1128 return USBD_IN_PROGRESS; 1105 return USBD_IN_PROGRESS;
1129 1106
1130fail2: 1107fail2:
1131 dwc2_urb->priv = NULL; 1108 dwc2_urb->priv = NULL;
1132 mutex_spin_exit(&hsotg->lock); 1109 mutex_spin_exit(&hsotg->lock);
1133 pool_cache_put(sc->sc_qtdpool, qtd); 1110 pool_cache_put(sc->sc_qtdpool, qtd);
1134 1111
1135fail1: 1112fail1:
1136 if (qh_allocated) { 1113 if (qh_allocated) {
1137 dpipe->priv = NULL; 1114 dpipe->priv = NULL;
1138 dwc2_hcd_qh_free(hsotg, qh); 1115 dwc2_hcd_qh_free(hsotg, qh);
1139 } 1116 }

cvs diff -r1.30 -r1.31 src/sys/rump/dev/lib/libugenhc/ugenhc.c (expand / switch to unified diff)

--- src/sys/rump/dev/lib/libugenhc/ugenhc.c 2022/03/03 06:04:31 1.30
+++ src/sys/rump/dev/lib/libugenhc/ugenhc.c 2022/03/03 06:12:11 1.31
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ugenhc.c,v 1.30 2022/03/03 06:04:31 riastradh Exp $ */ 1/* $NetBSD: ugenhc.c,v 1.31 2022/03/03 06:12:11 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2009, 2010 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2009, 2010 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -51,27 +51,27 @@ @@ -51,27 +51,27 @@
51 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 51 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 52 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 53 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 54 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55 * POSSIBILITY OF SUCH DAMAGE. 55 * POSSIBILITY OF SUCH DAMAGE.
56 */ 56 */
57 57
58/* 58/*
59 * This rump driver attaches ugen as a kernel usb host controller. 59 * This rump driver attaches ugen as a kernel usb host controller.
60 * It's still somewhat under the hammer .... 60 * It's still somewhat under the hammer ....
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: ugenhc.c,v 1.30 2022/03/03 06:04:31 riastradh Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: ugenhc.c,v 1.31 2022/03/03 06:12:11 riastradh Exp $");
65 65
66#include <sys/param.h> 66#include <sys/param.h>
67#include <sys/bus.h> 67#include <sys/bus.h>
68#include <sys/conf.h> 68#include <sys/conf.h>
69#include <sys/device.h> 69#include <sys/device.h>
70#include <sys/fcntl.h> 70#include <sys/fcntl.h>
71#include <sys/kmem.h> 71#include <sys/kmem.h>
72#include <sys/kernel.h> 72#include <sys/kernel.h>
73#include <sys/kthread.h> 73#include <sys/kthread.h>
74#include <sys/mutex.h> 74#include <sys/mutex.h>
75 75
76#include <dev/usb/usb.h> 76#include <dev/usb/usb.h>
77#include <dev/usb/usbdi.h> 77#include <dev/usb/usbdi.h>
@@ -217,26 +217,28 @@ ugenhc_roothub_ctrl(struct usbd_bus *bus @@ -217,26 +217,28 @@ ugenhc_roothub_ctrl(struct usbd_bus *bus
217} 217}
218 218
219static usbd_status 219static usbd_status
220rumpusb_device_ctrl_start(struct usbd_xfer *xfer) 220rumpusb_device_ctrl_start(struct usbd_xfer *xfer)
221{ 221{
222 usb_device_request_t *req = &xfer->ux_request; 222 usb_device_request_t *req = &xfer->ux_request;
223 struct ugenhc_softc *sc = UGENHC_XFER2SC(xfer); 223 struct ugenhc_softc *sc = UGENHC_XFER2SC(xfer);
224 uint8_t *buf = NULL; 224 uint8_t *buf = NULL;
225 int len, totlen; 225 int len, totlen;
226 int value; 226 int value;
227 int err = 0; 227 int err = 0;
228 int ru_error, mightfail = 0; 228 int ru_error, mightfail = 0;
229 229
 230 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 231
230 len = totlen = UGETW(req->wLength); 232 len = totlen = UGETW(req->wLength);
231 if (len) 233 if (len)
232 buf = xfer->ux_buf; 234 buf = xfer->ux_buf;
233 value = UGETW(req->wValue); 235 value = UGETW(req->wValue);
234 236
235#define C(x,y) ((x) | ((y) << 8)) 237#define C(x,y) ((x) | ((y) << 8))
236 switch(C(req->bRequest, req->bmRequestType)) { 238 switch(C(req->bRequest, req->bmRequestType)) {
237 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 239 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
238 switch (value>>8) { 240 switch (value>>8) {
239 case UDESC_DEVICE: 241 case UDESC_DEVICE:
240 { 242 {
241 usb_device_descriptor_t uddesc; 243 usb_device_descriptor_t uddesc;
242 totlen = uimin(len, USB_DEVICE_DESCRIPTOR_SIZE); 244 totlen = uimin(len, USB_DEVICE_DESCRIPTOR_SIZE);
@@ -381,29 +383,27 @@ rumpusb_device_ctrl_start(struct usbd_xf @@ -381,29 +383,27 @@ rumpusb_device_ctrl_start(struct usbd_xf
381 } 383 }
382 } 384 }
383 break; 385 break;
384 386
385 default: 387 default:
386 panic("unhandled request"); 388 panic("unhandled request");
387 break; 389 break;
388 } 390 }
389 xfer->ux_actlen = totlen; 391 xfer->ux_actlen = totlen;
390 err = USBD_NORMAL_COMPLETION; 392 err = USBD_NORMAL_COMPLETION;
391 393
392 ret: 394 ret:
393 xfer->ux_status = err; 395 xfer->ux_status = err;
394 mutex_enter(&sc->sc_lock); 
395 usb_transfer_complete(xfer); 396 usb_transfer_complete(xfer);
396 mutex_exit(&sc->sc_lock); 
397 397
398 return USBD_IN_PROGRESS; 398 return USBD_IN_PROGRESS;
399} 399}
400 400
401static usbd_status 401static usbd_status
402rumpusb_device_ctrl_transfer(struct usbd_xfer *xfer) 402rumpusb_device_ctrl_transfer(struct usbd_xfer *xfer)
403{ 403{
404 404
405 return rumpusb_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 405 return rumpusb_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
406} 406}
407 407
408static void 408static void
409rumpusb_device_ctrl_abort(struct usbd_xfer *xfer) 409rumpusb_device_ctrl_abort(struct usbd_xfer *xfer)
@@ -506,35 +506,35 @@ rhscintr(void *arg) @@ -506,35 +506,35 @@ rhscintr(void *arg)
506 506
507 kpause("ugwait3", false, hz, NULL); 507 kpause("ugwait3", false, hz, NULL);
508 } 508 }
509 509
510 kthread_exit(0); 510 kthread_exit(0);
511} 511}
512 512
513static usbd_status 513static usbd_status
514rumpusb_root_intr_start(struct usbd_xfer *xfer) 514rumpusb_root_intr_start(struct usbd_xfer *xfer)
515{ 515{
516 struct ugenhc_softc *sc = UGENHC_XFER2SC(xfer); 516 struct ugenhc_softc *sc = UGENHC_XFER2SC(xfer);
517 int error; 517 int error;
518 518
519 mutex_enter(&sc->sc_lock); 519 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 520
520 sc->sc_intrxfer = xfer; 521 sc->sc_intrxfer = xfer;
521 if (!sc->sc_rhintr) { 522 if (!sc->sc_rhintr) {
522 error = kthread_create(PRI_NONE, 0, NULL, 523 error = kthread_create(PRI_NONE, 0, NULL,
523 rhscintr, sc, &sc->sc_rhintr, "ugenrhi"); 524 rhscintr, sc, &sc->sc_rhintr, "ugenrhi");
524 if (error) 525 if (error)
525 xfer->ux_status = USBD_IOERROR; 526 xfer->ux_status = USBD_IOERROR;
526 } 527 }
527 mutex_exit(&sc->sc_lock); 
528 528
529 return USBD_IN_PROGRESS; 529 return USBD_IN_PROGRESS;
530} 530}
531 531
532static usbd_status 532static usbd_status
533rumpusb_root_intr_transfer(struct usbd_xfer *xfer) 533rumpusb_root_intr_transfer(struct usbd_xfer *xfer)
534{ 534{
535 535
536 return rumpusb_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 536 return rumpusb_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
537} 537}
538 538
539static void 539static void
540rumpusb_root_intr_abort(struct usbd_xfer *xfer) 540rumpusb_root_intr_abort(struct usbd_xfer *xfer)
@@ -571,26 +571,28 @@ static const struct usbd_pipe_methods ru @@ -571,26 +571,28 @@ static const struct usbd_pipe_methods ru
571 571
572static usbd_status 572static usbd_status
573rumpusb_device_bulk_start(struct usbd_xfer *xfer) 573rumpusb_device_bulk_start(struct usbd_xfer *xfer)
574{ 574{
575 struct ugenhc_softc *sc = UGENHC_XFER2SC(xfer); 575 struct ugenhc_softc *sc = UGENHC_XFER2SC(xfer);
576 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; 576 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc;
577 size_t n, done; 577 size_t n, done;
578 bool isread; 578 bool isread;
579 int len, error, endpt; 579 int len, error, endpt;
580 uint8_t *buf; 580 uint8_t *buf;
581 int xfererr = USBD_NORMAL_COMPLETION; 581 int xfererr = USBD_NORMAL_COMPLETION;
582 int shortval, i; 582 int shortval, i;
583 583
 584 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
 585
584 ed = xfer->ux_pipe->up_endpoint->ue_edesc; 586 ed = xfer->ux_pipe->up_endpoint->ue_edesc;
585 endpt = ed->bEndpointAddress; 587 endpt = ed->bEndpointAddress;
586 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 588 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
587 endpt = UE_GET_ADDR(endpt); 589 endpt = UE_GET_ADDR(endpt);
588 KASSERT(endpt < UGEN_NEPTS); 590 KASSERT(endpt < UGEN_NEPTS);
589 591
590 buf = xfer->ux_buf; 592 buf = xfer->ux_buf;
591 done = 0; 593 done = 0;
592 if ((ed->bmAttributes & UE_XFERTYPE) == UE_ISOCHRONOUS) { 594 if ((ed->bmAttributes & UE_XFERTYPE) == UE_ISOCHRONOUS) {
593 for (i = 0, len = 0; i < xfer->ux_nframes; i++) 595 for (i = 0, len = 0; i < xfer->ux_nframes; i++)
594 len += xfer->ux_frlengths[i]; 596 len += xfer->ux_frlengths[i];
595 } else { 597 } else {
596 KASSERT(xfer->ux_length); 598 KASSERT(xfer->ux_length);
@@ -657,44 +659,40 @@ rumpusb_device_bulk_start(struct usbd_xf @@ -657,44 +659,40 @@ rumpusb_device_bulk_start(struct usbd_xf
657 } 659 }
658 660
659 if (RUSB(xfer)->rusb_status == 0) { 661 if (RUSB(xfer)->rusb_status == 0) {
660 xfer->ux_actlen = done; 662 xfer->ux_actlen = done;
661 } else { 663 } else {
662 xfererr = USBD_CANCELLED; 664 xfererr = USBD_CANCELLED;
663 RUSB(xfer)->rusb_status = 2; 665 RUSB(xfer)->rusb_status = 2;
664 } 666 }
665 out: 667 out:
666 if ((ed->bmAttributes & UE_XFERTYPE) == UE_ISOCHRONOUS) 668 if ((ed->bmAttributes & UE_XFERTYPE) == UE_ISOCHRONOUS)
667 if (done != len) 669 if (done != len)
668 panic("lazy bum"); 670 panic("lazy bum");
669 xfer->ux_status = xfererr; 671 xfer->ux_status = xfererr;
670 mutex_enter(&sc->sc_lock); 
671 usb_transfer_complete(xfer); 672 usb_transfer_complete(xfer);
672 mutex_exit(&sc->sc_lock); 
673 return USBD_IN_PROGRESS; 673 return USBD_IN_PROGRESS;
674} 674}
675 675
676static void 676static void
677doxfer_kth(void *arg) 677doxfer_kth(void *arg)
678{ 678{
679 struct usbd_pipe *pipe = arg; 679 struct usbd_pipe *pipe = arg;
680 struct ugenhc_softc *sc = UGENHC_PIPE2SC(pipe); 680 struct ugenhc_softc *sc = UGENHC_PIPE2SC(pipe);
681 681
682 mutex_enter(&sc->sc_lock); 682 mutex_enter(&sc->sc_lock);
683 do { 683 do {
684 struct usbd_xfer *xfer = SIMPLEQ_FIRST(&pipe->up_queue); 684 struct usbd_xfer *xfer = SIMPLEQ_FIRST(&pipe->up_queue);
685 mutex_exit(&sc->sc_lock); 
686 rumpusb_device_bulk_start(xfer); 685 rumpusb_device_bulk_start(xfer);
687 mutex_enter(&sc->sc_lock); 
688 } while (!SIMPLEQ_EMPTY(&pipe->up_queue)); 686 } while (!SIMPLEQ_EMPTY(&pipe->up_queue));
689 mutex_exit(&sc->sc_lock); 687 mutex_exit(&sc->sc_lock);
690 kthread_exit(0); 688 kthread_exit(0);
691} 689}
692 690
693static usbd_status 691static usbd_status
694rumpusb_device_bulk_transfer(struct usbd_xfer *xfer) 692rumpusb_device_bulk_transfer(struct usbd_xfer *xfer)
695{ 693{
696 694
697 if (!rump_threads) { 695 if (!rump_threads) {
698 /* XXX: lie about supporting async transfers */ 696 /* XXX: lie about supporting async transfers */
699 if ((xfer->ux_flags & USBD_SYNCHRONOUS) == 0) { 697 if ((xfer->ux_flags & USBD_SYNCHRONOUS) == 0) {
700 printf("non-threaded rump does not support " 698 printf("non-threaded rump does not support "