I'm trying to develop a (user space) Linux driver for one of my company's products, the bTop-2:
http://perfsci.com/hardware.htm
We currently have software to control the device in Mac OS X and in Windows. All of the software is open source and available from our website:
http://perfsci.com/btop_software.htm
Sorry for the long introduction. Now here's my problem:
I've been partially successful in porting the code in our Windows development kit to Linux. I can, from user space, discover the board when it's plugged in, set a configuration, claim an interface, and set an alternative setting. I can even write to the bulk out endpoints using:
Code:
struct usb_bulktransfer bulk;
int ret, sent = 0;
do{
bulk.ep = EP & BTOP_EP_MASK;
bulk.len = *bufferSize - sent;
bulk.timeout = 5000;
bulk.data = (unsigned char*)buffer + sent;
ret = ioctl(m_handle, IOCTL_USB_BULK, &bulk);
if(ret < 0){
printf("error (%d) (transferData): %s\n", ret, strerror(errno));
return ret;
}
sent += ret;
}while(ret > 0 && sent < *bufferSize);
But if I try to use this same function to read from a bulk in endpoint I get an "Operation timed out" error every single time. (I've tried extending the timeout to a full minute, and it really shouldn't take more than a fraction of a second anyway). I'm pretty sure the endpoints are right since I get a different error (no such file) if I use a nonsense endpoint. My one other endpoint related clue comes from libusb. I tried using a function from that library:
Code:
ret = usb_bulk_read(dev_handle, EP & BTOP_EP_MASK,
(char*)buffer, *bufferSize, 1000);
where dev_handle was set up according to the usual libusb method.
Code:
ret = usb_bulk_write(dev_handle, EP & BTOP_EP_MASK,
(char*)buffer, *bufferSize, 1000);
does work with the appropriate out endpoints, but when I try to use a bulk in endpoint with the usb_bulk_read command, I get a "No such file" error. It turns out that in the usb_bulk_read function, the input endpoint number is OR'd with USB_ENDPOINT_IN (0x80), so
(EP & BTOP_EP_MASK) becomes ((EP & BTOP_EP_MASK) | USB_ENDPOINT_IN), which is not a valid endpoint number for our device. So does this mean that the endpoint numbers from the device are somehow fundamentally incompatible with Linux? That seems very unlikely to me, but I don't have much experience with the Linux USB system.
I'm opening the device with:
m_handle = open(path_to_device, O_RDWR | O_APPEND)
and I'm running the test code as root so I know it's not a permissions issue. Any ideas?
If anyone else would like to take a crack at this port let me know and I'll send you all my test code. (I might even be able to get you a free bTop). As I mentioned above, all of our bTop related code for Windows and Mac OS X is already open source. I've looked at a bunch of example code for controlling USB devices from user space either with ioctl calls or with libusb, but those examples were all mysteriously lacking bulk reads.