Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User mode USB isochronous transfer from device-to-host

Tags:

c

linux

usb

I am currently trying to interface with a USB audio device from user land. I currently have the device fully enumerated and I've set the interface and set the alternative interface to the interface non-zero-bandwidth alternative interface.

Firstly I have to say I can't use anything like libusb. I ned to do this via Linux's USB device file system.

So as far as I can tell I'm ready to begin receiving isochronous data. However I can find very little information on how to do an isochronous transfer.

From what I can tell I need to populate a usbdevfs_urb structure but I'm completely unsure of how exactly to fill this structure.

Also, once I have filled this structure am I right in thinking I need to call the following:

int retSubmit   = ioctl( fd, USBDEVFS_SUBMITURB, &usbRequest );

and then once submitted I can wait for the request to complete using

USBDEVFS_REAPURBNDELAY

In the case of REAPURBNDELAY what exactly is the parameter I need to pass?

Am I even barking up the right tree?

Any information would be massively appreciated.

Thanks in advance!

Edit:

I attempt to do the isochronous transfer as follows:

usbdevfs_urb&   urbRequest      = *(usbdevfs_urb*)malloc( 384 );
urbRequest.type                 = USBDEVFS_URB_TYPE_ISO;
urbRequest.endpoint             = mpEndpoint->GetEndpointAddress();//mpEndpoint->GetEndpointIndex();
urbRequest.status               = 0;
urbRequest.flags                = USBDEVFS_URB_ISO_ASAP;
urbRequest.buffer               = pData;
urbRequest.buffer_length        = 0;
urbRequest.actual_length        = 0;
urbRequest.start_frame          = 0;
urbRequest.number_of_packets    = 1;
urbRequest.error_count          = 0;
urbRequest.signr                = 0;
urbRequest.usercontext          = pData;

usbdevfs_iso_packet_desc* pIsoPacketDesc    = &urbRequest.iso_frame_desc[0];
pIsoPacketDesc->length          = 384;
pIsoPacketDesc->actual_length   = 0;
pIsoPacketDesc->status          = 0;

Unfgortunately this gives me an error of -28 (ENOSPC).

<7>[ 3184.243163] usb 1-1: usbfs: usb_submit_urb returned -28

I can't understand why there wouldn't be enough usb bus bandwidth. There is only 1 usb port and my device is the only device plugged into it.

Any thoughts?

like image 876
Goz Avatar asked Nov 01 '11 09:11

Goz


1 Answers

Ok so it turns out that the problem is due to the fact that the android OS has placed an HID driver to handle the HID controls. This seems to block up the bandwidth. Detaching these drivers from the HID interfaces releases the bandwidth allowing the isochronous transfer to proceed.

You detach the kernel driver by doing the following:

usbdevfs_ioctl command;
command.ifno        = mpInterface->GetInterfaceNumber();
command.ioctl_code  = USBDEVFS_DISCONNECT;
command.data        = NULL;

int ret = ioctl( fd, USBDEVFS_IOCTL, &command );

Otherwise what I have done is correct.

like image 135
Goz Avatar answered Oct 01 '22 04:10

Goz