Merge tag 'usb-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB / Thunderbolt fixes from Greg KH:
 "Here are some small USB and Thunderbolt driver fixes for 7.2-rc7 that
  resolve some reported issues. Included in here are:

   - new quirk for some broken USB devices

   - thunderbolt device fixes for reported issues

   - usb gadget driver fix

   - usb atm driver fix

   - xhci driver fixes.

   - other minor USB driver fixes

  All of these have been in linux-next this week with no reported
  issues"

* tag 'usb-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: xhci: use BIT_ULL for CRCR bits to fix incorrect 64bit mask
  usb: quirks: Add ShanWan gamepad to quirk list
  usb: hub: Split announce_device() to log device identity before enumeration
  usb: core: Add quirk for 255-bytes initial config read
  usb: atm: cxacru: properly kill rcv_urb on error in cxacru_cm()
  usb: misc: usbio: check ibuf_len against rxbuf_len in bulk msg
  usb: gadget: f_ncm: Use unsigned int for ndp_index
  usb: cdnsp: fix incorrect endian conversions for APB timeout register
  thunderbolt: Initialize ->domain_released completion before it is being used
  thunderbolt: icm: Preserve USB4 proxy data-valid bit
  thunderbolt: Bound the DROM dual link port number before indexing sw->ports
  thunderbolt: Fix bandwidth group reservation indexing
  thunderbolt: stream: Unmap buffers with mapped size
This commit is contained in:
Linus Torvalds
2026-08-08 16:33:04 -07:00
15 changed files with 76 additions and 28 deletions

View File

@@ -8169,6 +8169,11 @@ Kernel parameters
q = USB_QUIRK_FORCE_ONE_CONFIG (Device
claims zero configurations,
forcing to 1);
r = USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE (Device
fails during initialization when asked for
9-bytes configuration descriptor request.
Ask for 255-bytes request instead to mirror
Windows' behavior);
Example: quirks=0781:5580:bk,0a5c:5834:gij
usbhid.mousepoll=

View File

@@ -394,9 +394,16 @@ static int tb_drom_parse_entry_port(struct tb_switch *sw,
return -EIO;
}
port->link_nr = entry->link_nr;
if (entry->has_dual_link_port)
if (entry->has_dual_link_port) {
if (entry->dual_link_port_nr > sw->config.max_port_number) {
tb_sw_warn(sw,
"port entry has invalid dual link port number %u\n",
entry->dual_link_port_nr);
return -EIO;
}
port->dual_link_port =
&port->sw->ports[entry->dual_link_port_nr];
}
}
return 0;
}

View File

@@ -2341,7 +2341,7 @@ static int icm_usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata,
if (tx_data_len) {
request.data_len_valid |= ICM_USB4_SWITCH_DATA_VALID;
if (tx_data_len < ARRAY_SIZE(request.data))
request.data_len_valid =
request.data_len_valid |=
tx_data_len & ICM_USB4_SWITCH_DATA_LEN_MASK;
memcpy(request.data, tx_data, tx_data_len * sizeof(u32));
}

View File

@@ -1226,6 +1226,8 @@ int nhi_probe(struct tb_nhi *nhi)
return dev_err_probe(dev, res, "NHI specific init failed\n");
}
init_completion(&nhi->domain_released);
tb = nhi_select_cm(nhi);
if (!tb)
return dev_err_probe(dev, -ENODEV,
@@ -1233,8 +1235,6 @@ int nhi_probe(struct tb_nhi *nhi)
dev_dbg(dev, "NHI initialized, starting thunderbolt\n");
init_completion(&nhi->domain_released);
res = tb_domain_add(tb, host_reset);
if (res) {
/*

View File

@@ -257,7 +257,7 @@ static void tbstream_ring_free(struct tbstream_ring *ring)
if (sf->frame.buffer_phy)
dma_unmap_page(dma_dev, sf->frame.buffer_phy,
tb_ring_frame_size(&sf->frame), dir);
TB_MAX_FRAME_SIZE, dir);
sf->frame.buffer_phy = 0;
if (sf->page)
__free_page(sf->page);

View File

@@ -609,7 +609,7 @@ static int tb_consumed_dp_bandwidth(struct tb *tb,
int *consumed_up,
int *consumed_down)
{
int group_reserved[MAX_GROUPS] = {};
int group_reserved[MAX_GROUPS + 1] = {};
struct tb_cm *tcm = tb_priv(tb);
struct tb_tunnel *tunnel;
bool downstream;

View File

@@ -700,6 +700,8 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
ret = offd;
usb_dbg(instance->usbatm, "cm %#x\n", cm);
fail:
if (ret < 0)
usb_kill_urb(instance->rcv_urb);
mutex_unlock(&instance->cm_serialize);
err:
return ret;

View File

@@ -163,9 +163,9 @@ static void cdnsp_set_apb_timeout_value(struct cdnsp_device *pdev)
offset = cdnsp_find_next_ext_cap(base, offset, D_XEC_PRE_REGS_CAP);
reg = base + offset + REG_CHICKEN_BITS_3_OFFSET;
val = le32_to_cpu(readl(reg));
val = readl(reg);
val = CHICKEN_APB_TIMEOUT_SET(val, cdns->override_apb_timeout);
writel(cpu_to_le32(val), reg);
writel(val, reg);
}
static void cdnsp_set_chicken_bits_2(struct cdnsp_device *pdev, u32 bit)

View File

@@ -912,6 +912,18 @@ int usb_get_configuration(struct usb_device *dev)
unsigned char *bigbuffer;
struct usb_config_descriptor *desc;
int result;
size_t usb_config_req_size;
/*
* We usually start by grabbing the first 9-bytes descriptor so we know
* how long the whole configuration is. Some devices with quirky
* firmware will fail enumeration, so if the quirk is set, use 255 instead,
* mirroring the behavior of Windows.
*/
if (dev->quirks & USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE)
usb_config_req_size = 255;
else
usb_config_req_size = USB_DT_CONFIG_SIZE;
if (ncfg > USB_MAXCONFIG) {
dev_notice(ddev, "too many configurations: %d, "
@@ -938,15 +950,13 @@ int usb_get_configuration(struct usb_device *dev)
if (!dev->rawdescriptors)
return -ENOMEM;
desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
desc = kmalloc(usb_config_req_size, GFP_KERNEL);
if (!desc)
return -ENOMEM;
for (cfgno = 0; cfgno < ncfg; cfgno++) {
/* We grab just the first descriptor so we know how long
* the whole configuration is */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
desc, USB_DT_CONFIG_SIZE);
desc, usb_config_req_size);
if (result < 0) {
dev_err(ddev, "unable to read config index %d "
"descriptor/%s: %d\n", cfgno, "start", result);
@@ -956,16 +966,14 @@ int usb_get_configuration(struct usb_device *dev)
dev->descriptor.bNumConfigurations = cfgno;
break;
} else if (result < 4) {
dev_err(ddev, "config index %d descriptor too short "
"(expected %i, got %i)\n", cfgno,
USB_DT_CONFIG_SIZE, result);
dev_err(ddev, "config index %d descriptor too short (asked for %zu, got %i)\n",
cfgno, usb_config_req_size, result);
result = -EINVAL;
goto err;
}
length = max_t(int, le16_to_cpu(desc->wTotalLength),
USB_DT_CONFIG_SIZE);
/* Now that we know the length, get the whole thing */
bigbuffer = kmalloc(length, GFP_KERNEL);
if (!bigbuffer) {
result = -ENOMEM;
@@ -975,6 +983,13 @@ int usb_get_configuration(struct usb_device *dev)
if (dev->quirks & USB_QUIRK_DELAY_INIT)
msleep(200);
/* Skip the second read if we already got everything */
if (result >= length) {
memcpy(bigbuffer, desc, length);
goto store_and_parse;
}
/* Get the whole thing */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
bigbuffer, length);
if (result < 0) {
@@ -989,6 +1004,7 @@ int usb_get_configuration(struct usb_device *dev)
length = result;
}
store_and_parse:
dev->rawdescriptors[cfgno] = bigbuffer;
result = usb_parse_configuration(dev, cfgno,

View File

@@ -2401,7 +2401,7 @@ static void show_string(struct usb_device *udev, char *id, char *string)
dev_info(&udev->dev, "%s: %s\n", id, string);
}
static void announce_device(struct usb_device *udev)
static void announce_device_ids(struct usb_device *udev)
{
u16 bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice);
@@ -2410,6 +2410,10 @@ static void announce_device(struct usb_device *udev)
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct),
bcdDevice >> 8, bcdDevice & 0xff);
}
static void announce_device_strings(struct usb_device *udev)
{
dev_info(&udev->dev,
"New USB device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
udev->descriptor.iManufacturer,
@@ -2420,7 +2424,8 @@ static void announce_device(struct usb_device *udev)
show_string(udev, "SerialNumber", udev->serial);
}
#else
static inline void announce_device(struct usb_device *udev) { }
static inline void announce_device_ids(struct usb_device *udev) { }
static inline void announce_device_strings(struct usb_device *udev) { }
#endif
@@ -2651,6 +2656,9 @@ int usb_new_device(struct usb_device *udev)
device_init_wakeup(&udev->dev, 0);
}
/* Announce the device identity */
announce_device_ids(udev);
/* Tell the runtime-PM framework the device is active */
pm_runtime_set_active(&udev->dev);
pm_runtime_get_noresume(&udev->dev);
@@ -2672,8 +2680,8 @@ int usb_new_device(struct usb_device *udev)
udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,
(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
/* Tell the world! */
announce_device(udev);
/* Announce the device's product, manufacturer and serial number */
announce_device_strings(udev);
if (udev->serial)
add_device_randomness(udev->serial, strlen(udev->serial));

View File

@@ -142,6 +142,10 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp)
break;
case 'q':
flags |= USB_QUIRK_FORCE_ONE_CONFIG;
break;
case 'r':
flags |= USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE;
break;
/* Ignore unrecognized flag characters */
}
}
@@ -589,6 +593,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x2386, 0x350e), .driver_info = USB_QUIRK_NO_LPM },
/* ShanWan Wireless Gamepad */
{ USB_DEVICE(0x2563, 0x0575), .driver_info = USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE },
/* UGREEN 35871 - BOS descriptor fetch hangs at SuperSpeed Plus */
{ USB_DEVICE(0x2b89, 0x5871), .driver_info = USB_QUIRK_NO_BOS },

View File

@@ -1171,7 +1171,7 @@ static int ncm_unwrap_ntb(struct gether *port,
unsigned char *ntb_ptr = skb->data;
__le16 *tmp;
unsigned index, index2;
int ndp_index;
unsigned int ndp_index;
unsigned dg_len, dg_len2;
unsigned ndp_len;
unsigned block_len;

View File

@@ -190,13 +190,13 @@ struct xhci_op_regs {
/* CRCR - Command Ring Control Register - cmd_ring bitmasks */
/* bit 0 - Cycle bit indicates the ownership of the command ring */
#define CMD_RING_CYCLE BIT(0)
#define CMD_RING_CYCLE BIT_ULL(0)
/* stop ring operation after completion of the currently executing command */
#define CMD_RING_PAUSE BIT(1)
#define CMD_RING_PAUSE BIT_ULL(1)
/* stop ring immediately - abort the currently executing command */
#define CMD_RING_ABORT BIT(2)
#define CMD_RING_ABORT BIT_ULL(2)
/* true: command ring is running */
#define CMD_RING_RUNNING BIT(3)
#define CMD_RING_RUNNING BIT_ULL(3)
/* bits 63:6 - Command Ring pointer */
#define CMD_RING_PTR_MASK GENMASK_ULL(63, 6)
@@ -271,7 +271,7 @@ struct xhci_intr_reg {
* bit 3 - Event Handler Busy (EHB), whether the event ring is scheduled to be serviced by
* a work queue (or delayed service routine)?
*/
#define ERST_EHB BIT(3)
#define ERST_EHB BIT_ULL(3)
/* bits 63:4 - Event Ring Dequeue Pointer */
#define ERST_PTR_MASK GENMASK_ULL(63, 4)
@@ -502,7 +502,7 @@ struct xhci_ep_ctx {
#define CTX_TO_MAX_ESIT_PAYLOAD(p) (((p) >> 16) & 0xffff)
/* deq bitmasks */
#define EP_CTX_CYCLE_MASK BIT(0)
#define EP_CTX_CYCLE_MASK BIT_ULL(0)
/* bits 63:4 - TR Dequeue Pointer */
#define TR_DEQ_PTR_MASK GENMASK_ULL(63, 4)

View File

@@ -265,7 +265,7 @@ int usbio_bulk_msg(struct auxiliary_device *adev, u8 type, u8 cmd, bool last,
lockdep_assert_held(&usbio->bulk_mutex);
if ((obuf_len > (usbio->txbuf_len - sizeof(*bpkt))) ||
(ibuf_len > (usbio->txbuf_len - sizeof(*bpkt))))
(ibuf_len > (usbio->rxbuf_len - sizeof(*bpkt))))
return -EMSGSIZE;
if (ibuf_len)

View File

@@ -81,4 +81,7 @@
/* Device claims zero configurations, forcing to 1 */
#define USB_QUIRK_FORCE_ONE_CONFIG BIT(18)
/* Use a 255 bytes config descriptor request mirroring windows behavior */
#define USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE BIT(19)
#endif /* __LINUX_USB_QUIRKS_H */