Skip to content

Commit 6a65554

Browse files
committed
Merge tag 'usb-5.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB driver fixes from Greg KH: "Here are some small USB driver fixes for 5.14-rc5. They resolve a number of small reported issues, including: - cdnsp driver fixes - usb serial driver fixes and device id updates - usb gadget hid fixes - usb host driver fixes - usb dwc3 driver fixes - other usb gadget driver fixes All of these have been in linux-next for a while with no reported issues" * tag 'usb-5.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (21 commits) usb: typec: tcpm: Keep other events when receiving FRS and Sourcing_vbus events usb: dwc3: gadget: Avoid runtime resume if disabling pullup usb: dwc3: gadget: Use list_replace_init() before traversing lists USB: serial: ftdi_sio: add device ID for Auto-M3 OP-COM v2 USB: serial: pl2303: fix GT type detection USB: serial: option: add Telit FD980 composition 0x1056 USB: serial: pl2303: fix HX type detection USB: serial: ch341: fix character loss at high transfer rates usb: cdnsp: Fix the IMAN_IE_SET and IMAN_IE_CLEAR macro usb: cdnsp: Fixed issue with ZLP usb: cdnsp: Fix incorrect supported maximum speed usb: cdns3: Fixed incorrect gadget state usb: gadget: f_hid: idle uses the highest byte for duration Revert "thunderbolt: Hide authorized attribute if router does not support PCIe tunnels" usb: otg-fsm: Fix hrtimer list corruption usb: host: ohci-at91: suspend/resume ports after/before OHCI accesses usb: musb: Fix suspend and resume issues for PHYs on I2C and SPI usb: gadget: f_hid: added GET_IDLE and SET_IDLE handlers usb: gadget: f_hid: fixed NULL pointer dereference usb: gadget: remove leaked entry from udc driver list ...
2 parents 85a9050 + 43ad944 commit 6a65554

File tree

19 files changed

+173
-75
lines changed

19 files changed

+173
-75
lines changed

drivers/thunderbolt/switch.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,18 +1875,6 @@ static struct attribute *switch_attrs[] = {
18751875
NULL,
18761876
};
18771877

1878-
static bool has_port(const struct tb_switch *sw, enum tb_port_type type)
1879-
{
1880-
const struct tb_port *port;
1881-
1882-
tb_switch_for_each_port(sw, port) {
1883-
if (!port->disabled && port->config.type == type)
1884-
return true;
1885-
}
1886-
1887-
return false;
1888-
}
1889-
18901878
static umode_t switch_attr_is_visible(struct kobject *kobj,
18911879
struct attribute *attr, int n)
18921880
{
@@ -1895,8 +1883,7 @@ static umode_t switch_attr_is_visible(struct kobject *kobj,
18951883

18961884
if (attr == &dev_attr_authorized.attr) {
18971885
if (sw->tb->security_level == TB_SECURITY_NOPCIE ||
1898-
sw->tb->security_level == TB_SECURITY_DPONLY ||
1899-
!has_port(sw, TB_TYPE_PCIE_UP))
1886+
sw->tb->security_level == TB_SECURITY_DPONLY)
19001887
return 0;
19011888
} else if (attr == &dev_attr_device.attr) {
19021889
if (!sw->device)

drivers/usb/cdns3/cdns3-ep0.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ static int cdns3_gadget_ep0_queue(struct usb_ep *ep,
731731
request->actual = 0;
732732
priv_dev->status_completion_no_call = true;
733733
priv_dev->pending_status_request = request;
734+
usb_gadget_set_state(&priv_dev->gadget, USB_STATE_CONFIGURED);
734735
spin_unlock_irqrestore(&priv_dev->lock, flags);
735736

736737
/*

drivers/usb/cdns3/cdnsp-gadget.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1882,7 +1882,7 @@ static int __cdnsp_gadget_init(struct cdns *cdns)
18821882
pdev->gadget.name = "cdnsp-gadget";
18831883
pdev->gadget.speed = USB_SPEED_UNKNOWN;
18841884
pdev->gadget.sg_supported = 1;
1885-
pdev->gadget.max_speed = USB_SPEED_SUPER_PLUS;
1885+
pdev->gadget.max_speed = max_speed;
18861886
pdev->gadget.lpm_capable = 1;
18871887

18881888
pdev->setup_buf = kzalloc(CDNSP_EP0_SETUP_SIZE, GFP_KERNEL);

drivers/usb/cdns3/cdnsp-gadget.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,8 +383,8 @@ struct cdnsp_intr_reg {
383383
#define IMAN_IE BIT(1)
384384
#define IMAN_IP BIT(0)
385385
/* bits 2:31 need to be preserved */
386-
#define IMAN_IE_SET(p) (((p) & IMAN_IE) | 0x2)
387-
#define IMAN_IE_CLEAR(p) (((p) & IMAN_IE) & ~(0x2))
386+
#define IMAN_IE_SET(p) ((p) | IMAN_IE)
387+
#define IMAN_IE_CLEAR(p) ((p) & ~IMAN_IE)
388388

389389
/* IMOD - Interrupter Moderation Register - irq_control bitmasks. */
390390
/*

drivers/usb/cdns3/cdnsp-ring.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,15 +1932,13 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
19321932
}
19331933

19341934
if (enqd_len + trb_buff_len >= full_len) {
1935-
if (need_zero_pkt && zero_len_trb) {
1936-
zero_len_trb = true;
1937-
} else {
1938-
field &= ~TRB_CHAIN;
1939-
field |= TRB_IOC;
1940-
more_trbs_coming = false;
1941-
need_zero_pkt = false;
1942-
preq->td.last_trb = ring->enqueue;
1943-
}
1935+
if (need_zero_pkt)
1936+
zero_len_trb = !zero_len_trb;
1937+
1938+
field &= ~TRB_CHAIN;
1939+
field |= TRB_IOC;
1940+
more_trbs_coming = false;
1941+
preq->td.last_trb = ring->enqueue;
19441942
}
19451943

19461944
/* Only set interrupt on short packet for OUT endpoints. */
@@ -1955,7 +1953,7 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
19551953
length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) |
19561954
TRB_INTR_TARGET(0);
19571955

1958-
cdnsp_queue_trb(pdev, ring, more_trbs_coming | need_zero_pkt,
1956+
cdnsp_queue_trb(pdev, ring, more_trbs_coming | zero_len_trb,
19591957
lower_32_bits(send_addr),
19601958
upper_32_bits(send_addr),
19611959
length_field,

drivers/usb/class/usbtmc.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2324,17 +2324,10 @@ static void usbtmc_interrupt(struct urb *urb)
23242324
dev_err(dev, "overflow with length %d, actual length is %d\n",
23252325
data->iin_wMaxPacketSize, urb->actual_length);
23262326
fallthrough;
2327-
case -ECONNRESET:
2328-
case -ENOENT:
2329-
case -ESHUTDOWN:
2330-
case -EILSEQ:
2331-
case -ETIME:
2332-
case -EPIPE:
2327+
default:
23332328
/* urb terminated, clean up */
23342329
dev_dbg(dev, "urb terminated, status: %d\n", status);
23352330
return;
2336-
default:
2337-
dev_err(dev, "unknown status received: %d\n", status);
23382331
}
23392332
exit:
23402333
rv = usb_submit_urb(urb, GFP_ATOMIC);

drivers/usb/common/usb-otg-fsm.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,11 @@ static void otg_start_hnp_polling(struct otg_fsm *fsm)
193193
if (!fsm->host_req_flag)
194194
return;
195195

196-
INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work);
196+
if (!fsm->hnp_work_inited) {
197+
INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work);
198+
fsm->hnp_work_inited = true;
199+
}
200+
197201
schedule_delayed_work(&fsm->hnp_polling_work,
198202
msecs_to_jiffies(T_HOST_REQ_POLL));
199203
}

drivers/usb/dwc3/gadget.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,9 +1741,13 @@ static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep)
17411741
{
17421742
struct dwc3_request *req;
17431743
struct dwc3_request *tmp;
1744+
struct list_head local;
17441745
struct dwc3 *dwc = dep->dwc;
17451746

1746-
list_for_each_entry_safe(req, tmp, &dep->cancelled_list, list) {
1747+
restart:
1748+
list_replace_init(&dep->cancelled_list, &local);
1749+
1750+
list_for_each_entry_safe(req, tmp, &local, list) {
17471751
dwc3_gadget_ep_skip_trbs(dep, req);
17481752
switch (req->status) {
17491753
case DWC3_REQUEST_STATUS_DISCONNECTED:
@@ -1761,6 +1765,9 @@ static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep)
17611765
break;
17621766
}
17631767
}
1768+
1769+
if (!list_empty(&dep->cancelled_list))
1770+
goto restart;
17641771
}
17651772

17661773
static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
@@ -2249,6 +2256,17 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
22492256
}
22502257
}
22512258

2259+
/*
2260+
* Avoid issuing a runtime resume if the device is already in the
2261+
* suspended state during gadget disconnect. DWC3 gadget was already
2262+
* halted/stopped during runtime suspend.
2263+
*/
2264+
if (!is_on) {
2265+
pm_runtime_barrier(dwc->dev);
2266+
if (pm_runtime_suspended(dwc->dev))
2267+
return 0;
2268+
}
2269+
22522270
/*
22532271
* Check the return value for successful resume, or error. For a
22542272
* successful resume, the DWC3 runtime PM resume routine will handle
@@ -2958,15 +2976,22 @@ static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep,
29582976
{
29592977
struct dwc3_request *req;
29602978
struct dwc3_request *tmp;
2979+
struct list_head local;
29612980

2962-
list_for_each_entry_safe(req, tmp, &dep->started_list, list) {
2981+
restart:
2982+
list_replace_init(&dep->started_list, &local);
2983+
2984+
list_for_each_entry_safe(req, tmp, &local, list) {
29632985
int ret;
29642986

29652987
ret = dwc3_gadget_ep_cleanup_completed_request(dep, event,
29662988
req, status);
29672989
if (ret)
29682990
break;
29692991
}
2992+
2993+
if (!list_empty(&dep->started_list))
2994+
goto restart;
29702995
}
29712996

29722997
static bool dwc3_gadget_ep_should_continue(struct dwc3_ep *dep)

drivers/usb/gadget/function/f_hid.c

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ struct f_hidg {
4141
unsigned char bInterfaceSubClass;
4242
unsigned char bInterfaceProtocol;
4343
unsigned char protocol;
44+
unsigned char idle;
4445
unsigned short report_desc_length;
4546
char *report_desc;
4647
unsigned short report_length;
@@ -338,6 +339,11 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
338339

339340
spin_lock_irqsave(&hidg->write_spinlock, flags);
340341

342+
if (!hidg->req) {
343+
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
344+
return -ESHUTDOWN;
345+
}
346+
341347
#define WRITE_COND (!hidg->write_pending)
342348
try_again:
343349
/* write queue */
@@ -358,8 +364,14 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
358364
count = min_t(unsigned, count, hidg->report_length);
359365

360366
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
361-
status = copy_from_user(req->buf, buffer, count);
362367

368+
if (!req) {
369+
ERROR(hidg->func.config->cdev, "hidg->req is NULL\n");
370+
status = -ESHUTDOWN;
371+
goto release_write_pending;
372+
}
373+
374+
status = copy_from_user(req->buf, buffer, count);
363375
if (status != 0) {
364376
ERROR(hidg->func.config->cdev,
365377
"copy_from_user error\n");
@@ -387,14 +399,17 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
387399

388400
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
389401

402+
if (!hidg->in_ep->enabled) {
403+
ERROR(hidg->func.config->cdev, "in_ep is disabled\n");
404+
status = -ESHUTDOWN;
405+
goto release_write_pending;
406+
}
407+
390408
status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC);
391-
if (status < 0) {
392-
ERROR(hidg->func.config->cdev,
393-
"usb_ep_queue error on int endpoint %zd\n", status);
409+
if (status < 0)
394410
goto release_write_pending;
395-
} else {
411+
else
396412
status = count;
397-
}
398413

399414
return status;
400415
release_write_pending:
@@ -523,6 +538,14 @@ static int hidg_setup(struct usb_function *f,
523538
goto respond;
524539
break;
525540

541+
case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
542+
| HID_REQ_GET_IDLE):
543+
VDBG(cdev, "get_idle\n");
544+
length = min_t(unsigned int, length, 1);
545+
((u8 *) req->buf)[0] = hidg->idle;
546+
goto respond;
547+
break;
548+
526549
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
527550
| HID_REQ_SET_REPORT):
528551
VDBG(cdev, "set_report | wLength=%d\n", ctrl->wLength);
@@ -546,6 +569,14 @@ static int hidg_setup(struct usb_function *f,
546569
goto stall;
547570
break;
548571

572+
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
573+
| HID_REQ_SET_IDLE):
574+
VDBG(cdev, "set_idle\n");
575+
length = 0;
576+
hidg->idle = value >> 8;
577+
goto respond;
578+
break;
579+
549580
case ((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8
550581
| USB_REQ_GET_DESCRIPTOR):
551582
switch (value >> 8) {
@@ -773,6 +804,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
773804
hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
774805
hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
775806
hidg->protocol = HID_REPORT_PROTOCOL;
807+
hidg->idle = 1;
776808
hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
777809
hidg_ss_in_comp_desc.wBytesPerInterval =
778810
cpu_to_le16(hidg->report_length);

drivers/usb/gadget/udc/max3420_udc.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,12 +1255,14 @@ static int max3420_probe(struct spi_device *spi)
12551255
err = devm_request_irq(&spi->dev, irq, max3420_irq_handler, 0,
12561256
"max3420", udc);
12571257
if (err < 0)
1258-
return err;
1258+
goto del_gadget;
12591259

12601260
udc->thread_task = kthread_create(max3420_thread, udc,
12611261
"max3420-thread");
1262-
if (IS_ERR(udc->thread_task))
1263-
return PTR_ERR(udc->thread_task);
1262+
if (IS_ERR(udc->thread_task)) {
1263+
err = PTR_ERR(udc->thread_task);
1264+
goto del_gadget;
1265+
}
12641266

12651267
irq = of_irq_get_byname(spi->dev.of_node, "vbus");
12661268
if (irq <= 0) { /* no vbus irq implies self-powered design */
@@ -1280,10 +1282,14 @@ static int max3420_probe(struct spi_device *spi)
12801282
err = devm_request_irq(&spi->dev, irq,
12811283
max3420_vbus_handler, 0, "vbus", udc);
12821284
if (err < 0)
1283-
return err;
1285+
goto del_gadget;
12841286
}
12851287

12861288
return 0;
1289+
1290+
del_gadget:
1291+
usb_del_gadget_udc(&udc->gadget);
1292+
return err;
12871293
}
12881294

12891295
static int max3420_remove(struct spi_device *spi)

0 commit comments

Comments
 (0)