usb/181987: USB isochronous transfer of the USB driver (Mentor Graphics OTG: musb_otg) is not working.

Hans Petter Selasky hps at bitfrost.no
Tue Oct 15 07:10:02 UTC 2013


The following reply was made to PR usb/181987; it has been noted by GNATS.

From: Hans Petter Selasky <hps at bitfrost.no>
To: SAITOU Toshihide <toshi at ruby.ocn.ne.jp>
Cc: freebsd-gnats-submit at FreeBSD.org
Subject: Re: usb/181987: USB isochronous transfer of the USB driver (Mentor
 Graphics OTG: musb_otg) is not working.
Date: Tue, 15 Oct 2013 09:05:26 +0200

 This is a multi-part message in MIME format.
 --------------090607060603090803000207
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 On 09/10/13 13:01, SAITOU Toshihide wrote:
 >
 >> Number:         181987
 >> Category:       usb
 >> Synopsis:       USB isochronous transfer of the USB driver (Mentor Graphics OTG: musb_otg) is not working.
 >> Confidential:   no
 >> Severity:       non-critical
 >> Priority:       low
 >> Responsible:    freebsd-usb
 >> State:          open
 >> Quarter:
 >> Keywords:
 >> Date-Required:
 >> Class:          sw-bug
 >> Submitter-Id:   current-users
 >> Arrival-Date:   Tue Sep 10 11:10:00 UTC 2013
 >> Closed-Date:
 >> Last-Modified:
 >> Originator:     SAITOU Toshihide
 >> Release:        FreeBSD 10.0-CURRENT
 >> Organization:
 >> Environment:
 > FreeBSD bbb 10.0-CURRENT FreeBSD 10.0-CURRENT #1: Mon Sep  9 23:34:15 JST 2013     toshi at fbsd:/usr/obj/arm.armv6/usr/src/sys/BEAGLEBONE  arm
 >
 >> Description:
 > The patch attached is somewhat fixed the problem for the
 > LOGICOOL C920 but still most UVC devices are not working.
 >
 > My guess is that the not working device requires three
 > transactions per *microframe* for the data transfer rate as
 > the video streaming but the current driver performs one
 > transaction per microframe. The following page imply the
 > existence of the undocumented setting to perform so.
 > http://e2e.ti.com/support/embedded/wince/f/353/t/68966.aspx
 >
 >> How-To-Repeat:
 >
 >> Fix:
 >
 >
 >> Release-Note:
 >> Audit-Trail:
 >> Unformatted:
 > _______________________________________________
 > freebsd-usb at freebsd.org mailing list
 > http://lists.freebsd.org/mailman/listinfo/freebsd-usb
 > To unsubscribe, send any mail to "freebsd-usb-unsubscribe at freebsd.org"
 >
 
 Hi,
 
 Can you please test the attached patch and report back?
 
 --HPS
 
 --------------090607060603090803000207
 Content-Type: text/x-patch;
  name="musb.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="musb.diff"
 
 === sys/dev/usb/controller/musb_otg.c
 ==================================================================
 --- sys/dev/usb/controller/musb_otg.c	(revision 256504)
 +++ sys/dev/usb/controller/musb_otg.c	(local)
 @@ -646,8 +646,8 @@
  	count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
  
  	/* verify the packet byte count */
 -	if (count != td->max_frame_size) {
 -		if (count < td->max_frame_size) {
 +	if (count != td->max_packet_size) {
 +		if (count < td->max_packet_size) {
  			/* we have a short packet */
  			td->short_pkt = 1;
  			got_short = 1;
 @@ -775,7 +775,7 @@
  	if (csr & MUSB2_MASK_CSR0L_TXPKTRDY) {
  		return (1);		/* not complete */
  	}
 -	count = td->max_frame_size;
 +	count = td->max_packet_size;
  	if (td->remainder < count) {
  		/* we have a short packet */
  		td->short_pkt = 1;
 @@ -936,8 +936,8 @@
  	count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
  
  	/* verify the packet byte count */
 -	if (count != td->max_frame_size) {
 -		if (count < td->max_frame_size) {
 +	if (count != td->max_packet_size) {
 +		if (count < td->max_packet_size) {
  			/* we have a short packet */
  			td->short_pkt = 1;
  			got_short = 1;
 @@ -1126,7 +1126,7 @@
  	}
  
  	/* check for short packet */
 -	count = td->max_frame_size;
 +	count = td->max_packet_size;
  	if (td->remainder < count) {
  		/* we have a short packet */
  		td->short_pkt = 1;
 @@ -1453,8 +1453,8 @@
  	/*
  	 * Check for short or invalid packet:
  	 */
 -	if (count != td->max_frame_size) {
 -		if (count < td->max_frame_size) {
 +	if (count != td->max_packet_size) {
 +		if (count < td->max_packet_size) {
  			/* we have a short packet */
  			td->short_pkt = 1;
  			got_short = 1;
 @@ -1592,7 +1592,7 @@
  		return (1);		/* not complete */
  	}
  	/* check for short packet */
 -	count = td->max_frame_size;
 +	count = td->max_packet_size;
  	if (td->remainder < count) {
  		/* we have a short packet */
  		td->short_pkt = 1;
 @@ -1661,7 +1661,8 @@
  	}
  
  	/* Max packet size */
 -	MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, td->max_packet);
 +	MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, td->max_packet_size |
 +	    ((td->max_packet_count - 1) << 11));
  
  	/* write command */
  	MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
 @@ -1726,13 +1727,17 @@
  		    td->hport);
  
  		/* RX NAK timeout */
 -		MUSB2_WRITE_1(sc, MUSB2_REG_RXNAKLIMIT, MAX_NAK_TO);
 +		if (td->transfer_type & MUSB2_MASK_TI_PROTO_ISOC)
 +			MUSB2_WRITE_1(sc, MUSB2_REG_RXNAKLIMIT, 0);
 +		else
 +			MUSB2_WRITE_1(sc, MUSB2_REG_RXNAKLIMIT, MAX_NAK_TO);
  
  		/* Protocol, speed, device endpoint */
  		MUSB2_WRITE_1(sc, MUSB2_REG_RXTI, td->transfer_type);
  
  		/* Max packet size */
 -		MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, td->max_packet);
 +		MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, td->max_packet_size |
 +		    ((td->max_packet_count - 1) << 11));
  
  		/* Data Toggle */
  		csrh = MUSB2_READ_1(sc, MUSB2_REG_RXCSRH);
 @@ -1797,8 +1802,8 @@
  	/*
  	 * Check for short or invalid packet:
  	 */
 -	if (count != td->max_frame_size) {
 -		if (count < td->max_frame_size) {
 +	if (count != td->max_packet_size) {
 +		if (count < td->max_packet_size) {
  			/* we have a short packet */
  			td->short_pkt = 1;
  			got_short = 1;
 @@ -1938,7 +1943,7 @@
  		return (0);	/* complete */
  	}
  
 -	if (csr & MUSB2_MASK_CSRL_TXNAKTO ) {
 +	if (csr & MUSB2_MASK_CSRL_TXNAKTO) {
  		/* 
  		 * Flush TX FIFO before clearing NAK TO
  		 */
 @@ -1989,7 +1994,7 @@
  	}
  
  	/* check for short packet */
 -	count = td->max_frame_size;
 +	count = td->max_packet_size;
  	if (td->remainder < count) {
  		/* we have a short packet */
  		td->short_pkt = 1;
 @@ -2069,13 +2074,17 @@
  	    td->hport);
  
  	/* TX NAK timeout */
 -	MUSB2_WRITE_1(sc, MUSB2_REG_TXNAKLIMIT, MAX_NAK_TO);
 +	if (td->transfer_type & MUSB2_MASK_TI_PROTO_ISOC)
 +		MUSB2_WRITE_1(sc, MUSB2_REG_TXNAKLIMIT, 0);
 +	else
 +		MUSB2_WRITE_1(sc, MUSB2_REG_TXNAKLIMIT, MAX_NAK_TO);
  
  	/* Protocol, speed, device endpoint */
  	MUSB2_WRITE_1(sc, MUSB2_REG_TXTI, td->transfer_type);
  
  	/* Max packet size */
 -	MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, td->max_packet);
 +	MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, td->max_packet_size |
 +	    ((td->max_packet_count - 1) << 11));
  
  	if (!td->transaction_started) {
  		csrh = MUSB2_READ_1(sc, MUSB2_REG_TXCSRH);
 @@ -2444,7 +2453,6 @@
  		}
  
  		temp.transfer_type |= ep_no;
 -		td->max_packet = xfer->max_packet_size;
  		td->toggle = xfer->endpoint->toggle_next;
  	}
  
 @@ -2534,7 +2542,8 @@
  
  			/* regular data transfer */
  
 -			temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
 +			temp.short_pkt = ((!xfer->flags_int.isochronous_xfr) &&
 +			    xfer->flags.force_short_xfer) ? 0 : 1;
  		}
  
  		musbotg_setup_standard_chain_sub(&temp);
 @@ -3158,7 +3167,12 @@
  
  		if (dynfifo) {
  			if (frx && (temp <= nrx)) {
 -				if (temp < 8) {
 +				if (temp == 1) {
 +					frx = 12;	/* 4K */
 +					MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ, 
 +					    MUSB2_VAL_FIFOSZ_4096 |
 +					    MUSB2_MASK_FIFODB);
 +				} else if (temp < 8) {
  					frx = 10;	/* 1K */
  					MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ, 
  					    MUSB2_VAL_FIFOSZ_512 |
 @@ -3175,7 +3189,12 @@
  				offset += (1 << frx);
  			}
  			if (ftx && (temp <= ntx)) {
 -				if (temp < 8) {
 +				if (temp == 1) {
 +					ftx = 12;	/* 4K */
 +					MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ,
 +	 				    MUSB2_VAL_FIFOSZ_4096 |
 +	 				    MUSB2_MASK_FIFODB);
 +				} else if (temp < 8) {
  					ftx = 10;	/* 1K */
  					MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ,
  	 				    MUSB2_VAL_FIFOSZ_512 |
 @@ -4042,7 +4061,7 @@
  	 * reasonable dummies:
  	 */
  	parm->hc_max_packet_size = 0x400;
 -	parm->hc_max_frame_size = 0x400;
 +	parm->hc_max_frame_size = 0xc00;
  
  	if ((parm->methods == &musbotg_device_isoc_methods) ||
  	    (parm->methods == &musbotg_device_intr_methods))
 @@ -4116,7 +4135,8 @@
  			td = USB_ADD_BYTES(parm->buf, parm->size[0]);
  
  			/* init TD */
 -			td->max_frame_size = xfer->max_frame_size;
 +			td->max_packet_size = xfer->max_packet_size;
 +			td->max_packet_count = xfer->max_packet_count;
  			td->ep_no = ep_no;
  			td->obj_next = last_obj;
  
 === sys/dev/usb/controller/musb_otg.h
 ==================================================================
 --- sys/dev/usb/controller/musb_otg.h	(revision 256504)
 +++ sys/dev/usb/controller/musb_otg.h	(local)
 @@ -315,10 +315,10 @@
  	struct usb_page_cache *pc;
  	uint32_t offset;
  	uint32_t remainder;
 -	uint16_t max_frame_size;	/* packet_size * mult */
 +	uint16_t max_packet_size;
  	uint8_t	ep_no;
  	uint8_t	transfer_type;
 -	uint8_t	max_packet;
 +	uint8_t max_packet_count;
  	uint8_t	error:1;
  	uint8_t	alt_next:1;
  	uint8_t	short_pkt:1;
 
 --------------090607060603090803000207--


More information about the freebsd-usb mailing list