On 05/14/2012 03:12 PM, Pete Batard wrote:
I addressed this point already. It doesn't matter if you modify libusbx
or add an extra layer on top of it. The issue is you are replicating a
feature that libusbx is planning to provide, and that, as far as I could
see from my tests, unless somebody else provides the same feature as a
layer, in the same fashion as you do, they will not encounter the issue.
In essence what happens from the libusbx pov is:
1) libusbx gets initialized
2) libusb_get_device_list() gets called
3) a new USB device gets plugged in
4) that new device gets the winusb driver bound to it
5) libusb_get_device_list() gets called again
And after 5 we expect libusbx to both know about the device, and for the
app to be able to use the device through libusbx. This seems like a
reasonable thing to expect to me, even of a not hotplug aware libusbx.
Which it does.
As far as I know, I tested xusb in exactly the fashion highlighted
above, and found no issue. I produced the result from the test I ran as
well as the xusb patch I applied, and it matches your list. I was able
to use the device as expected after the second libusb_get_device_list()
was called. Are you sure you're issuing a libusb_free_device_list before
issuing the second libusb_get_device_list?
Right now, outside of not freeing the list (but in that case, expecting
an enum list to auto-update itself if after it has been generated IS
hotplug), the only way I see for your issue to manifest itself is if the
driver installation ends when we're in the middle of enumeration on
Windows, i.e. we ran an enum pass where the driver was seen as
unsupported (no driver) and later passes see the driver as supported
through WinUSB. But I can only see that happen if someone provides a
custom hotplug implementation.
Now, if you can modify xusb or produce a sample that demonstrates that
your issue occurs in a non custom hotplug scenario, that's a different
story.
Attached kindly find such a patch, together with output with/without the
patch.
(I also changed -k option's according to vid:pid of a usb disk I'm
testing with)
$ xusb -k -d -i
Thanks,
Uri.
diff --git a/examples/xusb.c b/examples/xusb.c
index 2c0409f..bdac37b 100644
--- a/examples/xusb.c
+++ b/examples/xusb.c
@@ -572,6 +572,80 @@ static void
read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin
}
}
+
+static void rescan_devices(void)
+{
+ libusb_device **devlist;
+
+ libusb_get_device_list(NULL, &devlist);
+ libusb_free_device_list(devlist, 1);
+}
+
+/* returns a libusb_device if found, NULL if not */
+static libusb_device* find_device_with_vid_pid(uint16_t vid, uint16_t pid)
+{
+ ssize_t nitems, i, r;
+ libusb_device **devlist, *dev = NULL;
+ struct libusb_device_descriptor desc;
+
+ nitems = libusb_get_device_list(NULL, &devlist);
+
+ printf("There are %ld devices plugged into the machine\n",
(long)nitems);
+
+ for (i=0; (i<nitems) && (devlist[i] != NULL); i++) {
+ r = libusb_get_device_descriptor(devlist[i], &desc);
+ if (r < 0) {
+ perr("failed to get device descriptor");
+ break;
+ }
+
+ if ((desc.idVendor == vid) && (desc.idProduct == pid)) {
+ printf("found the device\n");
+ dev = libusb_ref_device(devlist[i]);
+ break;
+ }
+ }
+ libusb_free_device_list(devlist, 1);
+ return dev;
+}
+
+static int test_driver_install(uint16_t vid, uint16_t pid)
+{
+ libusb_device *dev;
+ libusb_device_handle *handle = NULL;
+ int r;
+
+ dev = find_device_with_vid_pid(vid, pid);
+ if (!dev) {
+ perr("Failed to find device 0x%04x:0x%04x\n", vid, pid);
+ return -1;
+ }
+
+ printf("Opening device...\n");
+
+ r = libusb_open(dev, &handle);
+
+ if (r != 0) {
+ perr("Please install driver NOW!\n");
+ while(getchar() != 0x0A);
+ r = libusb_open(dev, &handle);
+ if (r != 0) {
+ perr("Going to rescan devices\n");
+ rescan_devices();
+ r = libusb_open(dev, &handle);
+ if (r != 0) {
+ perr(" Open Failed r=%d\n", r);
+ }
+ }
+ }
+
+ printf("Closing device...\n");
+ if (handle)
+ libusb_close(handle);
+ libusb_unref_device(dev);
+ return r;
+}
+
static int test_device(uint16_t vid, uint16_t pid)
{
libusb_device_handle *handle;
@@ -756,6 +837,7 @@ int main(int argc, char** argv)
size_t i, arglen;
unsigned tmp_vid, tmp_pid;
uint16_t endian_test = 0xBE00;
+ int is_test_driver_install = 0;
// Default to generic, expecting VID:PID
VID = 0;
@@ -793,11 +875,14 @@ int main(int argc, char** argv)
PID = 0x0004;
}
break;
+ case 'i':
+ // test libusb driver install
+ is_test_driver_install = 1;
case 'k':
// Generic 2 GB USB Key (SCSI
Transparent/Bulk Only) - 1 interface
if (!VID && !PID) {
VID = 0x0204;
PID = 0x6025;
}
break;
// The following tests will force VID:PID if
already provided
@@ -843,6 +928,7 @@ int main(int argc, char** argv)
printf(" -b: dump Mass Storage first block to binary file\n");
printf(" -g: short generic test (default)\n");
printf(" -k: test generic Mass Storage USB device (using
WinUSB)\n");
+ printf(" -i: test driver being installed dynamically\n");
printf(" -j: test FTDI based JTAG device (using WinUSB)\n");
printf(" -p: test Sony PS3 SixAxis controller (using
WinUSB)\n");
printf(" -x: test Microsoft XBox Controller Type S (using
WinUSB)\n");
@@ -858,7 +944,10 @@ int main(int argc, char** argv)
// Info = 3, Debug = 4
libusb_set_debug(NULL, debug_mode?4:3);
- test_device(VID, PID);
+ if (!is_test_driver_install)
+ test_device(VID, PID);
+ else
+ test_driver_install(VID, PID);
libusb_exit(NULL);
Using libusbx v1.0.11.10504
[timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
There are 2 devices plugged into the machine
found the device
Opening device...
[ 0.000000] [00000150] libusbx: warning [windows_get_device_list] could not
retrieve port number for device '\\.\ROOT#SYSTEM#0003', skipping: [13] The data
is invalid.
Please install driver NOW!
Going to rescan devices
[30.328125] [00000150] libusbx: warning [windows_get_device_list] could not
retrieve port number for device '\\.\ROOT#SYSTEM#0003', skipping: [13] The data
is invalid.
Open Failed r=-12
Closing device...
Using libusbx v1.0.11.10505
[timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
There are 2 devices plugged into the machine
found the device
Opening device...
[ 0.000000] [000003d4] libusbx: warning [windows_get_device_list] could not
retrieve port number for device '\\.\ROOT#SYSTEM#0003', skipping: [13] The data
is invalid.
Please install driver NOW!
Going to rescan devices
[24.140625] [000003d4] libusbx: warning [windows_get_device_list] could not
retrieve port number for device '\\.\ROOT#SYSTEM#0003', skipping: [13] The data
is invalid.
Closing device...
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusbx-devel mailing list
libusbx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusbx-devel