isoc-in endpoint transfers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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. 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).

I use:
- a kernel 2.6.31.12 with the RT patch on the host;
- 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;
           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);
   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,
};

I suspect that it should be a synchronization issue. I also tryed to
change the USB_ENDPOINT_SYNC_* attribute using SYNC_SYNC but without
luck... Could someone help me?
Thanks in advance,

Daniele
--
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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux