summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
...
* hotplug: Add a hotplug_poll backend functionHans de Goede2013-05-3010-15/+70
| | | | | | | | | | | | | | | | | | | | Apps which were written before hotplug support, may listen for hotplug events on their own and call libusb_get_device_list on device addition. In this case libusb_get_device_list will likely return a list without the new device in there, as the hotplug event thread will still be busy enumerating the device, which may take a while, or may not even have seen the event yet. To avoid this add a new hotplug_poll backend function and make libusb_get_device_list call a this before copying ctx->usb_devs to the user. In this function the backend should ensure any pending hotplug events are fully processed before returning. This patch implements hotplug_poll for linux, it should probably be also implemented for darwin. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: rework hotplug lock handlingHans de Goede2013-05-305-11/+13
| | | | | | | | I could not find if libudev is completely threadsafe anywhere, so rework the lock handling to serialize all libudev accesses. This is a preparation patch for adding hotplug_poll support, see the next patch in this series. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Add a linux_netlink_read_message helper functionHans de Goede2013-05-302-30/+40
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* descriptor.c: AlternateSettings are related by InterfaceNumberHans de Goede2013-05-302-2/+6
| | | | | | | | A block of AlternateSettings for a certain InterfaceNumber does not necessarily start with AlternateSetting 0, so check Interface Descriptors belong to each other by using InterfaceNumber, as specified in the spec. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* WinCE: Add hotplug.c to projectsToby Gray2013-05-283-1/+9
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* Windows: Add new symbol for libusb_get_port_numbers to def fileToby Gray2013-05-282-1/+3
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* Hotplug: Make use of HAVE_SYS_TYPES_H defineToby Gray2013-05-282-1/+3
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* POSIX: Move setting of pipes to non-blocking into usbi_pipeToby Gray2013-05-285-12/+52
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* wince_get_active_config_descriptor() sets host_endian incorrectlySimon Haggett2013-05-242-2/+2
| | | | | | | | 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>
* all: ensure host_endian is always initializedHans de Goede2013-05-243-2/+3
| | | | | | | | | | | 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>
* all: Allow backend to provide a better get_config_descriptor_by_valueHans de Goede2013-05-247-9/+39
| | | | | | | | | | | | 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>
* descriptor.c: Add a raw_desc_to_config helper functionHans de Goede2013-05-242-68/+44
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* descriptor.c: Consequently check bDescriptorType and bLength everywhereHans de Goede2013-05-242-58/+86
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* descriptor.c: Read a full config-desc-header on first config-desc readHans de Goede2013-05-242-6/+24
| | | | | | | | | | | | 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>
* all: Make usbi_os_backend.get_[active_]config_descriptor return lenHans de Goede2013-05-245-10/+13
| | | | | | | | | | | | | | | | | | | | 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>
* linux: Properly deal with invalid config.wTotalLength in sysfsHans de Goede2013-05-242-10/+62
| | | | | | | | | | | | | | | | 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>
* linux: get_configuration don't return LIBUSB_ERROR_NOT_SUPPORTED with usbfsHans de Goede2013-05-242-4/+7
| | | | | | We have an implementation of get_configuration with usbfs, so lets use it. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Use cached config descriptorsHans de Goede2013-05-242-310/+133
| | | | | | | | | 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: init: Only stop the event monitor if we also started itHans de Goede2013-05-242-2/+2
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Switch to kernel version check to determine if sysfs can relate devsHans de Goede2013-05-242-67/+25
| | | | | | | | | | | | 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: Switch to kernel version check to determine if sysfs has descriptorsHans de Goede2013-05-232-23/+25
| | | | | | | | | | | | | | 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: Clear descriptor buffer before read when using usbfsHans de Goede2013-05-232-1/+6
| | | | | | | | | | | | | 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: Cache the entire descriptors at device-initHans de Goede2013-05-232-78/+50
| | | | | | | | | | | | | | | | | | | | | | | 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: Add a _get_usbfs_fd helper functionHans de Goede2013-05-222-39/+35
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* usbi_alloc_device: Drop unnecessary memset 0Hans de Goede2013-05-222-2/+1
| | | | | | The memory gets calloc-ed, so there no need to clear it. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Fix host_endian handlingHans de Goede2013-05-182-7/+11
| | | | | | | | | | | | | | | | | | | -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>
* Examples: Fix use of deprecated libusb_get_port_pathHans de Goede2013-05-173-11/+7
| | | | | | While at it also simplify the path printing in listdevs Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* core: Add a new public libusb_get_port_numbers functionHans de Goede2013-05-173-10/+34
| | | | | | | | | | | | This new function replaces the now deprecated libusb_get_port_path function, as that is the only function operating on a libusb_device which also takes a libusb_context, which is rather inconsistent. Note we will keep libusb_get_port_path around in the 1.0.x for the forseeable future for ABI compatibility reasons, but it should not be used in any new code. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* core: Fix handle_events return code on hotplug pipe read errorHans de Goede2013-05-172-2/+2
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* usbi_handle_disconnect: Fix race condition leading to double completionHans de Goede2013-05-163-16/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It took me quite a while to debug this, here is a step by step for the race which I believe is happening in some cases: 1) app calls libusb_submit_transfer 2) libusb_submit_transfer locks itransfer->lock 3) libusb_submit_transfer adds the transfer to the flying list 4) *thread switch* 5) other thread notices POLL_ERR on device fd, calls usbi_handle_disconnect 6) usbi_handle_disconnect find the transfer which is in progress of being submitted in the flying list 7) usbi_handle_disconnect calls usbi_backend->clear_transfer_priv on the transfer, this blocks waiting on itransfer->lock 8) *thread switch* 9) libusb_submit_transfer actually tries to submit the transfer now, calls usbi_backend->submit_transfer, which fails with -ENODEV 10) libusb_submit_transfer *removes* the transfer from the flying list, unlocks itransfer->lock and returns an error to its caller 11) the caller frees the transfer, meaning the to_cancel pointer in usbi_handle_disconnect now points to free-ed memory, for extra mayhem 12) *thread switch* 13) usbi_handle_disconnect calls usbi_handle_transfer_completion 14) usbi_handle_transfer_completion tries to remove the transfer from the flying list *for the 2nd time* But the first call done from libusb_submit_transfer has already done this. libusb's list_del looks like this: static inline void list_del(struct list_head *entry) { entry->next->prev = entry->prev; entry->prev->next = entry->next; entry->next = entry->prev = NULL; } So the first call sets it next and prev to NULL, and then the 2nd call tries to deref next -> BOOM For an example backtrace caused by this, see: https://bugs.freedesktop.org/show_bug.cgi?id=55619#c7 This patch fixes this by letting libusb_submit keep the flying transfers list locked during submission, so the submission flow changes from: 1) lock flying transfers add to flying transfers unlock 2) submit 3) on submission error: lock flying transfers remove from flying transfers unlock to: 1) lock flying transfers 2) add to flying transfers 3) submit 4) on submission error: remove from flying transfers 5) unlock This means that the os backends submit handler now gets called with the flying transfers lock held! I've looked at all the backends and this should not be a problem. Only the windows and win-ce backends care about the flying transfers list at all, and then only in their handle_events handler. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* usbi_handle_disconnect: Add some debugging wrt cancelled transfersHans de Goede2013-05-162-1/+4
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: linux_get_parent_info: properly propagate malloc errorsHans de Goede2013-05-162-6/+10
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* listdevs: Also print portpath for non root hubsHans de Goede2013-05-162-3/+16
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* All: ref dev->parent_devHans de Goede2013-05-165-13/+6
| | | | | | | | | | | | | | An app can hold a reference to just a leave device, if then an entire hub goes away, all removed devices will get there final unref, except for the one ref-ed by the app. If the app then tries to use parent_dev in anyway after this, we've a use-after-free bug. This fixes this. Also remove the lets re-enumerate fix for this from libusb_get_port_path, I'm not sure what the exact idea behind this fix was, but after this patch it is no longer needed, and this patch also fixes usage of for example libusb_get_parent(). Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* core: Improve error / debug messages for hotplug pipe handlingHans de Goede2013-05-162-1/+5
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Fixup init_count tracking on hotplug init errorHans de Goede2013-05-162-6/+9
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux_udev: linux_start_event_monitor: Properly cleanup on errorHans de Goede2013-05-162-5/+18
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Replace should-not-happen checks with assertsHans de Goede2013-05-163-23/+17
| | | | | | | These all really should never happen, so rather then to do error handling when they do, simple assert them. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Not finding a device on hotplug_disconnect is not an errorHans de Goede2013-05-162-3/+4
| | | | | | | | This can happen if the device gets removed between registering the hot-plug event handler and initial device enumeration running. So lets turn this into a debug message to avoid spurious bug-reports. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Improve topology related debug messagesHans de Goede2013-05-162-4/+6
| | | | | | And use usbi_dbg, rather then fprintf(stderr, ... Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Set device->port_numberHans de Goede2013-05-162-12/+13
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Deal with devices being enumerated before their parents areHans de Goede2013-05-162-2/+14
| | | | | | | | | | | | | | | | | | | | | | The linux netlink enumeration code processes devices in readdir order, which means devices may get enumerated before their parent is, IE on my system readdir order is (ls -U) 1-1 usb4 2-1.8 6-0:1.0 1-1.4.3 1-1.4.4.1:1.0 2-1 usb5 6-1.4 6-1:1.0 1-1.4.4 1-1.4.4.1:1.1 6-1 usb6 3-0:1.0 2-1.8:1.0 1-0:1.0 1-1.4.4.1:1.2 7-1 usb7 1-1.4.3:1.0 2-1.8:1.1 1-1:1.0 usb1 1-1.4.4.1 1-1.4.4:1.0 2-1.8:1.2 6-1.4:1.0 usb2 1-1.4:1.0 4-0:1.0 7-0:1.0 2-0:1.0 usb3 1-1.4 5-0:1.0 7-1:1.0 2-1:1.0 So 1.4.4.1 will get added (way) before 1.4.4 and indeed: [ 0.002243] [00004055] libusbx: debug [linux_get_device_address] scan 1-1.4.4.1 Dev 0x1973bc0 (1-1.4.4.1) has parent (nil) This patch fixes this by forcing enumeration of the parent from linux_parent_dev. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Move check for a device being added twice to linux_enumerate_deviceHans de Goede2013-05-162-7/+7
| | | | | | | | | | | | It is possible for a device to show up between the hotplug code starting to listen for new devices, and the enumeration of existing devices. This will cause a device to get enumerated twice. The next patch in this series adds a different code path which can cause a device to be enumerated twice, this patch therefor moves the check for this to linux_enumerate_device, so that this will get caught in all cases. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: hotplug_enumerate and _disconnect take active_contexts_lockHans de Goede2013-05-162-1/+5
| | | | | | | | | Take the active_contexts_lock when enumerating over active_contexts. Note that the active_contexts_lock is taken *before* the hotplug lock, as they are taken in the same order in the libusb_init path. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Replace pthread_mutex with usbi_mutex_staticHans de Goede2013-05-162-11/+11
| | | | | | | Boils down to the same thing, but mixing and matching lock types in one file looks ugly. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* core: Fixup default_context handlingHans de Goede2013-05-162-10/+9
| | | | | | | | | | Now that we set the default context earlier in libusb_init: -There is no need to do it a second time at the end of libusb_init -We need to set it to NULL if libusb_init fails later on -Since it now can be set then reset by libusb_init, libusb_exit needs to take the lock while testing if the passed in ctx == default_context Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* core: Fixup cleanup on init errorHans de Goede2013-05-162-8/+11
| | | | | | | -mutexes were not being destroyed on backend init failure -hotplug_cbs_lock mutex was never being destroyed Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* core: Add ctx to the active context list before backend->initHans de Goede2013-05-162-10/+12
| | | | | | | | As soon as backend->init has completed hotplug events may fire, and they will not get processed on the created context until it has been added to the active_context list. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: Take hotplug_lock for scan_devices, hotplug_enumerate and _disconnectHans de Goede2013-05-162-4/+8
| | | | | | | | | | | | As soon as we've started listening for hp events, hotplug_enumerate and _disconnect can run, they do test then add / remove operations on the device list. This can race with scan_devices adding devices, so take the lock around all 3 to avoid the race. Also fix the lock not being released in case of linux_start_event_monitor failure. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* linux: linux_parent_dev search for . from the rightHans de Goede2013-05-162-3/+3
| | | | | | | If hubs are chained to other hubs there will be multiple '.' characters, and want the last one. Signed-off-by: Hans de Goede <hdegoede@redhat.com>