linux: Fix host_endian handling

-in 2 cases the passed in host_endian was not being set
-get_config_descriptor was wrongly calling seek_to_next_config with
 host_endian set to 1, but the only case where host_endian is 1 is when
 reading the device-desc from usbfs, even in usbfs the config descriptors
 are in raw format

Note that the 2nd change partly reverts commit
7f2e9f0776386997d2b4c4c47598ab88e3caeb7a
"Linux: Fix usbfs/sysfs config descriptor handling on big-endian"
Which commit msg says: "checked against Documentation/usb/proc_usb_info.txt"

Well guess what, I checked the actual drivers/usb/core/devio.c code
and Documentation/usb/proc_usb_info.txt is *wrong*. I'll send a patch to
update it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
usbi_alloc_device: Drop unnecessary memset 0

The memory gets calloc-ed, so there no need to clear it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
linux: Add a _get_usbfs_fd helper function

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
linux: Cache the entire descriptors at device-init

Now that the core caches device-descriptors, we end up opening each
usbfs-node or sysfs-descriptors file once on libusb_init anyways.

So we might as well do this on device-init, rather then waiting for the
core to call op_get_device_descriptor. This allows us to simplify the
code in various places.

While we've it open, read the entire file rather then only reading the
device-descriptor. This is practically free, since most of the cost is in
the opening of the file, not in reading it.

Running the stress test, which does 10000 libusb_init calls, takes 21.8 seconds
on avarage on my idle system with 17 usb devices both before and after this
patch, showing that the cost of also reading the config descriptors while
we've the file open is truely neglible.

Note that this patch does not yet use the cached config descriptors, this is
done by a later patch in this series.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
linux: Clear descriptor buffer before read when using usbfs

In usbfs the config descriptors are config.wTotalLength bytes apart, but the
device may actually return a shorter descriptor then advertised, in this
case the kernel will simply skip over any bytes read which the device did
not actually return. Note the kernel will *not* return 0 data, it will simply
leave the memory passed in to the read call as is.

Therefor this patch clears the buffer before calling read, to ensure that
the non existing parts of the descriptors are always properly zero-ed.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
linux: Switch to kernel version check to determine if sysfs has descriptors

With the refactoring of the Linux descriptors handling, we only want to use
sysfs descriptors if they have the complete config descriptors (versus just
the active config descriptor), which is the case since Linux 2.6.26.

This means that we will fallback to using the usbfs descriptors for the device
descriptor on Linux 2.6.23 - 2.6.25, which only have the active config
descriptor. This will cause a tiny performance penalty, but only on these
3 kernel versions (which are not used in any still supported Linux distros),
and then only on library init since we now cache everything.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
linux: Switch to kernel version check to determine if sysfs can relate devs

We rely on the kernel version for determining capabilities, except for
sysfs_can_relate_devices. This changes sysfs_can_relate_devices over to
a kernel version check to.

This makes things more consistent, removes a whole bunch of code, and since
it stops us from needlessly banging sysfs, it reduces the avarage run time for
the stress test on my system from 21.8 to 16.7 seconds.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
linux: init: Only stop the event monitor if we also started it

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
linux: Use cached config descriptors

Use cached config descriptors instead of doing tons file io, because:
- Less fileio is more
- Less code is more, diffstat for this patch:
 1 file changed, 128 insertions(+), 307 deletions(-)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
linux: get_configuration don't return LIBUSB_ERROR_NOT_SUPPORTED with usbfs

We have an implementation of get_configuration with usbfs, so lets use it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
linux: Properly deal with invalid config.wTotalLength in sysfs

In usbfs wTotalLength can be trusted, in the sense that the kernel simple
has holes in the descriptors file when a device returns a smaller config
descriptor then advertised.

In sysfs this is not the case, sysfs descriptors only contain descriptors
actually returned by the device, with no holes. The kernel does validate
the bLength field of all the descriptors and removes any invalid ones.

So with sysfs we cannot rely on wTotalLength, since we can trust bLength,
this patch searches forward for a descriptor with type of LIBUSB_DT_CONFIG
to find the next config on sysfs.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
all: Make usbi_os_backend.get_[active_]config_descriptor return len

Since commit 5e479f1821d3294fb1cc70c5867c69eca2551de7:
"Core: Avoid short read failures on broken descriptors"

usbi_os_backend.get_[active_]config_descriptor no longer return on error
(under Linux) when returning less bytes then requested. But
libusb_get_[active_]config_descriptor still not only requests wTotalLength
bytes, but also blindly assumes that on success it has gotten wTotalLength
bytes.

This patch fixes this, it changes all usbi_os_backend.get_*config_descriptor
implementations to return the actual length on success and uses this value as
the descriptor size in parse_configuration().

Note that the linux and wince backends were already returning the actual
length and thus are not touched.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
descriptor.c: Read a full config-desc-header on first config-desc read

For some reason the first get config call to determine the total-length
was only reading 8 of the 9 bytes of a full config-desc-header, which
is weird. The Linux kernel reads the full 9 on the first call, so lets
do that in libusb too. Note that for backends which cache the config this
does not matter.

Also check that we've actually gotten back a full header, before parsing it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
descriptor.c: Consequently check bDescriptorType and bLength everywhere

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
descriptor.c: Add a raw_desc_to_config helper function

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
all: Allow backend to provide a better get_config_descriptor_by_value

Our core get_config_descriptor_by_value is not exactly pretty nor efficient,
allow the backends to provide something better.

Note that the callback signature differs from get_config_descriptor in that
backend owned memory gets returned. This saves a needless malloc + memcpy +
free. If this turns out to be a problem for some backends we can always
change things to work like get_config_descriptor.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
all: ensure host_endian is always initialized

The get_device_descriptor backend call done from descriptor.c was passing
in an uninitialized host_endian value. Likewise for the windows backend,
host_endian was not being set from get_[active_]config_descriptor.

Since the 2 problem cases are for different backend calls, we were never using
an uninitialized host_endian, still lets set it everywhere for safety,

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
wince_get_active_config_descriptor() sets host_endian incorrectly

wince_get_active_config_descriptor() retrieves configuration descriptors
as raw bytes, in bus-endian order. Therefore, host_endian should be set
to 0 (as in wince_get_config_descriptor()).

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
POSIX: Move setting of pipes to non-blocking into usbi_pipe

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Hotplug: Make use of HAVE_SYS_TYPES_H define

Signed-off-by: Hans de Goede <hdegoede@redhat.com>