diff options
Diffstat (limited to 'libusb/os/linux_usbfs.c')
-rw-r--r-- | libusb/os/linux_usbfs.c | 269 |
1 files changed, 145 insertions, 124 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index fb2ed53..285d9ca 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -95,13 +95,9 @@ static int sysfs_available = -1; /* how many times have we initted (and not exited) ? */ static int init_count = 0; -#ifdef __ANDROID__ /* have no authority to operate usb device directly */ -static int weak_authority = 0; -#endif +static int no_enumeration = 0; -/* Serialize hotplug start/stop */ -static usbi_mutex_static_t linux_hotplug_startstop_lock = USBI_MUTEX_INITIALIZER; /* Serialize scan-devices, event-thread, and poll */ usbi_mutex_static_t linux_hotplug_lock = USBI_MUTEX_INITIALIZER; @@ -128,7 +124,7 @@ struct linux_device_priv { void *descriptors; size_t descriptors_len; struct config_descriptor *config_descriptors; - uint8_t active_config; /* cache val for !sysfs_available */ + int active_config; /* cache val for !sysfs_available */ }; struct linux_device_handle_priv { @@ -169,6 +165,21 @@ struct linux_transfer_priv { int iso_packet_offset; }; +static int dev_has_config0(struct libusb_device *dev) +{ + struct linux_device_priv *priv = usbi_get_device_priv(dev); + struct config_descriptor *config; + uint8_t idx; + + for (idx = 0; idx < dev->device_descriptor.bNumConfigurations; idx++) { + config = &priv->config_descriptors[idx]; + if (config->desc->bConfigurationValue == 0) + return 1; + } + + return 0; +} + static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent) { struct libusb_context *ctx = DEVICE_CTX(dev); @@ -223,11 +234,11 @@ static int is_usbdev_entry(const char *name, uint8_t *bus_p, uint8_t *dev_p) if (sscanf(name, "usbdev%d.%d", &busnum, &devnum) != 2) return 0; if (busnum < 0 || busnum > UINT8_MAX || devnum < 0 || devnum > UINT8_MAX) { - usbi_dbg("invalid usbdev format '%s'", name); + usbi_dbg(NULL, "invalid usbdev format '%s'", name); return 0; } - usbi_dbg("found: %s", name); + usbi_dbg(NULL, "found: %s", name); if (bus_p) *bus_p = (uint8_t)busnum; if (dev_p) @@ -312,7 +323,7 @@ static int get_kernel_version(struct libusb_context *ctx, if (atoms < 3) ver->sublevel = -1; - usbi_dbg("reported kernel version is %s", uts.release); + usbi_dbg(ctx, "reported kernel version is %s", uts.release); return 0; } @@ -360,7 +371,7 @@ static int op_init(struct libusb_context *ctx) return LIBUSB_ERROR_OTHER; } - usbi_dbg("found usbfs at %s", usbfs_path); + usbi_dbg(ctx, "found usbfs at %s", usbfs_path); if (!max_iso_packet_len) { if (kernel_version_ge(&kversion, 5, 2, 0)) @@ -371,14 +382,14 @@ static int op_init(struct libusb_context *ctx) max_iso_packet_len = 8192; } - usbi_dbg("max iso packet length is (likely) %u bytes", max_iso_packet_len); + usbi_dbg(ctx, "max iso packet length is (likely) %u bytes", max_iso_packet_len); if (sysfs_available == -1) { struct statfs statfsbuf; r = statfs(SYSFS_MOUNT_PATH, &statfsbuf); if (r == 0 && statfsbuf.f_type == SYSFS_MAGIC) { - usbi_dbg("sysfs is available"); + usbi_dbg(ctx, "sysfs is available"); sysfs_available = 1; } else { usbi_warn(ctx, "sysfs not mounted"); @@ -386,13 +397,10 @@ static int op_init(struct libusb_context *ctx) } } -#ifdef __ANDROID__ - if (weak_authority) { + if (no_enumeration) { return LIBUSB_SUCCESS; } -#endif - usbi_mutex_static_lock(&linux_hotplug_startstop_lock); r = LIBUSB_SUCCESS; if (init_count == 0) { /* start up hotplug event handler */ @@ -407,7 +415,6 @@ static int op_init(struct libusb_context *ctx) } else { usbi_err(ctx, "error starting hotplug event monitor"); } - usbi_mutex_static_unlock(&linux_hotplug_startstop_lock); return r; } @@ -415,13 +422,16 @@ static int op_init(struct libusb_context *ctx) static void op_exit(struct libusb_context *ctx) { UNUSED(ctx); - usbi_mutex_static_lock(&linux_hotplug_startstop_lock); + + if (no_enumeration) { + return; + } + assert(init_count != 0); if (!--init_count) { /* tear down event handler */ linux_stop_event_monitor(); } - usbi_mutex_static_unlock(&linux_hotplug_startstop_lock); } static int op_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap) @@ -429,15 +439,11 @@ static int op_set_option(struct libusb_context *ctx, enum libusb_option option, UNUSED(ctx); UNUSED(ap); -#ifdef __ANDROID__ - if (option == LIBUSB_OPTION_WEAK_AUTHORITY) { - usbi_dbg("set libusb has weak authority"); - weak_authority = 1; + if (option == LIBUSB_OPTION_NO_DEVICE_DISCOVERY) { + usbi_dbg(ctx, "no enumeration will be performed"); + no_enumeration = 1; return LIBUSB_SUCCESS; } -#else - UNUSED(option); -#endif return LIBUSB_ERROR_NOT_SUPPORTED; } @@ -498,7 +504,7 @@ static int read_sysfs_attr(struct libusb_context *ctx, if (fd < 0) return fd; - r = read(fd, buf, sizeof(buf)); + r = read(fd, buf, sizeof(buf) - 1); if (r < 0) { r = errno; close(fd); @@ -516,16 +522,18 @@ static int read_sysfs_attr(struct libusb_context *ctx, return 0; } - /* The kernel does *not* NULL-terminate the string, but every attribute + /* The kernel does *not* NUL-terminate the string, but every attribute * should be terminated with a newline character. */ if (!isdigit(buf[0])) { usbi_err(ctx, "attribute %s doesn't have numeric value?", attr); return LIBUSB_ERROR_IO; } else if (buf[r - 1] != '\n') { - usbi_err(ctx, "attribute %s doesn't end with newline?", attr); - return LIBUSB_ERROR_IO; + usbi_warn(ctx, "attribute %s doesn't end with newline?", attr); + } else { + /* Remove the terminating newline character */ + r--; } - buf[r - 1] = '\0'; + buf[r] = '\0'; errno = 0; value = strtol(buf, &endptr, 10); @@ -565,22 +573,12 @@ static int sysfs_scan_device(struct libusb_context *ctx, const char *devname) } /* read the bConfigurationValue for a device */ -static int sysfs_get_active_config(struct libusb_device *dev, uint8_t *config) +static int sysfs_get_active_config(struct libusb_device *dev, int *config) { struct linux_device_priv *priv = usbi_get_device_priv(dev); - int ret, tmp; - - ret = read_sysfs_attr(DEVICE_CTX(dev), priv->sysfs_dir, "bConfigurationValue", - UINT8_MAX, &tmp); - if (ret < 0) - return ret; - - if (tmp == -1) - tmp = 0; /* unconfigured */ - *config = (uint8_t)tmp; - - return 0; + return read_sysfs_attr(DEVICE_CTX(dev), priv->sysfs_dir, "bConfigurationValue", + UINT8_MAX, config); } int linux_get_device_address(struct libusb_context *ctx, int detached, @@ -590,7 +588,7 @@ int linux_get_device_address(struct libusb_context *ctx, int detached, int sysfs_val; int r; - usbi_dbg("getting address for device: %s detached: %d", sys_name, detached); + usbi_dbg(ctx, "getting address for device: %s detached: %d", sys_name, detached); /* can't use sysfs to read the bus and device number if the * device has been detached */ if (!sysfs_available || detached || !sys_name) { @@ -619,7 +617,7 @@ int linux_get_device_address(struct libusb_context *ctx, int detached, return LIBUSB_SUCCESS; } - usbi_dbg("scan %s", sys_name); + usbi_dbg(ctx, "scan %s", sys_name); r = read_sysfs_attr(ctx, sys_name, "busnum", UINT8_MAX, &sysfs_val); if (r < 0) @@ -631,7 +629,7 @@ int linux_get_device_address(struct libusb_context *ctx, int detached, return r; *devaddr = (uint8_t)sysfs_val; - usbi_dbg("bus=%u dev=%u", *busnum, *devaddr); + usbi_dbg(ctx, "bus=%u dev=%u", *busnum, *devaddr); return LIBUSB_SUCCESS; } @@ -641,7 +639,12 @@ static int seek_to_next_config(struct libusb_context *ctx, uint8_t *buffer, size_t len) { struct usbi_descriptor_header *header; - int offset = 0; + int offset; + + /* Start seeking past the config descriptor */ + offset = LIBUSB_DT_CONFIG_SIZE; + buffer += LIBUSB_DT_CONFIG_SIZE; + len -= LIBUSB_DT_CONFIG_SIZE; while (len > 0) { if (len < 2) { @@ -718,7 +721,7 @@ static int parse_config_descriptors(struct libusb_device *dev) } if (priv->sysfs_dir) { - /* + /* * In sysfs wTotalLength is ignored, instead the kernel returns a * config descriptor with verified bLength fields, with descriptors * with an invalid bLength removed. @@ -727,8 +730,7 @@ static int parse_config_descriptors(struct libusb_device *dev) int offset; if (num_configs > 1 && idx < num_configs - 1) { - offset = seek_to_next_config(ctx, buffer + LIBUSB_DT_CONFIG_SIZE, - remaining - LIBUSB_DT_CONFIG_SIZE); + offset = seek_to_next_config(ctx, buffer, remaining); if (offset < 0) return offset; sysfs_config_len = (uint16_t)offset; @@ -752,6 +754,9 @@ static int parse_config_descriptors(struct libusb_device *dev) } } + if (config_desc->bConfigurationValue == 0) + usbi_warn(ctx, "device has configuration 0"); + priv->config_descriptors[idx].desc = config_desc; priv->config_descriptors[idx].actual_len = config_len; @@ -785,7 +790,7 @@ static int op_get_active_config_descriptor(struct libusb_device *dev, { struct linux_device_priv *priv = usbi_get_device_priv(dev); void *config_desc; - uint8_t active_config; + int active_config; int r; if (priv->sysfs_dir) { @@ -797,12 +802,12 @@ static int op_get_active_config_descriptor(struct libusb_device *dev, active_config = priv->active_config; } - if (active_config == 0) { + if (active_config == -1) { usbi_err(DEVICE_CTX(dev), "device unconfigured"); return LIBUSB_ERROR_NOT_FOUND; } - r = op_get_config_descriptor_by_value(dev, active_config, &config_desc); + r = op_get_config_descriptor_by_value(dev, (uint8_t)active_config, &config_desc); if (r < 0) return r; @@ -850,17 +855,26 @@ static int usbfs_get_active_config(struct libusb_device *dev, int fd) /* we hit this error path frequently with buggy devices :( */ usbi_warn(DEVICE_CTX(dev), "get configuration failed, errno=%d", errno); + + /* assume the current configuration is the first one if we have + * the configuration descriptors, otherwise treat the device + * as unconfigured. */ + if (priv->config_descriptors) + priv->active_config = (int)priv->config_descriptors[0].desc->bConfigurationValue; + else + priv->active_config = -1; } else if (active_config == 0) { - /* some buggy devices have a configuration 0, but we're - * reaching into the corner of a corner case here, so let's - * not support buggy devices in these circumstances. - * stick to the specs: a configuration value of 0 means - * unconfigured. */ - usbi_warn(DEVICE_CTX(dev), "active cfg 0? assuming unconfigured device"); + if (dev_has_config0(dev)) { + /* some buggy devices have a configuration 0, but we're + * reaching into the corner of a corner case here. */ + priv->active_config = 0; + } else { + priv->active_config = -1; + } + } else { + priv->active_config = (int)active_config; } - priv->active_config = active_config; - return LIBUSB_SUCCESS; } @@ -991,9 +1005,9 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum, usbi_warn(ctx, "Missing rw usbfs access; cannot determine " "active configuration descriptor"); if (priv->config_descriptors) - priv->active_config = priv->config_descriptors[0].desc->bConfigurationValue; + priv->active_config = (int)priv->config_descriptors[0].desc->bConfigurationValue; else - priv->active_config = 0; /* No config dt */ + priv->active_config = -1; /* No config dt */ return LIBUSB_SUCCESS; } @@ -1058,14 +1072,14 @@ retry: usbi_mutex_unlock(&ctx->usb_devs_lock); if (!dev->parent_dev && add_parent) { - usbi_dbg("parent_dev %s not enumerated yet, enumerating now", + usbi_dbg(ctx, "parent_dev %s not enumerated yet, enumerating now", parent_sysfs_dir); sysfs_scan_device(ctx, parent_sysfs_dir); add_parent = 0; goto retry; } - usbi_dbg("dev %p (%s) has parent %p (%s) port %u", dev, sysfs_dir, + usbi_dbg(ctx, "dev %p (%s) has parent %p (%s) port %u", dev, sysfs_dir, dev->parent_dev, parent_sysfs_dir, dev->port_number); free(parent_sysfs_dir); @@ -1084,17 +1098,17 @@ int linux_enumerate_device(struct libusb_context *ctx, * will be reused. instead we should add a simple sysfs attribute with * a session ID. */ session_id = busnum << 8 | devaddr; - usbi_dbg("busnum %u devaddr %u session_id %lu", busnum, devaddr, session_id); + usbi_dbg(ctx, "busnum %u devaddr %u session_id %lu", busnum, devaddr, session_id); dev = usbi_get_device_by_session_id(ctx, session_id); if (dev) { /* device already exists in the context */ - usbi_dbg("session_id %lu already exists", session_id); + usbi_dbg(ctx, "session_id %lu already exists", session_id); libusb_unref_device(dev); return LIBUSB_SUCCESS; } - usbi_dbg("allocating new device for %u/%u (session %lu)", + usbi_dbg(ctx, "allocating new device for %u/%u (session %lu)", busnum, devaddr, session_id); dev = usbi_alloc_device(ctx, session_id); if (!dev) @@ -1143,7 +1157,7 @@ void linux_device_disconnected(uint8_t busnum, uint8_t devaddr) usbi_disconnect_device(dev); libusb_unref_device(dev); } else { - usbi_dbg("device not found for session %lx", session_id); + usbi_dbg(ctx, "device not found for session %lx", session_id); } } usbi_mutex_static_unlock(&active_contexts_lock); @@ -1175,7 +1189,7 @@ static int usbfs_scan_busdir(struct libusb_context *ctx, uint8_t busnum) int r = LIBUSB_ERROR_IO; sprintf(dirpath, USB_DEVTMPFS_PATH "/%03u", busnum); - usbi_dbg("%s", dirpath); + usbi_dbg(ctx, "%s", dirpath); dir = opendir(dirpath); if (!dir) { usbi_err(ctx, "opendir '%s' failed, errno=%d", dirpath, errno); @@ -1191,12 +1205,12 @@ static int usbfs_scan_busdir(struct libusb_context *ctx, uint8_t busnum) continue; if (!parse_u8(entry->d_name, &devaddr)) { - usbi_dbg("unknown dir entry %s", entry->d_name); + usbi_dbg(ctx, "unknown dir entry %s", entry->d_name); continue; } if (linux_enumerate_device(ctx, busnum, devaddr, NULL)) { - usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + usbi_dbg(ctx, "failed to enumerate dir entry %s", entry->d_name); continue; } @@ -1234,12 +1248,12 @@ static int usbfs_get_device_list(struct libusb_context *ctx) r = linux_enumerate_device(ctx, busnum, devaddr, NULL); if (r < 0) { - usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + usbi_dbg(ctx, "failed to enumerate dir entry %s", entry->d_name); continue; } } else { if (!parse_u8(entry->d_name, &busnum)) { - usbi_dbg("unknown dir entry %s", entry->d_name); + usbi_dbg(ctx, "unknown dir entry %s", entry->d_name); continue; } @@ -1274,7 +1288,7 @@ static int sysfs_get_device_list(struct libusb_context *ctx) num_devices++; if (sysfs_scan_device(ctx, entry->d_name)) { - usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + usbi_dbg(ctx, "failed to enumerate dir entry %s", entry->d_name); continue; } @@ -1314,7 +1328,7 @@ static int initialize_handle(struct libusb_device_handle *handle, int fd) r = ioctl(fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps); if (r < 0) { if (errno == ENOTTY) - usbi_dbg("getcap not available"); + usbi_dbg(HANDLE_CTX(handle), "getcap not available"); else usbi_err(HANDLE_CTX(handle), "getcap failed, errno=%d", errno); hpriv->caps = USBFS_CAP_BULK_CONTINUATION; @@ -1348,7 +1362,7 @@ static int op_wrap_sys_device(struct libusb_context *ctx, /* Session id is unused as we do not add the device to the list of * connected devices. */ - usbi_dbg("allocating new device for fd %d", fd); + usbi_dbg(ctx, "allocating new device for fd %d", fd); dev = usbi_alloc_device(ctx, 0); if (!dev) return LIBUSB_ERROR_NO_MEM; @@ -1361,7 +1375,7 @@ static int op_wrap_sys_device(struct libusb_context *ctx, goto out; /* Consider the device as connected, but do not add it to the managed * device list. */ - dev->attached = 1; + usbi_atomic_store(&dev->attached, 1); handle->dev = dev; r = initialize_handle(handle, fd); @@ -1383,8 +1397,8 @@ static int op_open(struct libusb_device_handle *handle) /* device will still be marked as attached if hotplug monitor thread * hasn't processed remove event yet */ usbi_mutex_static_lock(&linux_hotplug_lock); - if (handle->dev->attached) { - usbi_dbg("open failed with no device, but device still attached"); + if (usbi_atomic_load(&handle->dev->attached)) { + usbi_dbg(HANDLE_CTX(handle), "open failed with no device, but device still attached"); linux_device_disconnected(handle->dev->bus_number, handle->dev->device_address); } @@ -1415,22 +1429,27 @@ static int op_get_configuration(struct libusb_device_handle *handle, uint8_t *config) { struct linux_device_priv *priv = usbi_get_device_priv(handle->dev); + int active_config = -1; /* to please compiler */ int r; if (priv->sysfs_dir) { - r = sysfs_get_active_config(handle->dev, config); + r = sysfs_get_active_config(handle->dev, &active_config); } else { struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle); r = usbfs_get_active_config(handle->dev, hpriv->fd); if (r == LIBUSB_SUCCESS) - *config = priv->active_config; + active_config = priv->active_config; } if (r < 0) return r; - if (*config == 0) - usbi_err(HANDLE_CTX(handle), "device unconfigured"); + if (active_config == -1) { + usbi_warn(HANDLE_CTX(handle), "device unconfigured"); + active_config = 0; + } + + *config = (uint8_t)active_config; return 0; } @@ -1454,11 +1473,13 @@ static int op_set_configuration(struct libusb_device_handle *handle, int config) return LIBUSB_ERROR_OTHER; } - if (config == -1) - config = 0; + /* if necessary, update our cached active config descriptor */ + if (!priv->sysfs_dir) { + if (config == 0 && !dev_has_config0(handle->dev)) + config = -1; - /* update our cached active config descriptor */ - priv->active_config = (uint8_t)config; + priv->active_config = config; + } return LIBUSB_SUCCESS; } @@ -1847,11 +1868,11 @@ static int discard_urbs(struct usbi_transfer *itransfer, int first, int last_plu continue; if (errno == EINVAL) { - usbi_dbg("URB not found --> assuming ready to be reaped"); + usbi_dbg(TRANSFER_CTX(transfer), "URB not found --> assuming ready to be reaped"); if (i == (last_plus_one - 1)) ret = LIBUSB_ERROR_NOT_FOUND; } else if (errno == ENODEV) { - usbi_dbg("Device not found for URB --> assuming ready to be reaped"); + usbi_dbg(TRANSFER_CTX(transfer), "Device not found for URB --> assuming ready to be reaped"); ret = LIBUSB_ERROR_NO_DEVICE; } else { usbi_warn(TRANSFER_CTX(transfer), "unrecognised discard errno %d", errno); @@ -1942,7 +1963,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer) last_urb_partial = 1; num_urbs++; } - usbi_dbg("need %d urbs for new transfer with length %d", num_urbs, transfer->length); + usbi_dbg(TRANSFER_CTX(transfer), "need %d urbs for new transfer with length %d", num_urbs, transfer->length); urbs = calloc(num_urbs, sizeof(*urbs)); if (!urbs) return LIBUSB_ERROR_NO_MEM; @@ -2007,7 +2028,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer) /* if the first URB submission fails, we can simply free up and * return failure immediately. */ if (i == 0) { - usbi_dbg("first URB failed, easy peasy"); + usbi_dbg(TRANSFER_CTX(transfer), "first URB failed, easy peasy"); free(urbs); tpriv->urbs = NULL; return r; @@ -2041,7 +2062,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer) discard_urbs(itransfer, 0, i); - usbi_dbg("reporting successful submission but waiting for %d " + usbi_dbg(TRANSFER_CTX(transfer), "reporting successful submission but waiting for %d " "discards before reporting error", i); return 0; } @@ -2092,7 +2113,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) /* usbfs limits the number of iso packets per URB */ num_urbs = (num_packets + (MAX_ISO_PACKETS_PER_URB - 1)) / MAX_ISO_PACKETS_PER_URB; - usbi_dbg("need %d urbs for new transfer with length %d", num_urbs, transfer->length); + usbi_dbg(TRANSFER_CTX(transfer), "need %d urbs for new transfer with length %d", num_urbs, transfer->length); urbs = calloc(num_urbs, sizeof(*urbs)); if (!urbs) @@ -2163,7 +2184,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) /* if the first URB submission fails, we can simply free up and * return failure immediately. */ if (i == 0) { - usbi_dbg("first URB failed, easy peasy"); + usbi_dbg(TRANSFER_CTX(transfer), "first URB failed, easy peasy"); free_iso_urbs(tpriv); return r; } @@ -2188,7 +2209,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) tpriv->num_retired = num_urbs - i; discard_urbs(itransfer, 0, i); - usbi_dbg("reporting successful submission but waiting for %d " + usbi_dbg(TRANSFER_CTX(transfer), "reporting successful submission but waiting for %d " "discards before reporting error", i); return 0; } @@ -2318,14 +2339,14 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer, int urb_idx = urb - tpriv->urbs; usbi_mutex_lock(&itransfer->lock); - usbi_dbg("handling completion status %d of bulk urb %d/%d", urb->status, + usbi_dbg(TRANSFER_CTX(transfer), "handling completion status %d of bulk urb %d/%d", urb->status, urb_idx + 1, tpriv->num_urbs); tpriv->num_retired++; if (tpriv->reap_action != NORMAL) { /* cancelled, submit_fail, or completed early */ - usbi_dbg("abnormal reap: urb status %d", urb->status); + usbi_dbg(TRANSFER_CTX(transfer), "abnormal reap: urb status %d", urb->status); /* even though we're in the process of cancelling, it's possible that * we may receive some data in these URBs that we don't want to lose. @@ -2346,9 +2367,9 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer, if (urb->actual_length > 0) { unsigned char *target = transfer->buffer + itransfer->transferred; - usbi_dbg("received %d bytes of surplus data", urb->actual_length); + usbi_dbg(TRANSFER_CTX(transfer), "received %d bytes of surplus data", urb->actual_length); if (urb->buffer != target) { - usbi_dbg("moving surplus data from offset %zu to offset %zu", + usbi_dbg(TRANSFER_CTX(transfer), "moving surplus data from offset %zu to offset %zu", (unsigned char *)urb->buffer - transfer->buffer, target - transfer->buffer); memmove(target, urb->buffer, urb->actual_length); @@ -2357,7 +2378,7 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer, } if (tpriv->num_retired == tpriv->num_urbs) { - usbi_dbg("abnormal reap: last URB handled, reporting"); + usbi_dbg(TRANSFER_CTX(transfer), "abnormal reap: last URB handled, reporting"); if (tpriv->reap_action != COMPLETED_EARLY && tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) tpriv->reap_status = LIBUSB_TRANSFER_ERROR; @@ -2381,17 +2402,17 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer, break; case -ENODEV: case -ESHUTDOWN: - usbi_dbg("device removed"); + usbi_dbg(TRANSFER_CTX(transfer), "device removed"); tpriv->reap_status = LIBUSB_TRANSFER_NO_DEVICE; goto cancel_remaining; case -EPIPE: - usbi_dbg("detected endpoint stall"); + usbi_dbg(TRANSFER_CTX(transfer), "detected endpoint stall"); if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) tpriv->reap_status = LIBUSB_TRANSFER_STALL; goto cancel_remaining; case -EOVERFLOW: /* overflow can only ever occur in the last urb */ - usbi_dbg("overflow, actual_length=%d", urb->actual_length); + usbi_dbg(TRANSFER_CTX(transfer), "overflow, actual_length=%d", urb->actual_length); if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) tpriv->reap_status = LIBUSB_TRANSFER_OVERFLOW; goto completed; @@ -2400,7 +2421,7 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer, case -EILSEQ: case -ECOMM: case -ENOSR: - usbi_dbg("low-level bus error %d", urb->status); + usbi_dbg(TRANSFER_CTX(transfer), "low-level bus error %d", urb->status); tpriv->reap_action = ERROR; goto cancel_remaining; default: @@ -2412,10 +2433,10 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer, /* if we've reaped all urbs or we got less data than requested then we're * done */ if (tpriv->num_retired == tpriv->num_urbs) { - usbi_dbg("all URBs in transfer reaped --> complete!"); + usbi_dbg(TRANSFER_CTX(transfer), "all URBs in transfer reaped --> complete!"); goto completed; } else if (urb->actual_length < urb->buffer_length) { - usbi_dbg("short transfer %d/%d --> complete!", + usbi_dbg(TRANSFER_CTX(transfer), "short transfer %d/%d --> complete!", urb->actual_length, urb->buffer_length); if (tpriv->reap_action == NORMAL) tpriv->reap_action = COMPLETED_EARLY; @@ -2471,7 +2492,7 @@ static int handle_iso_completion(struct usbi_transfer *itransfer, return LIBUSB_ERROR_NOT_FOUND; } - usbi_dbg("handling completion status %d of iso urb %d/%d", urb->status, + usbi_dbg(TRANSFER_CTX(transfer), "handling completion status %d of iso urb %d/%d", urb->status, urb_idx, num_urbs); /* copy isochronous results back in */ @@ -2490,15 +2511,15 @@ static int handle_iso_completion(struct usbi_transfer *itransfer, break; case -ENODEV: case -ESHUTDOWN: - usbi_dbg("packet %d - device removed", i); + usbi_dbg(TRANSFER_CTX(transfer), "packet %d - device removed", i); lib_desc->status = LIBUSB_TRANSFER_NO_DEVICE; break; case -EPIPE: - usbi_dbg("packet %d - detected endpoint stall", i); + usbi_dbg(TRANSFER_CTX(transfer), "packet %d - detected endpoint stall", i); lib_desc->status = LIBUSB_TRANSFER_STALL; break; case -EOVERFLOW: - usbi_dbg("packet %d - overflow error", i); + usbi_dbg(TRANSFER_CTX(transfer), "packet %d - overflow error", i); lib_desc->status = LIBUSB_TRANSFER_OVERFLOW; break; case -ETIME: @@ -2507,7 +2528,7 @@ static int handle_iso_completion(struct usbi_transfer *itransfer, case -ECOMM: case -ENOSR: case -EXDEV: - usbi_dbg("packet %d - low-level USB error %d", i, urb_desc->status); + usbi_dbg(TRANSFER_CTX(transfer), "packet %d - low-level USB error %d", i, urb_desc->status); lib_desc->status = LIBUSB_TRANSFER_ERROR; break; default: @@ -2522,10 +2543,10 @@ static int handle_iso_completion(struct usbi_transfer *itransfer, tpriv->num_retired++; if (tpriv->reap_action != NORMAL) { /* cancelled or submit_fail */ - usbi_dbg("CANCEL: urb status %d", urb->status); + usbi_dbg(TRANSFER_CTX(transfer), "CANCEL: urb status %d", urb->status); if (tpriv->num_retired == num_urbs) { - usbi_dbg("CANCEL: last URB handled, reporting"); + usbi_dbg(TRANSFER_CTX(transfer), "CANCEL: last URB handled, reporting"); free_iso_urbs(tpriv); if (tpriv->reap_action == CANCELLED) { usbi_mutex_unlock(&itransfer->lock); @@ -2545,7 +2566,7 @@ static int handle_iso_completion(struct usbi_transfer *itransfer, case -ECONNRESET: break; case -ESHUTDOWN: - usbi_dbg("device removed"); + usbi_dbg(TRANSFER_CTX(transfer), "device removed"); status = LIBUSB_TRANSFER_NO_DEVICE; break; default: @@ -2556,7 +2577,7 @@ static int handle_iso_completion(struct usbi_transfer *itransfer, /* if we've reaped all urbs then we're done */ if (tpriv->num_retired == num_urbs) { - usbi_dbg("all URBs in transfer reaped --> complete!"); + usbi_dbg(TRANSFER_CTX(transfer), "all URBs in transfer reaped --> complete!"); free_iso_urbs(tpriv); usbi_mutex_unlock(&itransfer->lock); return usbi_handle_transfer_completion(itransfer, status); @@ -2574,7 +2595,7 @@ static int handle_control_completion(struct usbi_transfer *itransfer, int status; usbi_mutex_lock(&itransfer->lock); - usbi_dbg("handling completion status %d", urb->status); + usbi_dbg(ITRANSFER_CTX(itransfer), "handling completion status %d", urb->status); itransfer->transferred += urb->actual_length; @@ -2597,15 +2618,15 @@ static int handle_control_completion(struct usbi_transfer *itransfer, break; case -ENODEV: case -ESHUTDOWN: - usbi_dbg("device removed"); + usbi_dbg(ITRANSFER_CTX(itransfer), "device removed"); status = LIBUSB_TRANSFER_NO_DEVICE; break; case -EPIPE: - usbi_dbg("unsupported control request"); + usbi_dbg(ITRANSFER_CTX(itransfer), "unsupported control request"); status = LIBUSB_TRANSFER_STALL; break; case -EOVERFLOW: - usbi_dbg("overflow, actual_length=%d", urb->actual_length); + usbi_dbg(ITRANSFER_CTX(itransfer), "overflow, actual_length=%d", urb->actual_length); status = LIBUSB_TRANSFER_OVERFLOW; break; case -ETIME: @@ -2613,7 +2634,7 @@ static int handle_control_completion(struct usbi_transfer *itransfer, case -EILSEQ: case -ECOMM: case -ENOSR: - usbi_dbg("low-level bus error %d", urb->status); + usbi_dbg(ITRANSFER_CTX(itransfer), "low-level bus error %d", urb->status); status = LIBUSB_TRANSFER_ERROR; break; default: @@ -2650,7 +2671,7 @@ static int reap_for_handle(struct libusb_device_handle *handle) itransfer = urb->usercontext; transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); - usbi_dbg("urb type=%u status=%d transferred=%d", urb->type, urb->status, urb->actual_length); + usbi_dbg(HANDLE_CTX(handle), "urb type=%u status=%d transferred=%d", urb->type, urb->status, urb->actual_length); switch (transfer->type) { case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: @@ -2707,7 +2728,7 @@ static int op_handle_events(struct libusb_context *ctx, /* device will still be marked as attached if hotplug monitor thread * hasn't processed remove event yet */ usbi_mutex_static_lock(&linux_hotplug_lock); - if (handle->dev->attached) + if (usbi_atomic_load(&handle->dev->attached)) linux_device_disconnected(handle->dev->bus_number, handle->dev->device_address); usbi_mutex_static_unlock(&linux_hotplug_lock); |