tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Potential problem with reading data from usb devices with ugen(4)
hello folks. Perhaps someone on this list can enlighten me as to
where I'm going wrong, but I think there may be an issue with ugen(4) when
using the bulk read ahead and write behind code in conjunction with file
descriptors which are in O_NONBLOCK mode. This is with NetBSD/i386 5.2
with the UGEN_BULK_RA_WB code ifdef'd into the ugen(4) code. I've looked
at -current and it looks like the problem is still there. Let me explain:
I'm trying to get the usbmuxd and libimobiledevice code working under
NetBSD using the libusb1-1.0.19 package. The usbmuxd code scans the
available ugen devices, identifies which ones are Apple devices, and then
rescans the devices it identified as being of interest. With the default
libusb1 code, this functionality doesn't work because the usbmuxd code
expects to be able to do this over and over again but the ugen(4) driver
locks the process in "ugenrb" when it checks to see if a given device has
the proper bulk endpoints. I modified the libusb1 NetBSD backend module to
enable the read ahead code and write behind code, as well as to put the
file descriptor associated with each of the endpoints into non-blocking
mode with fcntl(2). Now, the first pass usbmuxd makes works, but it doesn't
generate any requests of the Apple devices which cause them to respond with
data on the bulk endpoints. That's fine, but when usbmuxd comes around to
begin conversing with the "interesting" devices again, it's told there's
nothing to read because the ugen(4) driver, which has read ahead enabled
already, doesn't check for new input from the USB device when read requests
are made and there's no data available. Specifically, when this code is
enabled, I think data is read from the bulk end points of a device using
the function ugen_bulkra_intr(). In theory it's supposed to be a self
perpetuating function that keeps checking for input, but it seems to only
get called from itself or when the read ahead code is enabled via the
ioctl(2) call. The scenario looks like this to me:
1. Enable the read ahead code with the ioctl(2) on a device bulk endpoint
and also set the file descriptor into non-blocking mode. The function
ugen_bulkra_intr() gets called once, but there's nothing to read so
the function doesn't set things up to call itself again.
2. The next call to read(2) by the user process doesn't rigger a call to
ugen_bulkra_intr() because the file descriptor is in non-blocking mode and
there's no data to pass to the process so the driver just returnes and
EWOULDBLOCK.
3. This repeats over and over again without ever actually querying the
device to see if it has anything to say.
I don't see it, but perhaps I'm missing something in terms of either
an interrupt that the physical device can generate that will cause the
ugen_bulkra_intr() function to get called in interrupt context or a callout
thread that does this on a timed basis? (Interestingly enough, I don't see
a call to the ugen_bulkra_intr() function from the ugenintr() function,
which is what I expected to find when I began looking at this issue.)
So, my question is, am I missing something obvious or should
ugen_bulkra_intr() get called periodically even if there's no data when the
file descriptor is in non-blocking mode? If so, would having it get called
when the general interrupt fires be sufficient or should a callout thread
be set up to do this?
Thoughts?
-thanks
-Brian
Home |
Main Index |
Thread Index |
Old Index