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