On Thu, 17 Mar 2011, Daniele Capuano wrote: > Hullo, > I'm a newbie in kernel development. I'm developing both the host-side > and the gadget-side of a usb connection, and i'm trying to setup an > isochronous transfer from the gadget to the host. My application needs > to allow the gadget to start sending a continuous flow of data > whenever it wants, thus the host has to wait until data are sent from > the gadget, and only then it can do its work. > So, I tryed two scenarios: > - first, i submitted the urb on the host-side as soon as possible, > while the gadget submitted isoc urbs only when data were available. In > this case, the host-side isoc-read callback was executed immediately > (i.e. the urb seems to complete) but no data was sent (actual_length = > 0). Both the urb->status and the urb->iso_frame_desc[0].status were > always zero. That's not right. If the gadget isn't sending data then iso_frame_desc[n].status should not be 0. It should be -EPROTO or something like that. If status is 0, it means that the gadget actually did send a zero-length packet rather than sending nothing at all. > When I started sending data from the gadget, no changes > happened to the host, even though I noticed that some sporadic buffer > has been received (one or two times); > - as the second scenario, I'm trying to let the gadget to start > sending packets first, while the host waits a little time to start > receiving. As a consequence, the first two or three buffers are > correctly received by the host, but then no more data is received > (i.e. actual_length = 0 and status = 0). The gadget cannot send any data until the host asks for it. > I use: > - a kernel 2.6.31.12 with the RT patch on the host; What type of host controller? Why not use a more recent kernel, like 2.6.37? > - a a kernel 2.6.32-psp on the gadget (i.e. a beagleboard with a > OMAP3550 core). I used openembedded/bitbake to build the kernel for > the gadget system. > > I use the following code to initialize the urb (host-side): > > urb->dev = usb->udev; > urb->context = dev; > urb->pipe = usb_rcvisocpipe(usb->udev, iso_in->iso_in_endpointAddr); > urb->interval = 6; > urb->transfer_flags = URB_ISO_ASAP; > urb->transfer_buffer = iso_in->iso_in_buffer; > urb->complete = thmx_read_iso_callback; > urb->number_of_packets = NUM_ISO_PACKETS; > urb->transfer_buffer_length = iso_in->iso_in_size; > for (i=0; i < NUM_ISO_PACKETS; i++) { > urb->iso_frame_desc[i].offset = i; This is almost certainly wrong. If NUM_ISO_PACKETS were larger than 1 then the packet buffers would overlap, unless the endpoint's maxpacket size is 1. More likely this should be i * iso_in->iso_in_size. > urb->iso_frame_desc[i].length = iso_in->iso_in_size; > } > > (NUM_ISO_PACKETS is 1). The callback is quite simple: > > status = urb->iso_frame_desc[0].status; > if (status && > !(status == -ENOENT || > status == -ECONNRESET || > status == -ESHUTDOWN)) { > dbg("%s - nonzero read isoc status received: %d", > __FUNCTION__, status); > return; > } > buf = urb->transfer_buffer; > actual_length = urb->iso_frame_desc[0].actual_length; > if (actual_length > 0) { > /* wake_up_worker_thread() */ > } > retval = usb_submit_urb(urb, GFP_KERNEL); This is wrong. Completion callbacks run with interrupts disabled; they cannot use GFP_KERNEL. You must use GFP_ATOMIC. > if (retval) { > err("%s - failed submitting isoc read urb, error %d", > __FUNCTION__, retval); > } > > on the gadget, i initialized the usb_endpoint_descriptor struct as follows: > > static struct usb_endpoint_descriptor > hs_iso_in_desc = { > .bLength = USB_DT_ENDPOINT_SIZE, > .bDescriptorType = USB_DT_ENDPOINT, > .bmAttributes = USB_ENDPOINT_SYNC_NONE | USB_ENDPOINT_XFER_ISOC, > .wMaxPacketSize = cpu_to_le16(512), > .bInterval = 6, > }; What happened to .bEndpointAddress? You have to specify USB_DIR_IN. > I suspect that it should be a synchronization issue. I doubt it. More likely the gadget code isn't sending the packets properly. > I also tryed to > change the USB_ENDPOINT_SYNC_* attribute using SYNC_SYNC but without > luck... Could someone help me? > Thanks in advance, Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html