NetBSD Problem Report #56115

From sc.dying@gmail.com  Sun Apr 18 12:15:44 2021
Return-Path: <sc.dying@gmail.com>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id E4CFC1A923B
	for <gnats-bugs@gnats.NetBSD.org>; Sun, 18 Apr 2021 12:15:43 +0000 (UTC)
Message-Id: <ebacb271-4b5a-958f-abdf-cec0d5807d4e@gmail.com>
Date: Sun, 18 Apr 2021 12:15:36 +0000
From: sc.dying@gmail.com
To: gnats-bugs@NetBSD.org
Subject: uvideo does not work on rpi4

>Number:         56115
>Category:       kern
>Synopsis:       uvideo does not work on rpi4
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Apr 18 12:20:00 +0000 2021
>Last-Modified:  Sat Jul 10 13:35:01 +0000 2021
>Originator:     sc.dying@gmail.com
>Release:        NetBSD-current 9.99.81
>Organization:
>Environment:
System: NetBSD  9.99.81 NetBSD 9.99.81 (GENERIC64) #0: Sat Apr 10 04:10:21 UTC 2021  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/evbarm/compile/GENERIC64 evbarm aarch64
Architecture: aarch64
Machine: evbarm
>Description:

My webcams that work on NetBSD-current/amd64 with Intel chipset
do not work on rpi4. mplayer shows simple black window.

% mplayer tv://
[...]
Audio: no sound
Starting playback...
v4l2: select timeout
v4l2: select timeout
v4l2: select timeout
v4l2: select timeout
v4l2: select timeout
v4l2: select timeout
v4l2: select timeout

>How-To-Repeat:

Install NetBSD-current/evbarm-aarch64 on Rpi4,
install multimedia/mplayer,
connect webcam which supports UVC protocol,
and run mplayer tv://.

>Fix:

Yes, please.

>Audit-Trail:
From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/56115: uvideo does not work on rpi4
Date: Wed, 9 Jun 2021 06:10:14 +0000

 not sent to gnats (send to gnats-bugs@, gnats-admin@ doesn't go
 anywhere useful)

    ------

 From: sc.dying@gmail.com
 To: kern-bug-people@netbsd.org, gnats-admin@netbsd.org
 Subject: Re: kern/56115: uvideo does not work on rpi4
 Date: Mon, 19 Apr 2021 08:18:01 +0000

 I rebuilt kernel with {USB,XHCI}_DEBUG, set
 sysctl -w hw.xhci.debug=10, and re-run mplayer.

 % mplayer tv://
 [...]
 Selected video codec: [rawyuy2] vfm: raw (RAW YU[  43.2245361] input control context: 32 bytes @ 0xffffc000adef1000
 [  43.2385004] 00 00 00 00 09 00 00 00  00 00 00 00 00 00 00 00 | ................
 [  43.2457881] 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 | ................
 [  43.2457881] input endpoint context: 32 bytes @ 0xffffc000adef1080
 [  43.2591506] 00 00 00 00 28 02 fc 03  01 50 82 08 00 00 00 00 | ....(....P......
 [  43.2664396] fc 03 00 00 00 00 00 00  00 00 00 00 00 00 00 00 | ................
 [  43.2664396] output context: 32 bytes @ 0xffffc000adeef060
 [  43.2791086] 01 00 00 00 28 02 fc 03  01 50 82 08 00 00 00 00 | ....(....P......
 [  43.2791086] fc 03 00 00 00 00 00 00  00 00 00 00 00 00 00 00 | ................
 Y2)
 ==========================================================================
 Audio: no sound
 Starting playback...
 v4l2: select timeout
 v4l2: select timeout
 v4l2: select timeout
 v4l2: select timeout
 v4l2: select timeout
 v4l2: select timeout
 v4l2: select timeout

 I've found some ERRs in vmstat -u usbhist.

 1618818118.241226 xhci_intr#21@0: called!
 1618818118.241227 xhci_intr1#21@0: called: USBSTS 0x00000018
 1618818118.241231 xhci_softintr#21@0: called: er: xr_ep 146 xr_cs 0
 1618818118.241232 xhci_handle_event#27@0: called: event: 0xffffc0009d97f920 0x0000000008825000 0x12000000 0x03038000
 1618818118.241232 xhci_event_transfer#26@0: called!
 1618818118.241232 xhci_event_transfer#26@0: ERR 18 slot 3 dci 3
 1618818118.241233 xhci_device_isoc_done#1@0: called: 0xffff0000fb332680 slot 3 dci 3
 1618818118.241350 xhci_intr#22@0: called!
 1618818118.241351 xhci_intr1#22@0: called: USBSTS 0x00000018
 1618818118.241355 xhci_softintr#22@0: called: er: xr_ep 147 xr_cs 0
 1618818118.241355 xhci_handle_event#28@0: called: event: 0xffffc0009d97f930 0x0000000008825010 0x12000000 0x03038000
 1618818118.241355 xhci_event_transfer#27@0: called!
 1618818118.241356 xhci_event_transfer#27@0: ERR 18 slot 3 dci 3
 1618818118.241474 xhci_intr#23@0: called!
 1618818118.241475 xhci_intr1#23@0: called: USBSTS 0x00000018
 1618818118.241479 xhci_softintr#23@0: called: er: xr_ep 148 xr_cs 0
 1618818118.241479 xhci_handle_event#29@0: called: event: 0xffffc0009d97f940 0x0000000008825020 0x12000000 0x03038000
 1618818118.241479 xhci_event_transfer#28@0: called!
 1618818118.241480 xhci_event_transfer#28@0: ERR 18 slot 3 dci 3

 It looks like running out of bandwidth.


From: sc.dying@gmail.com
To: gnats-bugs@netbsd.org, kern-bug-people@netbsd.org,
 gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Cc: 
Subject: Re: kern/56115: uvideo does not work on rpi4
Date: Sat, 10 Jul 2021 02:51:12 +0000

 This is a multi-part message in MIME format.
 --------------45EF0F7AF57EF5A266C127A5
 Content-Type: text/plain; charset=windows-1252
 Content-Transfer-Encoding: 7bit

 On 2021/06/09 6:15, David Holland wrote:
 > The following reply was made to PR kern/56115; it has been noted by GNATS.
 > 
 > From: David Holland <dholland-bugs@netbsd.org>
 > To: gnats-bugs@netbsd.org
 > Cc: 
 > Subject: Re: kern/56115: uvideo does not work on rpi4
 > Date: Wed, 9 Jun 2021 06:10:14 +0000
 > 
 >  not sent to gnats (send to gnats-bugs@, gnats-admin@ doesn't go
 >  anywhere useful)

 Thank you for forwarding.

 >  From: sc.dying@gmail.com
 >  To: kern-bug-people@netbsd.org, gnats-admin@netbsd.org
 >  Subject: Re: kern/56115: uvideo does not work on rpi4
 >  Date: Mon, 19 Apr 2021 08:18:01 +0000
 >  
 >  I rebuilt kernel with {USB,XHCI}_DEBUG, set
 >  sysctl -w hw.xhci.debug=10, and re-run mplayer.
 >  
 >  % mplayer tv://
 >  [...]
 >  Selected video codec: [rawyuy2] vfm: raw (RAW YU[  43.2245361] input control context: 32 bytes @ 0xffffc000adef1000
 >  [  43.2385004] 00 00 00 00 09 00 00 00  00 00 00 00 00 00 00 00 | ................
 >  [  43.2457881] 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 | ................
 >  [  43.2457881] input endpoint context: 32 bytes @ 0xffffc000adef1080
 >  [  43.2591506] 00 00 00 00 28 02 fc 03  01 50 82 08 00 00 00 00 | ....(....P......
 >  [  43.2664396] fc 03 00 00 00 00 00 00  00 00 00 00 00 00 00 00 | ................

 Currently Max ESIT Payload in periodic endpoint context is 0.
 VL805 on rpi4 strictly treats this value as an upper limit of transfer
 size for periodic endpoint, so the xfer fails with Bandwidth Overrun Error.

 Attached diff should fix it.


 --------------45EF0F7AF57EF5A266C127A5
 Content-Type: text/plain; charset=UTF-8;
  name="xhci.epctx.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="xhci.epctx.diff"

 - Set proper Max ESIT Payload value for interrupt/isoc endpoint context.
 - Set proper Average TRB Length value.
 - Not tested on superspeed/superspeedplus isochronous device.


 --- src/sys/dev/usb/xhcireg.h.orig	2021-05-23 12:05:57.038776963 +0000
 +++ src/sys/dev/usb/xhcireg.h	2021-05-29 06:15:54.861045575 +0000
 @@ -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
 --- src/sys/dev/usb/xhci.c.orig	2021-06-12 20:21:19.390313667 +0000
 +++ src/sys/dev/usb/xhci.c	2021-07-08 13:04:24.656596606 +0000
 @@ -188,7 +188,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 *);

 @@ -3520,9 +3520,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",
 @@ -3567,43 +3565,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? */
 @@ -3788,29 +3759,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;

 @@ -3832,61 +3798,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
 @@ -3899,9 +3957,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;


 --------------45EF0F7AF57EF5A266C127A5--

From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/56115: uvideo does not work on rpi4
Date: Sat, 10 Jul 2021 07:22:50 -0000 (UTC)

 sc.dying@gmail.com writes:

 >Currently Max ESIT Payload in periodic endpoint context is 0.
 >VL805 on rpi4 strictly treats this value as an upper limit of transfer
 >size for periodic endpoint, so the xfer fails with Bandwidth Overrun Error.

 >Attached diff should fix it.

 Also fixes USB audio.

From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/56115: uvideo does not work on rpi4
Date: Sat, 10 Jul 2021 09:38:32 -0000 (UTC)

 mlelstv@serpens.de (Michael van Elst) writes:

 >The following reply was made to PR kern/56115; it has been noted by GNATS.

 >From: mlelstv@serpens.de (Michael van Elst)
 >To: gnats-bugs@netbsd.org
 >Cc: 
 >Subject: Re: kern/56115: uvideo does not work on rpi4
 >Date: Sat, 10 Jul 2021 07:22:50 -0000 (UTC)

 > sc.dying@gmail.com writes:
 > 
 > >Currently Max ESIT Payload in periodic endpoint context is 0.
 > >VL805 on rpi4 strictly treats this value as an upper limit of transfer
 > >size for periodic endpoint, so the xfer fails with Bandwidth Overrun Error.
 > 
 > >Attached diff should fix it.
 > 
 > Also fixes USB audio.
 > 


 But it probably exposes a different issue then (uaudio has some
 extra debug output):

 [  9769.030793] audio0(uaudio0): trigger_input failed: errno=5

 EIO. Either uaudio_chan_open() or uaudio_chan_alloc_buffers() failed.

 [  9769.030793] audio0(uaudio0): audio_drain: device timeout, seq=7, usrbuf=46336/H69120, outbuf=2880/11520
 [  9769.030793] uaudio0: ptransfer error 6

 That's USBD_CANCELLED.


 [  9769.030793] panic: kernel diagnostic assertion "xfer == SIMPLEQ_FIRST(&pipe->up_queue)" failed: file "/scratch/netbsd-current/src/sys/dev/usb/usbdi.c", line 1050 xfer 0xffff0000d6f2e580 is not start of queue (0xffff0000d6f2e440 is at start)
 [  9769.030793] cpu0: Begin traceback...
 [  9769.030793] trace fp ffffc0009de17af0
 [  9769.030793] fp ffffc0009de17b20 vpanic() at ffffc0000056b5bc netbsd:vpanic+0x14c
 [  9769.030793] fp ffffc0009de17b80 kern_assert() at ffffc000007dea88 netbsd:kern_assert+0x58
 [  9769.030793] fp ffffc0009de17c10 usb_transfer_complete() at ffffc00000141600 netbsd:usb_transfer_complete+0x38c
 [  9769.030793] fp ffffc0009de17c50 xhci_softintr() at ffffc000001ef69c netbsd:xhci_softintr+0x478
 [  9769.030793] fp ffffc0009de17cd0 usb_soft_intr() at ffffc0000013d368 netbsd:usb_soft_intr+0x24
 [  9769.030793] fp ffffc0009de17d30 softint_dispatch() at ffffc00000534fe0 netbsd:softint_dispatch+0xe0
 [  9769.030793] fp ffffc0009dda8cc0 cpu_switchto_softint() at ffffc000000a5800 netbsd:cpu_switchto_softint+0x70
 [  9769.030793] fp 0000000000000000 max_watchpoint() at ffffc00000c466fc ffffc00000c466fc
 [  9769.030793] cpu0: End traceback...


From: sc.dying@gmail.com
To: gnats-bugs@netbsd.org, kern-bug-people@netbsd.org,
 gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Cc: 
Subject: Re: kern/56115: uvideo does not work on rpi4
Date: Sat, 10 Jul 2021 13:29:53 +0000

 On 2021/07/10 9:40, Michael van Elst wrote:
 > The following reply was made to PR kern/56115; it has been noted by GNATS.
 > 
 > From: mlelstv@serpens.de (Michael van Elst)
 > To: gnats-bugs@netbsd.org
 > Cc: 
 > Subject: Re: kern/56115: uvideo does not work on rpi4
 > Date: Sat, 10 Jul 2021 09:38:32 -0000 (UTC)
 > 
 >  mlelstv@serpens.de (Michael van Elst) writes:
 >  
 >  >The following reply was made to PR kern/56115; it has been noted by GNATS.
 >  
 >  >From: mlelstv@serpens.de (Michael van Elst)
 >  >To: gnats-bugs@netbsd.org
 >  >Cc: 
 >  >Subject: Re: kern/56115: uvideo does not work on rpi4
 >  >Date: Sat, 10 Jul 2021 07:22:50 -0000 (UTC)
 >  
 >  > sc.dying@gmail.com writes:
 >  > 
 >  > >Currently Max ESIT Payload in periodic endpoint context is 0.
 >  > >VL805 on rpi4 strictly treats this value as an upper limit of transfer
 >  > >size for periodic endpoint, so the xfer fails with Bandwidth Overrun Error.
 >  > 
 >  > >Attached diff should fix it.
 >  > 
 >  > Also fixes USB audio.
 >  > 
 >  
 >  
 >  But it probably exposes a different issue then (uaudio has some
 >  extra debug output):
 >  
 >  [  9769.030793] audio0(uaudio0): trigger_input failed: errno=5
 >  
 >  EIO. Either uaudio_chan_open() or uaudio_chan_alloc_buffers() failed.

 Depending on size of buffer, large allocation may fail because of
 fragmented DMA buffer.

 >  
 >  [  9769.030793] audio0(uaudio0): audio_drain: device timeout, seq=7, usrbuf=46336/H69120, outbuf=2880/11520
 >  [  9769.030793] uaudio0: ptransfer error 6
 >  
 >  That's USBD_CANCELLED.
 >  
 >  
 >  [  9769.030793] panic: kernel diagnostic assertion "xfer == SIMPLEQ_FIRST(&pipe->up_queue)" failed: file "/scratch/netbsd-current/src/sys/dev/usb/usbdi.c", line 1050 xfer 0xffff0000d6f2e580 is not start of queue (0xffff0000d6f2e440 is at start)
 >  [  9769.030793] cpu0: Begin traceback...
 >  [  9769.030793] trace fp ffffc0009de17af0
 >  [  9769.030793] fp ffffc0009de17b20 vpanic() at ffffc0000056b5bc netbsd:vpanic+0x14c
 >  [  9769.030793] fp ffffc0009de17b80 kern_assert() at ffffc000007dea88 netbsd:kern_assert+0x58
 >  [  9769.030793] fp ffffc0009de17c10 usb_transfer_complete() at ffffc00000141600 netbsd:usb_transfer_complete+0x38c
 >  [  9769.030793] fp ffffc0009de17c50 xhci_softintr() at ffffc000001ef69c netbsd:xhci_softintr+0x478
 >  [  9769.030793] fp ffffc0009de17cd0 usb_soft_intr() at ffffc0000013d368 netbsd:usb_soft_intr+0x24
 >  [  9769.030793] fp ffffc0009de17d30 softint_dispatch() at ffffc00000534fe0 netbsd:softint_dispatch+0xe0
 >  [  9769.030793] fp ffffc0009dda8cc0 cpu_switchto_softint() at ffffc000000a5800 netbsd:cpu_switchto_softint+0x70
 >  [  9769.030793] fp 0000000000000000 max_watchpoint() at ffffc00000c466fc ffffc00000c466fc
 >  [  9769.030793] cpu0: End traceback...

 I think this is an another problem.

 https://mail-index.netbsd.org/netbsd-bugs/2021/04/28/msg071340.html

 > Does xhci_event_transfer() forget to increment xx_isoc_done and
 > avoid calling usb_transfer_comeplete() in error paths?
 > When an error occurs while isoc transfer, i.e. completion code is not
 > SUCCESS nor SHORT_PKT, usb_transfer_comeplete is called without
 > incrementing xx_isoc_done and the xfer is removed from up_queue.
 > Then, usb_transfer_comeplete is called at the last of transferring
 > ux_frlengths[], but it cannot find the xfer in up_queue and fires KASSERT.

 I managed to fix by following patch but it was incomplete.
 The fix should also take care of MISSED_SRV, RING_UNDERRUN and RING_OVERRUN
 errors.

 --- src/sys/dev/usb/xhci.c.orig	2021-01-05 22:12:39.918386246 +0000
 +++ src/sys/dev/usb/xhci.c	2021-04-28 22:13:30.751444109 +0000
 @@ -2050,8 +2050,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)
 @@ -2107,6 +2105,19 @@ 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;
 +		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.

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.