mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-27 23:25:13 -04:00
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:
@@ -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=
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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 },
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user