mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
USB fixes for 6.17-rc6
Here are some small USB driver fixes and new device ids for 6.17-rc6.
Included in here are:
- new usb-serial driver device ids
- dummy-hcd locking bugfix for rt-enabled systems (which is crazy, but
people have odd testing requirements at times...)
- xhci driver bugfixes for reported issues
- typec driver bugfix
- midi2 gadget driver bugfixes
- usb core sysfs file regression fix from -rc1
All of these, except for the last usb sysfs file fix, have been in
linux-next with no reported issues. The sysfs fix was added to the tree
on Friday, and is "obviously correct" and should not have any problems
either, it just didn't have any time for linux-next to pick up (0-day
had no problems with it.)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-----BEGIN PGP SIGNATURE-----
iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaMas6Q8cZ3JlZ0Brcm9h
aC5jb20ACgkQMUfUDdst+ynTnQCcCnZGqZrq8wiioAa4AzwRkM0PqAAAn3N0yrx4
BXF8pTnpOkYZmjX1cIzK
=GoFM
-----END PGP SIGNATURE-----
Merge tag 'usb-6.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH:
"Here are some small USB driver fixes and new device ids for 6.17-rc6.
Included in here are:
- new usb-serial driver device ids
- dummy-hcd locking bugfix for rt-enabled systems (which is crazy,
but people have odd testing requirements at times...)
- xhci driver bugfixes for reported issues
- typec driver bugfix
- midi2 gadget driver bugfixes
- usb core sysfs file regression fix from -rc1
All of these, except for the last usb sysfs file fix, have been in
linux-next with no reported issues. The sysfs fix was added to the
tree on Friday, and is "obviously correct" and should not have any
problems either, it just didn't have any time for linux-next to pick
up (0-day had no problems with it)"
* tag 'usb-6.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
USB: core: remove the move buf action
usb: gadget: midi2: Fix MIDI2 IN EP max packet size
usb: gadget: midi2: Fix missing UMP group attributes initialization
usb: typec: tcpm: properly deliver cable vdms to altmode drivers
USB: gadget: dummy-hcd: Fix locking bug in RT-enabled kernels
xhci: fix memory leak regression when freeing xhci vdev devices depth first
xhci: dbc: Fix full DbC transfer ring after several reconnects
xhci: dbc: decouple endpoint allocation from initialization
USB: serial: option: add Telit Cinterion LE910C4-WWX new compositions
USB: serial: option: add Telit Cinterion FN990A w/audio compositions
This commit is contained in:
commit
d6b42787f3
|
|
@ -119,11 +119,11 @@ ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf)
|
|||
guard(mutex)(&usb_dynids_lock);
|
||||
list_for_each_entry(dynid, &dynids->list, node)
|
||||
if (dynid->id.bInterfaceClass != 0)
|
||||
count += sysfs_emit_at(&buf[count], count, "%04x %04x %02x\n",
|
||||
count += sysfs_emit_at(buf, count, "%04x %04x %02x\n",
|
||||
dynid->id.idVendor, dynid->id.idProduct,
|
||||
dynid->id.bInterfaceClass);
|
||||
else
|
||||
count += sysfs_emit_at(&buf[count], count, "%04x %04x\n",
|
||||
count += sysfs_emit_at(buf, count, "%04x %04x\n",
|
||||
dynid->id.idVendor, dynid->id.idProduct);
|
||||
return count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1599,6 +1599,7 @@ static int f_midi2_create_card(struct f_midi2 *midi2)
|
|||
strscpy(fb->info.name, ump_fb_name(b),
|
||||
sizeof(fb->info.name));
|
||||
}
|
||||
snd_ump_update_group_attrs(ump);
|
||||
}
|
||||
|
||||
for (i = 0; i < midi2->num_eps; i++) {
|
||||
|
|
@ -1736,9 +1737,12 @@ static int f_midi2_create_usb_configs(struct f_midi2 *midi2,
|
|||
case USB_SPEED_HIGH:
|
||||
midi2_midi1_ep_out_desc.wMaxPacketSize = cpu_to_le16(512);
|
||||
midi2_midi1_ep_in_desc.wMaxPacketSize = cpu_to_le16(512);
|
||||
for (i = 0; i < midi2->num_eps; i++)
|
||||
for (i = 0; i < midi2->num_eps; i++) {
|
||||
midi2_midi2_ep_out_desc[i].wMaxPacketSize =
|
||||
cpu_to_le16(512);
|
||||
midi2_midi2_ep_in_desc[i].wMaxPacketSize =
|
||||
cpu_to_le16(512);
|
||||
}
|
||||
fallthrough;
|
||||
case USB_SPEED_FULL:
|
||||
midi1_in_eps = midi2_midi1_ep_in_descs;
|
||||
|
|
@ -1747,9 +1751,12 @@ static int f_midi2_create_usb_configs(struct f_midi2 *midi2,
|
|||
case USB_SPEED_SUPER:
|
||||
midi2_midi1_ep_out_desc.wMaxPacketSize = cpu_to_le16(1024);
|
||||
midi2_midi1_ep_in_desc.wMaxPacketSize = cpu_to_le16(1024);
|
||||
for (i = 0; i < midi2->num_eps; i++)
|
||||
for (i = 0; i < midi2->num_eps; i++) {
|
||||
midi2_midi2_ep_out_desc[i].wMaxPacketSize =
|
||||
cpu_to_le16(1024);
|
||||
midi2_midi2_ep_in_desc[i].wMaxPacketSize =
|
||||
cpu_to_le16(1024);
|
||||
}
|
||||
midi1_in_eps = midi2_midi1_ep_in_ss_descs;
|
||||
midi1_out_eps = midi2_midi1_ep_out_ss_descs;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -765,8 +765,7 @@ static int dummy_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
|||
if (!dum->driver)
|
||||
return -ESHUTDOWN;
|
||||
|
||||
local_irq_save(flags);
|
||||
spin_lock(&dum->lock);
|
||||
spin_lock_irqsave(&dum->lock, flags);
|
||||
list_for_each_entry(iter, &ep->queue, queue) {
|
||||
if (&iter->req != _req)
|
||||
continue;
|
||||
|
|
@ -776,15 +775,16 @@ static int dummy_dequeue(struct usb_ep *_ep, struct usb_request *_req)
|
|||
retval = 0;
|
||||
break;
|
||||
}
|
||||
spin_unlock(&dum->lock);
|
||||
|
||||
if (retval == 0) {
|
||||
dev_dbg(udc_dev(dum),
|
||||
"dequeued req %p from %s, len %d buf %p\n",
|
||||
req, _ep->name, _req->length, _req->buf);
|
||||
spin_unlock(&dum->lock);
|
||||
usb_gadget_giveback_request(_ep, _req);
|
||||
spin_lock(&dum->lock);
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
spin_unlock_irqrestore(&dum->lock, flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,13 +101,34 @@ static u32 xhci_dbc_populate_strings(struct dbc_str_descs *strings)
|
|||
return string_length;
|
||||
}
|
||||
|
||||
static void xhci_dbc_init_ep_contexts(struct xhci_dbc *dbc)
|
||||
{
|
||||
struct xhci_ep_ctx *ep_ctx;
|
||||
unsigned int max_burst;
|
||||
dma_addr_t deq;
|
||||
|
||||
max_burst = DBC_CTRL_MAXBURST(readl(&dbc->regs->control));
|
||||
|
||||
/* Populate bulk out endpoint context: */
|
||||
ep_ctx = dbc_bulkout_ctx(dbc);
|
||||
deq = dbc_bulkout_enq(dbc);
|
||||
ep_ctx->ep_info = 0;
|
||||
ep_ctx->ep_info2 = dbc_epctx_info2(BULK_OUT_EP, 1024, max_burst);
|
||||
ep_ctx->deq = cpu_to_le64(deq | dbc->ring_out->cycle_state);
|
||||
|
||||
/* Populate bulk in endpoint context: */
|
||||
ep_ctx = dbc_bulkin_ctx(dbc);
|
||||
deq = dbc_bulkin_enq(dbc);
|
||||
ep_ctx->ep_info = 0;
|
||||
ep_ctx->ep_info2 = dbc_epctx_info2(BULK_IN_EP, 1024, max_burst);
|
||||
ep_ctx->deq = cpu_to_le64(deq | dbc->ring_in->cycle_state);
|
||||
}
|
||||
|
||||
static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length)
|
||||
{
|
||||
struct dbc_info_context *info;
|
||||
struct xhci_ep_ctx *ep_ctx;
|
||||
u32 dev_info;
|
||||
dma_addr_t deq, dma;
|
||||
unsigned int max_burst;
|
||||
dma_addr_t dma;
|
||||
|
||||
if (!dbc)
|
||||
return;
|
||||
|
|
@ -121,20 +142,8 @@ static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length)
|
|||
info->serial = cpu_to_le64(dma + DBC_MAX_STRING_LENGTH * 3);
|
||||
info->length = cpu_to_le32(string_length);
|
||||
|
||||
/* Populate bulk out endpoint context: */
|
||||
ep_ctx = dbc_bulkout_ctx(dbc);
|
||||
max_burst = DBC_CTRL_MAXBURST(readl(&dbc->regs->control));
|
||||
deq = dbc_bulkout_enq(dbc);
|
||||
ep_ctx->ep_info = 0;
|
||||
ep_ctx->ep_info2 = dbc_epctx_info2(BULK_OUT_EP, 1024, max_burst);
|
||||
ep_ctx->deq = cpu_to_le64(deq | dbc->ring_out->cycle_state);
|
||||
|
||||
/* Populate bulk in endpoint context: */
|
||||
ep_ctx = dbc_bulkin_ctx(dbc);
|
||||
deq = dbc_bulkin_enq(dbc);
|
||||
ep_ctx->ep_info = 0;
|
||||
ep_ctx->ep_info2 = dbc_epctx_info2(BULK_IN_EP, 1024, max_burst);
|
||||
ep_ctx->deq = cpu_to_le64(deq | dbc->ring_in->cycle_state);
|
||||
/* Populate bulk in and out endpoint contexts: */
|
||||
xhci_dbc_init_ep_contexts(dbc);
|
||||
|
||||
/* Set DbC context and info registers: */
|
||||
lo_hi_writeq(dbc->ctx->dma, &dbc->regs->dccp);
|
||||
|
|
@ -436,6 +445,42 @@ dbc_alloc_ctx(struct device *dev, gfp_t flags)
|
|||
return ctx;
|
||||
}
|
||||
|
||||
static void xhci_dbc_ring_init(struct xhci_ring *ring)
|
||||
{
|
||||
struct xhci_segment *seg = ring->first_seg;
|
||||
|
||||
/* clear all trbs on ring in case of old ring */
|
||||
memset(seg->trbs, 0, TRB_SEGMENT_SIZE);
|
||||
|
||||
/* Only event ring does not use link TRB */
|
||||
if (ring->type != TYPE_EVENT) {
|
||||
union xhci_trb *trb = &seg->trbs[TRBS_PER_SEGMENT - 1];
|
||||
|
||||
trb->link.segment_ptr = cpu_to_le64(ring->first_seg->dma);
|
||||
trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK));
|
||||
}
|
||||
xhci_initialize_ring_info(ring);
|
||||
}
|
||||
|
||||
static int xhci_dbc_reinit_ep_rings(struct xhci_dbc *dbc)
|
||||
{
|
||||
struct xhci_ring *in_ring = dbc->eps[BULK_IN].ring;
|
||||
struct xhci_ring *out_ring = dbc->eps[BULK_OUT].ring;
|
||||
|
||||
if (!in_ring || !out_ring || !dbc->ctx) {
|
||||
dev_warn(dbc->dev, "Can't re-init unallocated endpoints\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
xhci_dbc_ring_init(in_ring);
|
||||
xhci_dbc_ring_init(out_ring);
|
||||
|
||||
/* set ep context enqueue, dequeue, and cycle to initial values */
|
||||
xhci_dbc_init_ep_contexts(dbc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xhci_ring *
|
||||
xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags)
|
||||
{
|
||||
|
|
@ -464,15 +509,10 @@ xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags)
|
|||
|
||||
seg->dma = dma;
|
||||
|
||||
/* Only event ring does not use link TRB */
|
||||
if (type != TYPE_EVENT) {
|
||||
union xhci_trb *trb = &seg->trbs[TRBS_PER_SEGMENT - 1];
|
||||
|
||||
trb->link.segment_ptr = cpu_to_le64(dma);
|
||||
trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK));
|
||||
}
|
||||
INIT_LIST_HEAD(&ring->td_list);
|
||||
xhci_initialize_ring_info(ring);
|
||||
|
||||
xhci_dbc_ring_init(ring);
|
||||
|
||||
return ring;
|
||||
dma_fail:
|
||||
kfree(seg);
|
||||
|
|
@ -864,7 +904,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
|
|||
dev_info(dbc->dev, "DbC cable unplugged\n");
|
||||
dbc->state = DS_ENABLED;
|
||||
xhci_dbc_flush_requests(dbc);
|
||||
|
||||
xhci_dbc_reinit_ep_rings(dbc);
|
||||
return EVT_DISC;
|
||||
}
|
||||
|
||||
|
|
@ -874,7 +914,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
|
|||
writel(portsc, &dbc->regs->portsc);
|
||||
dbc->state = DS_ENABLED;
|
||||
xhci_dbc_flush_requests(dbc);
|
||||
|
||||
xhci_dbc_reinit_ep_rings(dbc);
|
||||
return EVT_DISC;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -962,7 +962,7 @@ static void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_i
|
|||
out:
|
||||
/* we are now at a leaf device */
|
||||
xhci_debugfs_remove_slot(xhci, slot_id);
|
||||
xhci_free_virt_device(xhci, vdev, slot_id);
|
||||
xhci_free_virt_device(xhci, xhci->devs[slot_id], slot_id);
|
||||
}
|
||||
|
||||
int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
|
||||
|
|
|
|||
|
|
@ -1322,7 +1322,18 @@ static const struct usb_device_id option_ids[] = {
|
|||
.driver_info = NCTRL(0) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */
|
||||
.driver_info = NCTRL(0) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1034, 0xff), /* Telit LE910C4-WWX (rmnet) */
|
||||
.driver_info = RSVD(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1035, 0xff) }, /* Telit LE910C4-WWX (ECM) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1036, 0xff) }, /* Telit LE910C4-WWX */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1037, 0xff), /* Telit LE910C4-WWX (rmnet) */
|
||||
.driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1038, 0xff), /* Telit LE910C4-WWX (rmnet) */
|
||||
.driver_info = NCTRL(0) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x103b, 0xff), /* Telit LE910C4-WWX */
|
||||
.driver_info = NCTRL(0) | NCTRL(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x103c, 0xff), /* Telit LE910C4-WWX */
|
||||
.driver_info = NCTRL(0) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0),
|
||||
.driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1),
|
||||
|
|
@ -1369,6 +1380,12 @@ static const struct usb_device_id option_ids[] = {
|
|||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990A (PCIe) */
|
||||
.driver_info = RSVD(0) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1077, 0xff), /* Telit FN990A (rmnet + audio) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1078, 0xff), /* Telit FN990A (MBIM + audio) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1079, 0xff), /* Telit FN990A (RNDIS + audio) */
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990A (rmnet) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1081, 0xff), /* Telit FE990A (MBIM) */
|
||||
|
|
|
|||
|
|
@ -2426,17 +2426,21 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
|
|||
case ADEV_NONE:
|
||||
break;
|
||||
case ADEV_NOTIFY_USB_AND_QUEUE_VDM:
|
||||
WARN_ON(typec_altmode_notify(adev, TYPEC_STATE_USB, NULL));
|
||||
typec_altmode_vdm(adev, p[0], &p[1], cnt);
|
||||
if (rx_sop_type == TCPC_TX_SOP_PRIME) {
|
||||
typec_cable_altmode_vdm(adev, TYPEC_PLUG_SOP_P, p[0], &p[1], cnt);
|
||||
} else {
|
||||
WARN_ON(typec_altmode_notify(adev, TYPEC_STATE_USB, NULL));
|
||||
typec_altmode_vdm(adev, p[0], &p[1], cnt);
|
||||
}
|
||||
break;
|
||||
case ADEV_QUEUE_VDM:
|
||||
if (response_tx_sop_type == TCPC_TX_SOP_PRIME)
|
||||
if (rx_sop_type == TCPC_TX_SOP_PRIME)
|
||||
typec_cable_altmode_vdm(adev, TYPEC_PLUG_SOP_P, p[0], &p[1], cnt);
|
||||
else
|
||||
typec_altmode_vdm(adev, p[0], &p[1], cnt);
|
||||
break;
|
||||
case ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL:
|
||||
if (response_tx_sop_type == TCPC_TX_SOP_PRIME) {
|
||||
if (rx_sop_type == TCPC_TX_SOP_PRIME) {
|
||||
if (typec_cable_altmode_vdm(adev, TYPEC_PLUG_SOP_P,
|
||||
p[0], &p[1], cnt)) {
|
||||
int svdm_version = typec_get_cable_svdm_version(
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user