snd_uaudio recording not working

Hans Petter Selasky hselasky at c2i.net
Mon May 10 23:38:30 UTC 2010


Hi,

I suspect I've found the issue.

Can you try to apply the attached patch by hand?

It appears one of my optimisations have broken something.

--HPS
-------------- next part --------------
--- src/sys/dev/usb/controller/ehci.c	2010-04-22 23:36:13.000000000 0000
+++ src/sys/dev/usb/controller/ehci.c	2010-04-22 23:36:13.000000000 0000
@@ -1352,22 +1352,32 @@
 		}
 	} else if (methods == &ehci_device_isoc_hs_methods) {
 		ehci_itd_t *td;
-		uint8_t n = (xfer->nframes & 7);
 
 		/* isochronous high speed transfer */
 
 		/* check last transfer */
 		td = xfer->td_transfer_last;
 		usb_pc_cpu_invalidate(td->page_cache);
-		if (n == 0)
-			status = td->itd_status[7];
-		else
-			status = td->itd_status[n-1];
+		status = td->itd_status[0];
+		status |= td->itd_status[1];
+		status |= td->itd_status[2];
+		status |= td->itd_status[3];
+		status |= td->itd_status[4];
+		status |= td->itd_status[5];
+		status |= td->itd_status[6];
+		status |= td->itd_status[7];
 
 		/* also check first transfer */
 		td = xfer->td_transfer_first;
 		usb_pc_cpu_invalidate(td->page_cache);
 		status |= td->itd_status[0];
+		status |= td->itd_status[1];
+		status |= td->itd_status[2];
+		status |= td->itd_status[3];
+		status |= td->itd_status[4];
+		status |= td->itd_status[5];
+		status |= td->itd_status[6];
+		status |= td->itd_status[7];
 
 		/* if no transactions are active we continue */
 		if (!(status & htohc32(sc, EHCI_ITD_ACTIVE))) {
@@ -2799,14 +2809,15 @@
 	uint8_t x;
 	uint8_t td_no;
 	uint8_t page_no;
+	uint8_t shift = usbd_xfer_get_fps_shift(xfer);
 
 #ifdef USB_DEBUG
 	uint8_t once = 1;
 
 #endif
 
-	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
-	    xfer, xfer->endpoint->isoc_next, xfer->nframes);
+	DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n",
+	    xfer, xfer->endpoint->isoc_next, xfer->nframes, (int)shift);
 
 	/* get the current frame index */
 
@@ -2820,7 +2831,7 @@
 	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
 
 	if ((xfer->endpoint->is_synced == 0) ||
-	    (buf_offset < ((xfer->nframes + 7) / 8))) {
+	    (buf_offset < (((xfer->nframes << shift) + 7) / 8))) {
 		/*
 		 * If there is data underflow or the pipe queue is empty we
 		 * schedule the transfer a few frames ahead of the current
@@ -2844,7 +2855,7 @@
 	 */
 	xfer->isoc_time_complete =
 	    usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset +
-	    ((xfer->nframes + 7) / 8);
+	    (((xfer->nframes << shift) + 7) / 8);
 
 	/* get the real number of frames */
 
--- src/sys/dev/usb/usb_hub.c	2010-05-05 19:58:31.000000000 0000
+++ src/sys/dev/usb/usb_hub.c	2010-05-05 19:58:31.000000000 0000
@@ -1230,6 +1230,11 @@
 	if (udev->flags.usb_mode != USB_MODE_HOST)
 		return;		/* not supported */
 
+	if (xfer->flags_int.bandwidth_reclaimed != 0)
+		return;		/* bandwidth already allocated */
+
+	xfer->flags_int.bandwidth_reclaimed = 1;
+
 	xfer->endpoint->refcount_bw++;
 	if (xfer->endpoint->refcount_bw != 1)
 		return;		/* already allocated */
@@ -1310,6 +1315,11 @@
 	if (udev->flags.usb_mode != USB_MODE_HOST)
 		return;		/* not supported */
 
+	if (xfer->flags_int.bandwidth_reclaimed == 0)
+		return;		/* bandwidth already freed */
+
+	xfer->flags_int.bandwidth_reclaimed = 0;
+
 	xfer->endpoint->refcount_bw--;
 	if (xfer->endpoint->refcount_bw != 0)
 		return;		/* still allocated */


More information about the freebsd-usb mailing list