Module Name: src Committed By: mlelstv Date: Wed Apr 6 21:51:29 UTC 2022
Modified Files: src/sys/dev/usb: ehci.c if_smscreg.h if_urtwn.c ubt.c uhub.c ukbd.c usb_subr.c usbdi.c uvideo.c xhci.c xhcireg.h Log Message: remove debug printf To generate a diff of this commit: cvs rdiff -u -r1.309 -r1.310 src/sys/dev/usb/ehci.c cvs rdiff -u -r1.6 -r1.7 src/sys/dev/usb/if_smscreg.h cvs rdiff -u -r1.101 -r1.102 src/sys/dev/usb/if_urtwn.c cvs rdiff -u -r1.64 -r1.65 src/sys/dev/usb/ubt.c cvs rdiff -u -r1.159 -r1.160 src/sys/dev/usb/uhub.c cvs rdiff -u -r1.160 -r1.161 src/sys/dev/usb/ukbd.c cvs rdiff -u -r1.275 -r1.276 src/sys/dev/usb/usb_subr.c cvs rdiff -u -r1.240 -r1.241 src/sys/dev/usb/usbdi.c cvs rdiff -u -r1.70 -r1.71 src/sys/dev/usb/uvideo.c cvs rdiff -u -r1.162 -r1.163 src/sys/dev/usb/xhci.c cvs rdiff -u -r1.19 -r1.20 src/sys/dev/usb/xhcireg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/ehci.c diff -u src/sys/dev/usb/ehci.c:1.309 src/sys/dev/usb/ehci.c:1.310 --- src/sys/dev/usb/ehci.c:1.309 Sun Mar 13 11:29:21 2022 +++ src/sys/dev/usb/ehci.c Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ehci.c,v 1.309 2022/03/13 11:29:21 riastradh Exp $ */ +/* $NetBSD: ehci.c,v 1.310 2022/04/06 21:51:29 mlelstv Exp $ */ /* * Copyright (c) 2004-2012,2016,2020 The NetBSD Foundation, Inc. @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.309 2022/03/13 11:29:21 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.310 2022/04/06 21:51:29 mlelstv Exp $"); #include "ohci.h" #include "uhci.h" @@ -790,6 +790,9 @@ ehci_intr1(ehci_softc_t *sc) if (eintrs & EHCI_STS_HSE) { printf("%s: unrecoverable error, controller halted\n", device_xname(sc->sc_dev)); +#ifdef EHCI_DEBUG + ehci_dump(); +#endif /* XXX what else */ } if (eintrs & EHCI_STS_PCD) { @@ -2241,6 +2244,7 @@ ehci_sync_hc(ehci_softc_t *sc) unsigned starttime = getticks(); unsigned endtime = starttime + delta; unsigned now; + uint32_t v; KASSERT(mutex_owned(&sc->sc_lock)); @@ -2260,7 +2264,10 @@ ehci_sync_hc(ehci_softc_t *sc) sc->sc_doorbelllwp = curlwp; /* ask for doorbell */ - EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) | EHCI_CMD_IAAD); + v = EOREAD4(sc, EHCI_USBCMD); + if ((v & EHCI_CMD_IAAD) == 0) + EOWRITE4(sc, EHCI_USBCMD, v | EHCI_CMD_IAAD); + DPRINTF("cmd = 0x%08jx sts = 0x%08jx", EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS), 0, 0); Index: src/sys/dev/usb/if_smscreg.h diff -u src/sys/dev/usb/if_smscreg.h:1.6 src/sys/dev/usb/if_smscreg.h:1.7 --- src/sys/dev/usb/if_smscreg.h:1.6 Mon Aug 12 08:40:09 2019 +++ src/sys/dev/usb/if_smscreg.h Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: if_smscreg.h,v 1.6 2019/08/12 08:40:09 skrll Exp $ */ +/* $NetBSD: if_smscreg.h,v 1.7 2022/04/06 21:51:29 mlelstv Exp $ */ /* $OpenBSD: if_smscreg.h,v 1.2 2012/09/27 12:38:11 jsg Exp $ */ /*- @@ -244,7 +244,7 @@ #define SMSC_UR_GET_STATS 0xA2 #define SMSC_RX_LIST_CNT 1 -#define SMSC_TX_LIST_CNT 1 +#define SMSC_TX_LIST_CNT 2 #define SMSC_CONFIG_INDEX 1 /* config number 1 */ #define SMSC_IFACE_IDX 0 Index: src/sys/dev/usb/if_urtwn.c diff -u src/sys/dev/usb/if_urtwn.c:1.101 src/sys/dev/usb/if_urtwn.c:1.102 --- src/sys/dev/usb/if_urtwn.c:1.101 Thu Oct 21 20:18:16 2021 +++ src/sys/dev/usb/if_urtwn.c Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: if_urtwn.c,v 1.101 2021/10/21 20:18:16 jnemeth Exp $ */ +/* $NetBSD: if_urtwn.c,v 1.102 2022/04/06 21:51:29 mlelstv Exp $ */ /* $OpenBSD: if_urtwn.c,v 1.42 2015/02/10 23:25:46 mpi Exp $ */ /*- @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.101 2021/10/21 20:18:16 jnemeth Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.102 2022/04/06 21:51:29 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -2623,7 +2623,8 @@ urtwn_txeof(struct usbd_xfer *xfer, void struct usbd_pipe *pipe = sc->tx_pipe[pidx]; usbd_clear_endpoint_stall_async(pipe); } - device_printf(sc->sc_dev, "device timeout\n"); + device_printf(sc->sc_dev, "device error %s\n", + usbd_errstr(status)); if_statinc(ifp, if_oerrors); } splx(s); Index: src/sys/dev/usb/ubt.c diff -u src/sys/dev/usb/ubt.c:1.64 src/sys/dev/usb/ubt.c:1.65 --- src/sys/dev/usb/ubt.c:1.64 Sun Dec 1 08:27:54 2019 +++ src/sys/dev/usb/ubt.c Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ubt.c,v 1.64 2019/12/01 08:27:54 maxv Exp $ */ +/* $NetBSD: ubt.c,v 1.65 2022/04/06 21:51:29 mlelstv Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ubt.c,v 1.64 2019/12/01 08:27:54 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ubt.c,v 1.65 2022/04/06 21:51:29 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -1456,7 +1456,7 @@ ubt_xmit_sco_start1(struct ubt_softc *sc isoc, isoc->size, num, - USBD_FORCE_SHORT_XFER, + USBD_FORCE_SHORT_XFER | USBD_SHORT_XFER_OK, ubt_xmit_sco_complete); usbd_transfer(isoc->xfer); @@ -1777,11 +1777,11 @@ ubt_recv_sco_complete(struct usbd_xfer * if (m == NULL) { MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) { - aprint_error_dev(sc->sc_dev, + device_printf(sc->sc_dev, "out of memory (xfer halted)\n"); sc->sc_stats.err_rx++; - return; /* lost sync */ + return; /* lost sync */ } ptr = mtod(m, uint8_t *); @@ -1808,14 +1808,21 @@ ubt_recv_sco_complete(struct usbd_xfer * if (want == sizeof(hci_scodata_hdr_t)) { uint32_t len = mtod(m, hci_scodata_hdr_t *)->length; - want += len; - if (len == 0 || want > MHLEN) { - aprint_error_dev(sc->sc_dev, + if (len == 0) { + ptr = mtod(m, uint8_t *); + ptr++; + got = 1; + } else if (want > MHLEN) { + device_printf(sc->sc_dev, "packet too large %u " "(lost sync)\n", len); sc->sc_stats.err_rx++; + + /* lost sync */ + m_freem(m); return; - } + } else + want += len; } if (got == want) { @@ -1825,6 +1832,9 @@ ubt_recv_sco_complete(struct usbd_xfer * sc->sc_stats.err_rx++; m = NULL; + ptr = NULL; + got = 0; + want = 0; } } Index: src/sys/dev/usb/uhub.c diff -u src/sys/dev/usb/uhub.c:1.159 src/sys/dev/usb/uhub.c:1.160 --- src/sys/dev/usb/uhub.c:1.159 Fri Feb 4 23:03:38 2022 +++ src/sys/dev/usb/uhub.c Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: uhub.c,v 1.159 2022/02/04 23:03:38 riastradh Exp $ */ +/* $NetBSD: uhub.c,v 1.160 2022/04/06 21:51:29 mlelstv Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */ /* $OpenBSD: uhub.c,v 1.86 2015/06/29 18:27:40 mpi Exp $ */ @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.159 2022/02/04 23:03:38 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.160 2022/04/06 21:51:29 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -563,9 +563,29 @@ uhub_explore(struct usbd_device *dev) for (port = 1; port <= hd->bNbrPorts; port++) { SDT_PROBE3(usb, hub, explore, rescan, dev, port, &dev->ud_hub->uh_ports[port - 1]); - subdev = dev->ud_hub->uh_ports[port - 1].up_dev; + up = &dev->ud_hub->uh_ports[port - 1]; + subdev = up->up_dev; if (subdev == NULL) continue; + + err = usbd_get_port_status(subdev, port, &up->up_status); + if (err) { + DPRINTF("uhub%jd get port stat failed, err %jd", + device_unit(sc->sc_dev), err, 0, 0); + continue; + } + + change = UGETW(up->up_status.wPortChange); + if ((change & UPS_C_PORT_ENABLED) == 0) { + if (usbd_reset_port(subdev, port, &up->up_status)) { + device_printf(sc->sc_dev, + "port %d reset failed\n", port); + continue; + } + device_printf(sc->sc_dev, + "port %d reset succeeded\n", port); + } + usbd_reattach_device(sc->sc_dev, subdev, port, NULL); } } @@ -864,7 +884,7 @@ uhub_explore(struct usbd_device *dev) * some other serious problem. Since we cannot leave * at 0 we have to disable the port instead. */ - aprint_error_dev(sc->sc_dev, + device_printf(sc->sc_dev, "device problem, disabling port %d\n", port); usbd_clear_port_feature(dev, port, UHF_PORT_ENABLE); } else { Index: src/sys/dev/usb/ukbd.c diff -u src/sys/dev/usb/ukbd.c:1.160 src/sys/dev/usb/ukbd.c:1.161 --- src/sys/dev/usb/ukbd.c:1.160 Sat Apr 2 19:19:12 2022 +++ src/sys/dev/usb/ukbd.c Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ukbd.c,v 1.160 2022/04/02 19:19:12 mlelstv Exp $ */ +/* $NetBSD: ukbd.c,v 1.161 2022/04/06 21:51:29 mlelstv Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.160 2022/04/02 19:19:12 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.161 2022/04/06 21:51:29 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -1083,9 +1083,6 @@ ukbd_parse_desc(struct ukbd_softc *sc) sc->sc_nkeycode = 0; d = hid_start_parse(desc, size, hid_input); while (hid_get_item(d, &h)) { - printf("ukbd: id=%d kind=%d usage=%#x flags=%#x pos=%d size=%d cnt=%d\n", - h.report_ID, h.kind, h.usage, h.flags, h.loc.pos, h.loc.size, h.loc.count); - /* Check for special Apple notebook FN key */ if (HID_GET_USAGE_PAGE(h.usage) == 0x00ff && HID_GET_USAGE(h.usage) == 0x0003 && Index: src/sys/dev/usb/usb_subr.c diff -u src/sys/dev/usb/usb_subr.c:1.275 src/sys/dev/usb/usb_subr.c:1.276 --- src/sys/dev/usb/usb_subr.c:1.275 Sat Mar 19 20:50:32 2022 +++ src/sys/dev/usb/usb_subr.c Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: usb_subr.c,v 1.275 2022/03/19 20:50:32 riastradh Exp $ */ +/* $NetBSD: usb_subr.c,v 1.276 2022/04/06 21:51:29 mlelstv Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ /* @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.275 2022/03/19 20:50:32 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.276 2022/04/06 21:51:29 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -247,8 +247,11 @@ usb_delay_ms_locked(struct usbd_bus *bus /* Wait at least two clock ticks so we know the time has passed. */ if (bus->ub_usepolling || cold) delay((ms+1) * 1000); - else + else { +int timeo = (ms*hz+999)/1000 + 1; +if (timeo > hz/2) printf("usb_delay_ms_locked(%p) %d ticks\n",lock,timeo); kpause("usbdly", false, (ms*hz+999)/1000 + 1, lock); + } } void @@ -458,8 +461,16 @@ usbd_iface_exlock(struct usbd_interface { mutex_enter(iface->ui_dev->ud_bus->ub_lock); +#if 1 +if (iface->ui_busy != 0) { + printf("%s: addr %d not idle, busy = %"PRId64"\n", + device_xname(iface->ui_dev->ud_bus->ub_usbctl), + iface->ui_dev->ud_addr, iface->ui_busy); +} +#else KASSERTMSG(iface->ui_busy == 0, "interface is not idle," " busy=%"PRId64, iface->ui_busy); +#endif iface->ui_busy = -1; mutex_exit(iface->ui_dev->ud_bus->ub_lock); } Index: src/sys/dev/usb/usbdi.c diff -u src/sys/dev/usb/usbdi.c:1.240 src/sys/dev/usb/usbdi.c:1.241 --- src/sys/dev/usb/usbdi.c:1.240 Sun Mar 20 00:40:52 2022 +++ src/sys/dev/usb/usbdi.c Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.c,v 1.240 2022/03/20 00:40:52 riastradh Exp $ */ +/* $NetBSD: usbdi.c,v 1.241 2022/04/06 21:51:29 mlelstv Exp $ */ /* * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.240 2022/03/20 00:40:52 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.241 2022/04/06 21:51:29 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -1185,7 +1185,11 @@ usb_transfer_complete(struct usbd_xfer * if (xfer->ux_callback) { if (!polling) { - KASSERT(pipe->up_callingxfer == NULL); + while (pipe->up_callingxfer != NULL) { +printf("callingxfer used\n"); + cv_wait(&pipe->up_callingcv, + pipe->up_dev->ud_bus->ub_lock); + } pipe->up_callingxfer = xfer; mutex_exit(pipe->up_dev->ud_bus->ub_lock); if (!(pipe->up_flags & USBD_MPSAFE)) Index: src/sys/dev/usb/uvideo.c diff -u src/sys/dev/usb/uvideo.c:1.70 src/sys/dev/usb/uvideo.c:1.71 --- src/sys/dev/usb/uvideo.c:1.70 Sat Mar 12 16:51:10 2022 +++ src/sys/dev/usb/uvideo.c Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: uvideo.c,v 1.70 2022/03/12 16:51:10 riastradh Exp $ */ +/* $NetBSD: uvideo.c,v 1.71 2022/04/06 21:51:29 mlelstv Exp $ */ /* * Copyright (c) 2008 Patrick Mahoney @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvideo.c,v 1.70 2022/03/12 16:51:10 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvideo.c,v 1.71 2022/04/06 21:51:29 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -1696,7 +1696,7 @@ uvideo_stream_stop_xfer(struct uvideo_st } /* Give it some time to settle */ - usbd_delay_ms(vs->vs_parent->sc_udev, 1000); + usbd_delay_ms(vs->vs_parent->sc_udev, 20); /* Set to zero bandwidth alternate interface zero */ err = usbd_set_interface(vs->vs_iface, 0); @@ -2142,11 +2142,11 @@ static int uvideo_start_transfer(void *addr) { struct uvideo_stream *vs = addr; - int s, err; + int /*s, */err; - s = splusb(); + // s = splusb(); err = uvideo_stream_start_xfer(vs); - splx(s); + // splx(s); return err; } @@ -2155,11 +2155,11 @@ static int uvideo_stop_transfer(void *addr) { struct uvideo_stream *vs = addr; - int err, s; + int err/* , s*/; - s = splusb(); + // s = splusb(); err = uvideo_stream_stop_xfer(vs); - splx(s); + // splx(s); return err; } @@ -2174,7 +2174,7 @@ uvideo_get_control_group(void *addr, str usbd_status err; uint8_t control_id, ent_id, data[16]; uint16_t len; - int s; + // int s; /* request setup */ switch (group->group_id) { @@ -2204,9 +2204,9 @@ uvideo_get_control_group(void *addr, str USETW(req.wIndex, (ent_id << 8) | sc->sc_ifaceno); USETW(req.wLength, len); - s = splusb(); + // s = splusb(); err = usbd_do_request(sc->sc_udev, &req, data); - splx(s); + // splx(s); if (err != USBD_NORMAL_COMPLETION) { DPRINTF(("uvideo_set_control: error %s (%d)\n", usbd_errstr(err), err)); @@ -2235,7 +2235,7 @@ uvideo_set_control_group(void *addr, con usbd_status err; uint8_t control_id, ent_id, data[16]; /* long enough for all controls */ uint16_t len; - int s; + // int s; switch (group->group_id) { case VIDEO_CONTROL_PANTILT_RELATIVE: @@ -2296,9 +2296,9 @@ uvideo_set_control_group(void *addr, con USETW(req.wIndex, (ent_id << 8) | sc->sc_ifaceno); USETW(req.wLength, len); - s = splusb(); + // s = splusb(); err = usbd_do_request(sc->sc_udev, &req, data); - splx(s); + // splx(s); if (err != USBD_NORMAL_COMPLETION) { DPRINTF(("uvideo_set_control: error %s (%d)\n", usbd_errstr(err), err)); Index: src/sys/dev/usb/xhci.c diff -u src/sys/dev/usb/xhci.c:1.162 src/sys/dev/usb/xhci.c:1.163 --- src/sys/dev/usb/xhci.c:1.162 Sun Mar 13 11:30:04 2022 +++ src/sys/dev/usb/xhci.c Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: xhci.c,v 1.162 2022/03/13 11:30:04 riastradh Exp $ */ +/* $NetBSD: xhci.c,v 1.163 2022/04/06 21:51:29 mlelstv Exp $ */ /* * Copyright (c) 2013 Jonathan A. Kollasch @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.162 2022/03/13 11:30:04 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.163 2022/04/06 21:51:29 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -192,7 +192,7 @@ static void xhci_setup_ctx(struct usbd_p static void xhci_setup_route(struct usbd_pipe *, uint32_t *); static void xhci_setup_tthub(struct usbd_pipe *, uint32_t *); static void xhci_setup_maxburst(struct usbd_pipe *, uint32_t *); -static uint32_t xhci_bival2ival(uint32_t, uint32_t); +static uint32_t xhci_bival2ival(uint32_t, uint32_t, uint32_t); static void xhci_noop(struct usbd_pipe *); @@ -2440,8 +2440,6 @@ xhci_event_transfer(struct xhci_softc * xfer->ux_frlengths[xx->xx_isoc_done] -= XHCI_TRB_2_REM_GET(trb_2); xfer->ux_actlen += xfer->ux_frlengths[xx->xx_isoc_done]; - if (++xx->xx_isoc_done < xfer->ux_nframes) - return; } else if ((trb_3 & XHCI_TRB_3_ED_BIT) == 0) { if (xfer->ux_actlen == 0) @@ -2473,6 +2471,22 @@ xhci_event_transfer(struct xhci_softc * break; } + if (xfertype == UE_ISOCHRONOUS) { + switch (trbcode) { + case XHCI_TRB_ERROR_SHORT_PKT: + case XHCI_TRB_ERROR_SUCCESS: + break; + case XHCI_TRB_ERROR_MISSED_SERVICE: + case XHCI_TRB_ERROR_RING_UNDERRUN: + case XHCI_TRB_ERROR_RING_OVERRUN: + default: + xfer->ux_frlengths[xx->xx_isoc_done] = 0; + break; + } + if (++xx->xx_isoc_done < xfer->ux_nframes) + return; + } + /* * Try to claim this xfer for completion. If it has already * completed or aborted, drop it on the floor. @@ -3479,9 +3493,7 @@ xhci_setup_ctx(struct usbd_pipe *pipe) const u_int dci = xhci_ep_get_dci(ed); const uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); uint32_t *cp; - uint16_t mps = UGETW(ed->wMaxPacketSize); uint8_t speed = dev->ud_speed; - uint8_t ival = ed->bInterval; XHCIHIST_FUNC(); XHCIHIST_CALLARGS("pipe %#jx: slot %ju dci %ju speed %ju", @@ -3526,43 +3538,16 @@ xhci_setup_ctx(struct usbd_pipe *pipe) if (xfertype != UE_ISOCHRONOUS) cp[1] |= XHCI_EPCTX_1_CERR_SET(3); - if (xfertype == UE_CONTROL) - cp[4] = XHCI_EPCTX_4_AVG_TRB_LEN_SET(8); /* 6.2.3 */ - else if (USB_IS_SS(speed)) - cp[4] = XHCI_EPCTX_4_AVG_TRB_LEN_SET(mps); - else - cp[4] = XHCI_EPCTX_4_AVG_TRB_LEN_SET(UE_GET_SIZE(mps)); - xhci_setup_maxburst(pipe, cp); - switch (xfertype) { - case UE_CONTROL: - break; - case UE_BULK: - /* XXX Set MaxPStreams, HID, and LSA if streams enabled */ - break; - case UE_INTERRUPT: - if (pipe->up_interval != USBD_DEFAULT_INTERVAL) - ival = pipe->up_interval; - - ival = xhci_bival2ival(ival, speed); - cp[0] |= XHCI_EPCTX_0_IVAL_SET(ival); - break; - case UE_ISOCHRONOUS: - if (pipe->up_interval != USBD_DEFAULT_INTERVAL) - ival = pipe->up_interval; - - /* xHCI 6.2.3.6 Table 65, USB 2.0 9.6.6 */ - if (speed == USB_SPEED_FULL) - ival += 3; /* 1ms -> 125us */ - ival--; - cp[0] |= XHCI_EPCTX_0_IVAL_SET(ival); - break; - default: - break; - } - DPRINTFN(4, "setting ival %ju MaxBurst %#jx", - XHCI_EPCTX_0_IVAL_GET(cp[0]), XHCI_EPCTX_1_MAXB_GET(cp[1]), 0, 0); + DPRINTFN(4, "setting on dci %ju ival %ju mult %ju mps %#jx", + dci, XHCI_EPCTX_0_IVAL_GET(cp[0]), XHCI_EPCTX_0_MULT_GET(cp[0]), + XHCI_EPCTX_1_MAXP_SIZE_GET(cp[1])); + DPRINTFN(4, " maxburst %ju mep %#jx atl %#jx", + XHCI_EPCTX_1_MAXB_GET(cp[1]), + (XHCI_EPCTX_0_MAX_ESIT_PAYLOAD_HI_GET(cp[0]) << 16) + + XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_GET(cp[4]), + XHCI_EPCTX_4_AVG_TRB_LEN_GET(cp[4]), 0); /* rewind TR dequeue pointer in xHC */ /* can't use xhci_ep_get_dci() yet? */ @@ -3747,29 +3732,24 @@ xhci_setup_tthub(struct usbd_pipe *pipe, XHCI_SCTX_2_TT_PORT_NUM_SET(ttportnum); } -/* set up params for periodic endpoint */ -static void -xhci_setup_maxburst(struct usbd_pipe *pipe, uint32_t *cp) +static const usb_endpoint_ss_comp_descriptor_t * +xhci_get_essc_desc(struct usbd_pipe *pipe) { - struct xhci_pipe * const xpipe = (struct xhci_pipe *)pipe; struct usbd_device *dev = pipe->up_dev; usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc; - const uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); - usbd_desc_iter_t iter; const usb_cdc_descriptor_t *cdcd; - uint32_t maxb = 0; - uint16_t mps = UGETW(ed->wMaxPacketSize); - uint8_t speed = dev->ud_speed; - uint8_t mult = 0; + usbd_desc_iter_t iter; uint8_t ep; /* config desc is NULL when opening ep0 */ if (dev == NULL || dev->ud_cdesc == NULL) - goto no_cdcd; + return NULL; + cdcd = (const usb_cdc_descriptor_t *)usb_find_desc(dev, UDESC_INTERFACE, USBD_CDCSUBTYPE_ANY); if (cdcd == NULL) - goto no_cdcd; + return NULL; + usb_desc_iter_init(dev, &iter); iter.cur = (const void *)cdcd; @@ -3791,61 +3771,153 @@ xhci_setup_maxburst(struct usbd_pipe *pi } } if (cdcd != NULL && cdcd->bDescriptorType == UDESC_ENDPOINT_SS_COMP) { - const usb_endpoint_ss_comp_descriptor_t * esscd = - (const usb_endpoint_ss_comp_descriptor_t *)cdcd; - maxb = esscd->bMaxBurst; - mult = UE_GET_SS_ISO_MULT(esscd->bmAttributes); + return (const usb_endpoint_ss_comp_descriptor_t *)cdcd; } + return NULL; +} - no_cdcd: - /* 6.2.3.4, 4.8.2.4 */ - if (USB_IS_SS(speed)) { - /* USB 3.1 9.6.6 */ - cp[1] |= XHCI_EPCTX_1_MAXP_SIZE_SET(mps); - /* USB 3.1 9.6.7 */ - cp[1] |= XHCI_EPCTX_1_MAXB_SET(maxb); -#ifdef notyet - if (xfertype == UE_ISOCHRONOUS) { - } - if (XHCI_HCC2_LEC(sc->sc_hcc2) != 0) { - /* use ESIT */ - cp[4] |= XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_SET(x); - cp[0] |= XHCI_EPCTX_0_MAX_ESIT_PAYLOAD_HI_SET(x); +/* set up params for periodic endpoint */ +static void +xhci_setup_maxburst(struct usbd_pipe *pipe, uint32_t *cp) +{ + struct xhci_pipe * const xpipe = (struct xhci_pipe *)pipe; + struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); + struct usbd_device * const dev = pipe->up_dev; + usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc; + const uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); + uint16_t mps = UGETW(ed->wMaxPacketSize); + uint8_t speed = dev->ud_speed; + uint32_t maxb, mep, atl; + uint8_t ival, mult; + + const usb_endpoint_ss_comp_descriptor_t * esscd = + xhci_get_essc_desc(pipe); + + /* USB 2.0 9.6.6, xHCI 4.8.2.4, 6.2.3.2 - 6.2.3.8 */ + switch (xfertype) { + case UE_ISOCHRONOUS: + case UE_INTERRUPT: + if (USB_IS_SS(speed)) { + maxb = esscd ? esscd->bMaxBurst : UE_GET_TRANS(mps); + mep = esscd ? UGETW(esscd->wBytesPerInterval) : + UE_GET_SIZE(mps) * (maxb + 1); + if (esscd && xfertype == UE_ISOCHRONOUS && + XHCI_HCC2_LEC(sc->sc_hcc2) == 0) { + mult = UE_GET_SS_ISO_MULT(esscd->bmAttributes); + mult = (mult > 2) ? 2 : mult; + } else + mult = 0; - /* XXX if LEC = 1, set ESIT instead */ - cp[0] |= XHCI_EPCTX_0_MULT_SET(0); } else { - /* use ival */ + switch (speed) { + case USB_SPEED_HIGH: + maxb = UE_GET_TRANS(mps); + mep = UE_GET_SIZE(mps) * (maxb + 1); + break; + case USB_SPEED_FULL: + maxb = 0; + mep = UE_GET_SIZE(mps); + break; + default: + maxb = 0; + mep = 0; + break; + } + mult = 0; } -#endif - } else { - /* USB 2.0 9.6.6 */ - cp[1] |= XHCI_EPCTX_1_MAXP_SIZE_SET(UE_GET_SIZE(mps)); + mps = UE_GET_SIZE(mps); - /* 6.2.3.4 */ - if (speed == USB_SPEED_HIGH && - (xfertype == UE_ISOCHRONOUS || xfertype == UE_INTERRUPT)) { - maxb = UE_GET_TRANS(mps); - } else { - /* LS/FS or HS CTRL or HS BULK */ + if (pipe->up_interval == USBD_DEFAULT_INTERVAL) + ival = ed->bInterval; + else + ival = pipe->up_interval; + + ival = xhci_bival2ival(ival, speed, xfertype); + atl = mep; + break; + case UE_CONTROL: + case UE_BULK: + default: + if (USB_IS_SS(speed)) { + maxb = esscd ? esscd->bMaxBurst : 0; + } else maxb = 0; + + mps = UE_GET_SIZE(mps); + mep = 0; + mult = 0; + ival = 0; + if (xfertype == UE_CONTROL) + atl = 8; /* 6.2.3 */ + else + atl = mps; + break; + } + + switch (speed) { + case USB_SPEED_LOW: + break; + case USB_SPEED_FULL: + if (xfertype == UE_INTERRUPT) + if (mep > XHCI_EPCTX_MEP_FS_INTR) + mep = XHCI_EPCTX_MEP_FS_INTR; + if (xfertype == UE_ISOCHRONOUS) + if (mep > XHCI_EPCTX_MEP_FS_ISOC) + mep = XHCI_EPCTX_MEP_FS_ISOC; + break; + case USB_SPEED_HIGH: + if (xfertype == UE_INTERRUPT) + if (mep > XHCI_EPCTX_MEP_HS_INTR) + mep = XHCI_EPCTX_MEP_HS_INTR; + if (xfertype == UE_ISOCHRONOUS) + if (mep > XHCI_EPCTX_MEP_HS_ISOC) + mep = XHCI_EPCTX_MEP_HS_ISOC; + break; + case USB_SPEED_SUPER: + case USB_SPEED_SUPER_PLUS: + default: + if (xfertype == UE_INTERRUPT) + if (mep > XHCI_EPCTX_MEP_SS_INTR) + mep = XHCI_EPCTX_MEP_SS_INTR; + if (xfertype == UE_ISOCHRONOUS) { + if (speed == USB_SPEED_SUPER || + XHCI_HCC2_LEC(sc->sc_hcc2) == 0) { + if (mep > XHCI_EPCTX_MEP_SS_ISOC) + mep = XHCI_EPCTX_MEP_SS_ISOC; + } else { + if (mep > XHCI_EPCTX_MEP_SS_ISOC_LEC) + mep = XHCI_EPCTX_MEP_SS_ISOC_LEC; + } } - cp[1] |= XHCI_EPCTX_1_MAXB_SET(maxb); + break; } + xpipe->xp_maxb = maxb + 1; xpipe->xp_mult = mult + 1; + + cp[0] |= XHCI_EPCTX_0_MAX_ESIT_PAYLOAD_HI_SET(mep >> 16); + cp[0] |= XHCI_EPCTX_0_IVAL_SET(ival); + cp[0] |= XHCI_EPCTX_0_MULT_SET(mult); + cp[1] |= XHCI_EPCTX_1_MAXP_SIZE_SET(mps); + cp[1] |= XHCI_EPCTX_1_MAXB_SET(maxb); + cp[4] |= XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_SET(mep & 0xffff); + cp[4] |= XHCI_EPCTX_4_AVG_TRB_LEN_SET(atl); } /* - * Convert endpoint bInterval value to endpoint context interval value - * for Interrupt pipe. + * Convert usbdi bInterval value to xhci endpoint context interval value + * for periodic pipe. * xHCI 6.2.3.6 Table 65, USB 2.0 9.6.6 */ static uint32_t -xhci_bival2ival(uint32_t ival, uint32_t speed) +xhci_bival2ival(uint32_t ival, uint32_t speed, uint32_t xfertype) { - if (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) { - int i; + if (xfertype != UE_INTERRUPT && xfertype != UE_ISOCHRONOUS) + return 0; + + if (xfertype == UE_INTERRUPT && + (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL)) { + u_int i; /* * round ival down to "the nearest base 2 multiple of @@ -3858,9 +3930,22 @@ xhci_bival2ival(uint32_t ival, uint32_t break; } ival = i; + + /* 3 - 10 */ + ival = (ival < 3) ? 3 : ival; + } else if (speed == USB_SPEED_FULL) { + /* FS isoc */ + ival += 3; /* 1ms -> 125us */ + ival--; /* Interval = bInterval-1 */ + /* 3 - 18 */ + ival = (ival > 18) ? 18 : ival; + ival = (ival < 3) ? 3 : ival; } else { - /* Interval = bInterval-1 for SS/HS */ - ival--; + /* SS/HS intr/isoc */ + if (ival > 0) + ival--; /* Interval = bInterval-1 */ + /* 0 - 15 */ + ival = (ival > 15) ? 15 : ival; } return ival; Index: src/sys/dev/usb/xhcireg.h diff -u src/sys/dev/usb/xhcireg.h:1.19 src/sys/dev/usb/xhcireg.h:1.20 --- src/sys/dev/usb/xhcireg.h:1.19 Sun May 23 11:49:45 2021 +++ src/sys/dev/usb/xhcireg.h Wed Apr 6 21:51:29 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: xhcireg.h,v 1.19 2021/05/23 11:49:45 riastradh Exp $ */ +/* $NetBSD: xhcireg.h,v 1.20 2022/04/06 21:51:29 mlelstv Exp $ */ /*- * Copyright (c) 2010 Hans Petter Selasky. All rights reserved. @@ -105,7 +105,7 @@ #define XHCI_HCC2_CMC(x) __SHIFTOUT((x), __BIT(1)) /* CEC MaxExLatTooLg */ #define XHCI_HCC2_FSC(x) __SHIFTOUT((x), __BIT(2)) /* Foce Save Context */ #define XHCI_HCC2_CTC(x) __SHIFTOUT((x), __BIT(3)) /* Compliance Transc */ -#define XHCI_HCC2_LEC(x) __SHIFTOUT((x), __BIT(4)) /* Large ESIT Paylod */ +#define XHCI_HCC2_LEC(x) __SHIFTOUT((x), __BIT(4)) /* Large ESIT Payload */ #define XHCI_HCC2_CIC(x) __SHIFTOUT((x), __BIT(5)) /* Configuration Inf */ #define XHCI_HCC2_ETC(x) __SHIFTOUT((x), __BIT(6)) /* Extended TBC */ #define XHCI_HCC2_ETC_TSC(x) __SHIFTOUT((x), __BIT(7)) /* ExtTBC TRB Status */ @@ -648,6 +648,13 @@ struct xhci_trb { #define XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_MASK __BITS(16, 31) #define XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_SET(x) __SHIFTIN((x), XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_MASK) #define XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_GET(x) __SHIFTOUT((x), XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_MASK) +#define XHCI_EPCTX_MEP_FS_INTR 64U +#define XHCI_EPCTX_MEP_FS_ISOC (1*1024U) +#define XHCI_EPCTX_MEP_HS_INTR (3*1024U) +#define XHCI_EPCTX_MEP_HS_ISOC (3*1024U) +#define XHCI_EPCTX_MEP_SS_INTR (3*1024U) +#define XHCI_EPCTX_MEP_SS_ISOC (48*1024U) +#define XHCI_EPCTX_MEP_SS_ISOC_LEC (16*1024*1024U - 1) #define XHCI_INCTX_NON_CTRL_MASK 0xFFFFFFFCU