Commit e9a61afb authored by Linus Torvalds's avatar Linus Torvalds

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

Pull USB fixes from Greg KH:
 "Here are a number of USB driver fixes for 5.7-rc3.

  Nothing huge, just the usual collection of:

   - xhci fixes

   - gadget driver fixes

   - syzkaller fuzzing fixes

   - new device ids and DT bindings

   - new quirks added for broken devices

  A few of the gadget driver fixes show up twice here as they were
  applied to my branch, and also by Felipe to his branch which I then
  pulled in as we got out of sync a bit.

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

* tag 'usb-5.7-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (33 commits)
  USB: sisusbvga: Change port variable from signed to unsigned
  usb-storage: Add unusual_devs entry for JMicron JMS566
  USB: hub: Revert commit bd0e6c96 ("usb: hub: try old enumeration scheme first for high speed devices")
  USB: hub: Fix handling of connect changes during sleep
  usb: typec: altmode: Fix typec_altmode_get_partner sometimes returning an invalid pointer
  xhci: Don't clear hub TT buffer on ep0 protocol stall
  xhci: prevent bus suspend if a roothub port detected a over-current condition
  xhci: Fix handling halted endpoint even if endpoint ring appears empty
  usb: raw-gadget: Fix copy_to/from_user() checks
  usb: raw-gadget: fix raw_event_queue_fetch locking
  usb: gadget: udc: atmel: Fix vbus disconnect handling
  usb: dwc3: gadget: Fix request completion check
  USB: Add USB_QUIRK_DELAY_CTRL_MSG and USB_QUIRK_DELAY_INIT for Corsair K70 RGB RAPIDFIRE
  phy: tegra: Select USB_COMMON for usb_get_maximum_speed()
  usb: typec: tcpm: Ignore CC and vbus changes in PORT_RESET change
  usb: f_fs: Clear OS Extended descriptor counts to zero in ffs_data_reset()
  cdc-acm: introduce a cool down
  cdc-acm: close race betrween suspend() and acm_softint
  UAS: fix deadlock in error handling and PM flushing work
  UAS: no use logging any details in case of ENODEV
  ...
parents c5f33785 2df7405f
...@@ -5187,8 +5187,7 @@ ...@@ -5187,8 +5187,7 @@
usbcore.old_scheme_first= usbcore.old_scheme_first=
[USB] Start with the old device initialization [USB] Start with the old device initialization
scheme, applies only to low and full-speed devices scheme (default 0 = off).
(default 0 = off).
usbcore.usbfs_memory_mb= usbcore.usbfs_memory_mb=
[USB] Memory limit (in MB) for buffers allocated by [USB] Memory limit (in MB) for buffers allocated by
......
...@@ -18,6 +18,7 @@ properties: ...@@ -18,6 +18,7 @@ properties:
- renesas,r8a774c0-usb3-peri # RZ/G2E - renesas,r8a774c0-usb3-peri # RZ/G2E
- renesas,r8a7795-usb3-peri # R-Car H3 - renesas,r8a7795-usb3-peri # R-Car H3
- renesas,r8a7796-usb3-peri # R-Car M3-W - renesas,r8a7796-usb3-peri # R-Car M3-W
- renesas,r8a77961-usb3-peri # R-Car M3-W+
- renesas,r8a77965-usb3-peri # R-Car M3-N - renesas,r8a77965-usb3-peri # R-Car M3-N
- renesas,r8a77990-usb3-peri # R-Car E3 - renesas,r8a77990-usb3-peri # R-Car E3
- const: renesas,rcar-gen3-usb3-peri - const: renesas,rcar-gen3-usb3-peri
......
...@@ -40,6 +40,7 @@ properties: ...@@ -40,6 +40,7 @@ properties:
- renesas,usbhs-r8a774c0 # RZ/G2E - renesas,usbhs-r8a774c0 # RZ/G2E
- renesas,usbhs-r8a7795 # R-Car H3 - renesas,usbhs-r8a7795 # R-Car H3
- renesas,usbhs-r8a7796 # R-Car M3-W - renesas,usbhs-r8a7796 # R-Car M3-W
- renesas,usbhs-r8a77961 # R-Car M3-W+
- renesas,usbhs-r8a77965 # R-Car M3-N - renesas,usbhs-r8a77965 # R-Car M3-N
- renesas,usbhs-r8a77990 # R-Car E3 - renesas,usbhs-r8a77990 # R-Car E3
- renesas,usbhs-r8a77995 # R-Car D3 - renesas,usbhs-r8a77995 # R-Car D3
......
...@@ -16,7 +16,8 @@ Required properties: ...@@ -16,7 +16,8 @@ Required properties:
- "renesas,xhci-r8a7791" for r8a7791 SoC - "renesas,xhci-r8a7791" for r8a7791 SoC
- "renesas,xhci-r8a7793" for r8a7793 SoC - "renesas,xhci-r8a7793" for r8a7793 SoC
- "renesas,xhci-r8a7795" for r8a7795 SoC - "renesas,xhci-r8a7795" for r8a7795 SoC
- "renesas,xhci-r8a7796" for r8a7796 SoC - "renesas,xhci-r8a7796" for r8a77960 SoC
- "renesas,xhci-r8a77961" for r8a77961 SoC
- "renesas,xhci-r8a77965" for r8a77965 SoC - "renesas,xhci-r8a77965" for r8a77965 SoC
- "renesas,xhci-r8a77990" for r8a77990 SoC - "renesas,xhci-r8a77990" for r8a77990 SoC
- "renesas,rcar-gen2-xhci" for a generic R-Car Gen2 or RZ/G1 compatible - "renesas,rcar-gen2-xhci" for a generic R-Car Gen2 or RZ/G1 compatible
......
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
config PHY_TEGRA_XUSB config PHY_TEGRA_XUSB
tristate "NVIDIA Tegra XUSB pad controller driver" tristate "NVIDIA Tegra XUSB pad controller driver"
depends on ARCH_TEGRA depends on ARCH_TEGRA && USB_SUPPORT
select USB_COMMON
select USB_CONN_GPIO select USB_CONN_GPIO
select USB_PHY select USB_PHY
help help
......
...@@ -412,9 +412,12 @@ static void acm_ctrl_irq(struct urb *urb) ...@@ -412,9 +412,12 @@ static void acm_ctrl_irq(struct urb *urb)
exit: exit:
retval = usb_submit_urb(urb, GFP_ATOMIC); retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval && retval != -EPERM) if (retval && retval != -EPERM && retval != -ENODEV)
dev_err(&acm->control->dev, dev_err(&acm->control->dev,
"%s - usb_submit_urb failed: %d\n", __func__, retval); "%s - usb_submit_urb failed: %d\n", __func__, retval);
else
dev_vdbg(&acm->control->dev,
"control resubmission terminated %d\n", retval);
} }
static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags) static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags)
...@@ -430,6 +433,8 @@ static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags) ...@@ -430,6 +433,8 @@ static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags)
dev_err(&acm->data->dev, dev_err(&acm->data->dev,
"urb %d failed submission with %d\n", "urb %d failed submission with %d\n",
index, res); index, res);
} else {
dev_vdbg(&acm->data->dev, "intended failure %d\n", res);
} }
set_bit(index, &acm->read_urbs_free); set_bit(index, &acm->read_urbs_free);
return res; return res;
...@@ -471,6 +476,7 @@ static void acm_read_bulk_callback(struct urb *urb) ...@@ -471,6 +476,7 @@ static void acm_read_bulk_callback(struct urb *urb)
int status = urb->status; int status = urb->status;
bool stopped = false; bool stopped = false;
bool stalled = false; bool stalled = false;
bool cooldown = false;
dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n", dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n",
rb->index, urb->actual_length, status); rb->index, urb->actual_length, status);
...@@ -497,6 +503,14 @@ static void acm_read_bulk_callback(struct urb *urb) ...@@ -497,6 +503,14 @@ static void acm_read_bulk_callback(struct urb *urb)
__func__, status); __func__, status);
stopped = true; stopped = true;
break; break;
case -EOVERFLOW:
case -EPROTO:
dev_dbg(&acm->data->dev,
"%s - cooling babbling device\n", __func__);
usb_mark_last_busy(acm->dev);
set_bit(rb->index, &acm->urbs_in_error_delay);
cooldown = true;
break;
default: default:
dev_dbg(&acm->data->dev, dev_dbg(&acm->data->dev,
"%s - nonzero urb status received: %d\n", "%s - nonzero urb status received: %d\n",
...@@ -518,9 +532,11 @@ static void acm_read_bulk_callback(struct urb *urb) ...@@ -518,9 +532,11 @@ static void acm_read_bulk_callback(struct urb *urb)
*/ */
smp_mb__after_atomic(); smp_mb__after_atomic();
if (stopped || stalled) { if (stopped || stalled || cooldown) {
if (stalled) if (stalled)
schedule_work(&acm->work); schedule_work(&acm->work);
else if (cooldown)
schedule_delayed_work(&acm->dwork, HZ / 2);
return; return;
} }
...@@ -557,14 +573,20 @@ static void acm_softint(struct work_struct *work) ...@@ -557,14 +573,20 @@ static void acm_softint(struct work_struct *work)
struct acm *acm = container_of(work, struct acm, work); struct acm *acm = container_of(work, struct acm, work);
if (test_bit(EVENT_RX_STALL, &acm->flags)) { if (test_bit(EVENT_RX_STALL, &acm->flags)) {
if (!(usb_autopm_get_interface(acm->data))) { smp_mb(); /* against acm_suspend() */
if (!acm->susp_count) {
for (i = 0; i < acm->rx_buflimit; i++) for (i = 0; i < acm->rx_buflimit; i++)
usb_kill_urb(acm->read_urbs[i]); usb_kill_urb(acm->read_urbs[i]);
usb_clear_halt(acm->dev, acm->in); usb_clear_halt(acm->dev, acm->in);
acm_submit_read_urbs(acm, GFP_KERNEL); acm_submit_read_urbs(acm, GFP_KERNEL);
usb_autopm_put_interface(acm->data); clear_bit(EVENT_RX_STALL, &acm->flags);
} }
clear_bit(EVENT_RX_STALL, &acm->flags); }
if (test_and_clear_bit(ACM_ERROR_DELAY, &acm->flags)) {
for (i = 0; i < ACM_NR; i++)
if (test_and_clear_bit(i, &acm->urbs_in_error_delay))
acm_submit_read_urb(acm, i, GFP_NOIO);
} }
if (test_and_clear_bit(EVENT_TTY_WAKEUP, &acm->flags)) if (test_and_clear_bit(EVENT_TTY_WAKEUP, &acm->flags))
...@@ -1333,6 +1355,7 @@ static int acm_probe(struct usb_interface *intf, ...@@ -1333,6 +1355,7 @@ static int acm_probe(struct usb_interface *intf,
acm->readsize = readsize; acm->readsize = readsize;
acm->rx_buflimit = num_rx_buf; acm->rx_buflimit = num_rx_buf;
INIT_WORK(&acm->work, acm_softint); INIT_WORK(&acm->work, acm_softint);
INIT_DELAYED_WORK(&acm->dwork, acm_softint);
init_waitqueue_head(&acm->wioctl); init_waitqueue_head(&acm->wioctl);
spin_lock_init(&acm->write_lock); spin_lock_init(&acm->write_lock);
spin_lock_init(&acm->read_lock); spin_lock_init(&acm->read_lock);
...@@ -1542,6 +1565,7 @@ static void acm_disconnect(struct usb_interface *intf) ...@@ -1542,6 +1565,7 @@ static void acm_disconnect(struct usb_interface *intf)
acm_kill_urbs(acm); acm_kill_urbs(acm);
cancel_work_sync(&acm->work); cancel_work_sync(&acm->work);
cancel_delayed_work_sync(&acm->dwork);
tty_unregister_device(acm_tty_driver, acm->minor); tty_unregister_device(acm_tty_driver, acm->minor);
...@@ -1584,6 +1608,8 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) ...@@ -1584,6 +1608,8 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
acm_kill_urbs(acm); acm_kill_urbs(acm);
cancel_work_sync(&acm->work); cancel_work_sync(&acm->work);
cancel_delayed_work_sync(&acm->dwork);
acm->urbs_in_error_delay = 0;
return 0; return 0;
} }
......
...@@ -109,8 +109,11 @@ struct acm { ...@@ -109,8 +109,11 @@ struct acm {
# define EVENT_TTY_WAKEUP 0 # define EVENT_TTY_WAKEUP 0
# define EVENT_RX_STALL 1 # define EVENT_RX_STALL 1
# define ACM_THROTTLED 2 # define ACM_THROTTLED 2
# define ACM_ERROR_DELAY 3
unsigned long urbs_in_error_delay; /* these need to be restarted after a delay */
struct usb_cdc_line_coding line; /* bits, stop, parity */ struct usb_cdc_line_coding line; /* bits, stop, parity */
struct work_struct work; /* work queue entry for line discipline waking up */ struct work_struct work; /* work queue entry for various purposes*/
struct delayed_work dwork; /* for cool downs needed in error recovery */
unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */
unsigned int ctrlout; /* output control lines (DTR, RTS) */ unsigned int ctrlout; /* output control lines (DTR, RTS) */
struct async_icount iocount; /* counters for control line changes */ struct async_icount iocount; /* counters for control line changes */
......
...@@ -1223,6 +1223,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) ...@@ -1223,6 +1223,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
#ifdef CONFIG_PM #ifdef CONFIG_PM
udev->reset_resume = 1; udev->reset_resume = 1;
#endif #endif
/* Don't set the change_bits when the device
* was powered off.
*/
if (test_bit(port1, hub->power_bits))
set_bit(port1, hub->change_bits);
} else { } else {
/* The power session is gone; tell hub_wq */ /* The power session is gone; tell hub_wq */
...@@ -2723,13 +2728,11 @@ static bool use_new_scheme(struct usb_device *udev, int retry, ...@@ -2723,13 +2728,11 @@ static bool use_new_scheme(struct usb_device *udev, int retry,
{ {
int old_scheme_first_port = int old_scheme_first_port =
port_dev->quirks & USB_PORT_QUIRK_OLD_SCHEME; port_dev->quirks & USB_PORT_QUIRK_OLD_SCHEME;
int quick_enumeration = (udev->speed == USB_SPEED_HIGH);
if (udev->speed >= USB_SPEED_SUPER) if (udev->speed >= USB_SPEED_SUPER)
return false; return false;
return USE_NEW_SCHEME(retry, old_scheme_first_port || old_scheme_first return USE_NEW_SCHEME(retry, old_scheme_first_port || old_scheme_first);
|| quick_enumeration);
} }
/* Is a USB 3.0 port in the Inactive or Compliance Mode state? /* Is a USB 3.0 port in the Inactive or Compliance Mode state?
...@@ -3088,6 +3091,15 @@ static int check_port_resume_type(struct usb_device *udev, ...@@ -3088,6 +3091,15 @@ static int check_port_resume_type(struct usb_device *udev,
if (portchange & USB_PORT_STAT_C_ENABLE) if (portchange & USB_PORT_STAT_C_ENABLE)
usb_clear_port_feature(hub->hdev, port1, usb_clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_ENABLE); USB_PORT_FEAT_C_ENABLE);
/*
* Whatever made this reset-resume necessary may have
* turned on the port1 bit in hub->change_bits. But after
* a successful reset-resume we want the bit to be clear;
* if it was on it would indicate that something happened
* following the reset-resume.
*/
clear_bit(port1, hub->change_bits);
} }
return status; return status;
......
...@@ -589,12 +589,13 @@ void usb_sg_cancel(struct usb_sg_request *io) ...@@ -589,12 +589,13 @@ void usb_sg_cancel(struct usb_sg_request *io)
int i, retval; int i, retval;
spin_lock_irqsave(&io->lock, flags); spin_lock_irqsave(&io->lock, flags);
if (io->status) { if (io->status || io->count == 0) {
spin_unlock_irqrestore(&io->lock, flags); spin_unlock_irqrestore(&io->lock, flags);
return; return;
} }
/* shut everything down */ /* shut everything down */
io->status = -ECONNRESET; io->status = -ECONNRESET;
io->count++; /* Keep the request alive until we're done */
spin_unlock_irqrestore(&io->lock, flags); spin_unlock_irqrestore(&io->lock, flags);
for (i = io->entries - 1; i >= 0; --i) { for (i = io->entries - 1; i >= 0; --i) {
...@@ -608,6 +609,12 @@ void usb_sg_cancel(struct usb_sg_request *io) ...@@ -608,6 +609,12 @@ void usb_sg_cancel(struct usb_sg_request *io)
dev_warn(&io->dev->dev, "%s, unlink --> %d\n", dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
__func__, retval); __func__, retval);
} }
spin_lock_irqsave(&io->lock, flags);
io->count--;
if (!io->count)
complete(&io->complete);
spin_unlock_irqrestore(&io->lock, flags);
} }
EXPORT_SYMBOL_GPL(usb_sg_cancel); EXPORT_SYMBOL_GPL(usb_sg_cancel);
......
...@@ -430,6 +430,10 @@ static const struct usb_device_id usb_quirk_list[] = { ...@@ -430,6 +430,10 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Corsair K70 LUX */ /* Corsair K70 LUX */
{ USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT }, { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT },
/* Corsair K70 RGB RAPDIFIRE */
{ USB_DEVICE(0x1b1c, 0x1b38), .driver_info = USB_QUIRK_DELAY_INIT |
USB_QUIRK_DELAY_CTRL_MSG },
/* MIDI keyboard WORLDE MINI */ /* MIDI keyboard WORLDE MINI */
{ USB_DEVICE(0x1c75, 0x0204), .driver_info = { USB_DEVICE(0x1c75, 0x0204), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS }, USB_QUIRK_CONFIG_INTF_STRINGS },
......
...@@ -307,10 +307,14 @@ ...@@ -307,10 +307,14 @@
/* Global TX Fifo Size Register */ /* Global TX Fifo Size Register */
#define DWC31_GTXFIFOSIZ_TXFRAMNUM BIT(15) /* DWC_usb31 only */ #define DWC31_GTXFIFOSIZ_TXFRAMNUM BIT(15) /* DWC_usb31 only */
#define DWC31_GTXFIFOSIZ_TXFDEF(n) ((n) & 0x7fff) /* DWC_usb31 only */ #define DWC31_GTXFIFOSIZ_TXFDEP(n) ((n) & 0x7fff) /* DWC_usb31 only */
#define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) #define DWC3_GTXFIFOSIZ_TXFDEP(n) ((n) & 0xffff)
#define DWC3_GTXFIFOSIZ_TXFSTADDR(n) ((n) & 0xffff0000) #define DWC3_GTXFIFOSIZ_TXFSTADDR(n) ((n) & 0xffff0000)
/* Global RX Fifo Size Register */
#define DWC31_GRXFIFOSIZ_RXFDEP(n) ((n) & 0x7fff) /* DWC_usb31 only */
#define DWC3_GRXFIFOSIZ_RXFDEP(n) ((n) & 0xffff)
/* Global Event Size Registers */ /* Global Event Size Registers */
#define DWC3_GEVNTSIZ_INTMASK BIT(31) #define DWC3_GEVNTSIZ_INTMASK BIT(31)
#define DWC3_GEVNTSIZ_SIZE(n) ((n) & 0xffff) #define DWC3_GEVNTSIZ_SIZE(n) ((n) & 0xffff)
......
...@@ -1728,7 +1728,6 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc) ...@@ -1728,7 +1728,6 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
u32 reg; u32 reg;
u8 link_state; u8 link_state;
u8 speed;
/* /*
* According to the Databook Remote wakeup request should * According to the Databook Remote wakeup request should
...@@ -1738,16 +1737,13 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc) ...@@ -1738,16 +1737,13 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
*/ */
reg = dwc3_readl(dwc->regs, DWC3_DSTS); reg = dwc3_readl(dwc->regs, DWC3_DSTS);
speed = reg & DWC3_DSTS_CONNECTSPD;
if ((speed == DWC3_DSTS_SUPERSPEED) ||
(speed == DWC3_DSTS_SUPERSPEED_PLUS))
return 0;
link_state = DWC3_DSTS_USBLNKST(reg); link_state = DWC3_DSTS_USBLNKST(reg);
switch (link_state) { switch (link_state) {
case DWC3_LINK_STATE_RESET:
case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */ case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */
case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */ case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */
case DWC3_LINK_STATE_RESUME:
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -2227,7 +2223,6 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) ...@@ -2227,7 +2223,6 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
{ {
struct dwc3 *dwc = dep->dwc; struct dwc3 *dwc = dep->dwc;
int mdwidth; int mdwidth;
int kbytes;
int size; int size;
mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
...@@ -2236,24 +2231,24 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) ...@@ -2236,24 +2231,24 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1)); size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1));
if (dwc3_is_usb31(dwc)) if (dwc3_is_usb31(dwc))
size = DWC31_GTXFIFOSIZ_TXFDEF(size); size = DWC31_GTXFIFOSIZ_TXFDEP(size);
else else
size = DWC3_GTXFIFOSIZ_TXFDEF(size); size = DWC3_GTXFIFOSIZ_TXFDEP(size);
/* FIFO Depth is in MDWDITH bytes. Multiply */ /* FIFO Depth is in MDWDITH bytes. Multiply */
size *= mdwidth; size *= mdwidth;
kbytes = size / 1024;
if (kbytes == 0)
kbytes = 1;
/* /*
* FIFO sizes account an extra MDWIDTH * (kbytes + 1) bytes for * To meet performance requirement, a minimum TxFIFO size of 3x
* internal overhead. We don't really know how these are used, * MaxPacketSize is recommended for endpoints that support burst and a
* but documentation say it exists. * minimum TxFIFO size of 2x MaxPacketSize for endpoints that don't
* support burst. Use those numbers and we can calculate the max packet
* limit as below.
*/ */
size -= mdwidth * (kbytes + 1); if (dwc->maximum_speed >= USB_SPEED_SUPER)
size /= kbytes; size /= 3;
else
size /= 2;
usb_ep_set_maxpacket_limit(&dep->endpoint, size); usb_ep_set_maxpacket_limit(&dep->endpoint, size);
...@@ -2271,8 +2266,39 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) ...@@ -2271,8 +2266,39 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep) static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep)
{ {
struct dwc3 *dwc = dep->dwc; struct dwc3 *dwc = dep->dwc;
int mdwidth;
int size;
mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
usb_ep_set_maxpacket_limit(&dep->endpoint, 1024); /* MDWIDTH is represented in bits, convert to bytes */
mdwidth /= 8;
/* All OUT endpoints share a single RxFIFO space */
size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0));
if (dwc3_is_usb31(dwc))
size = DWC31_GRXFIFOSIZ_RXFDEP(size);
else
size = DWC3_GRXFIFOSIZ_RXFDEP(size);
/* FIFO depth is in MDWDITH bytes */
size *= mdwidth;
/*
* To meet performance requirement, a minimum recommended RxFIFO size
* is defined as follow:
* RxFIFO size >= (3 x MaxPacketSize) +
* (3 x 8 bytes setup packets size) + (16 bytes clock crossing margin)
*
* Then calculate the max packet limit as below.
*/
size -= (3 * 8) + 16;
if (size < 0)
size = 0;
else
size /= 3;
usb_ep_set_maxpacket_limit(&dep->endpoint, size);
dep->endpoint.max_streams = 15; dep->endpoint.max_streams = 15;
dep->endpoint.ops = &dwc3_gadget_ep_ops; dep->endpoint.ops = &dwc3_gadget_ep_ops;
list_add_tail(&dep->endpoint.ep_list, list_add_tail(&dep->endpoint.ep_list,
...@@ -2484,14 +2510,7 @@ static int dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep, ...@@ -2484,14 +2510,7 @@ static int dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep,
static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req) static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req)
{ {
/* return req->num_pending_sgs == 0;
* For OUT direction, host may send less than the setup
* length. Return true for all OUT requests.
*/
if (!req->direction)
return true;
return req->request.actual == req->request.length;
} }
static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
...@@ -2515,8 +2534,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, ...@@ -2515,8 +2534,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
req->request.actual = req->request.length - req->remaining; req->request.actual = req->request.length - req->remaining;
if (!dwc3_gadget_ep_request_completed(req) || if (!dwc3_gadget_ep_request_completed(req)) {
req->num_pending_sgs) {
__dwc3_gadget_kick_transfer(dep); __dwc3_gadget_kick_transfer(dep);
goto out; goto out;
} }
......
...@@ -728,19 +728,19 @@ static void xdbc_handle_tx_event(struct xdbc_trb *evt_trb) ...@@ -728,19 +728,19 @@ static void xdbc_handle_tx_event(struct xdbc_trb *evt_trb)
case COMP_USB_TRANSACTION_ERROR: case COMP_USB_TRANSACTION_ERROR:
case COMP_STALL_ERROR: case COMP_STALL_ERROR:
default: default:
if (ep_id == XDBC_EPID_OUT) if (ep_id == XDBC_EPID_OUT || ep_id == XDBC_EPID_OUT_INTEL)
xdbc.flags |= XDBC_FLAGS_OUT_STALL; xdbc.flags |= XDBC_FLAGS_OUT_STALL;
if (ep_id == XDBC_EPID_IN) if (ep_id == XDBC_EPID_IN || ep_id == XDBC_EPID_IN_INTEL)
xdbc.flags |= XDBC_FLAGS_IN_STALL; xdbc.flags |= XDBC_FLAGS_IN_STALL;
xdbc_trace("endpoint %d stalled\n", ep_id); xdbc_trace("endpoint %d stalled\n", ep_id);
break; break;
} }
if (ep_id == XDBC_EPID_IN) { if (ep_id == XDBC_EPID_IN || ep_id == XDBC_EPID_IN_INTEL) {
xdbc.flags &= ~XDBC_FLAGS_IN_PROCESS; xdbc.flags &= ~XDBC_FLAGS_IN_PROCESS;
xdbc_bulk_transfer(NULL, XDBC_MAX_PACKET, true); xdbc_bulk_transfer(NULL, XDBC_MAX_PACKET, true);
} else if (ep_id == XDBC_EPID_OUT) { } else if (ep_id == XDBC_EPID_OUT || ep_id == XDBC_EPID_OUT_INTEL) {
xdbc.flags &= ~XDBC_FLAGS_OUT_PROCESS; xdbc.flags &= ~XDBC_FLAGS_OUT_PROCESS;
} else { } else {
xdbc_trace("invalid endpoint id %d\n", ep_id); xdbc_trace("invalid endpoint id %d\n", ep_id);
......
...@@ -120,8 +120,22 @@ struct xdbc_ring { ...@@ -120,8 +120,22 @@ struct xdbc_ring {
u32 cycle_state; u32 cycle_state;
}; };
#define XDBC_EPID_OUT 2 /*
#define XDBC_EPID_IN 3 * These are the "Endpoint ID" (also known as "Context Index") values for the
* OUT Transfer Ring and the IN Transfer Ring of a Debug Capability Context data
* structure.
* According to the "eXtensible Host Controller Interface for Universal Serial
* Bus (xHCI)" specification, section "7.6.3.2 Endpoint Contexts and Transfer
* Rings", these should be 0 and 1, and those are the values AMD machines give
* you; but Intel machines seem to use the formula from section "4.5.1 Device
* Context Index", which is supposed to be used for the Device Context only.
* Luckily the values from Intel don't overlap with those from AMD, so we can
* just test for both.
*/
#define XDBC_EPID_OUT 0
#define XDBC_EPID_IN 1
#define XDBC_EPID_OUT_INTEL 2
#define XDBC_EPID_IN_INTEL 3
struct xdbc_state { struct xdbc_state {
u16 vendor; u16 vendor;
......
...@@ -1813,6 +1813,10 @@ static void ffs_data_reset(struct ffs_data *ffs) ...@@ -1813,6 +1813,10 @@ static void ffs_data_reset(struct ffs_data *ffs)
ffs->state = FFS_READ_DESCRIPTORS; ffs->state = FFS_READ_DESCRIPTORS;
ffs->setup_state = FFS_NO_SETUP; ffs->setup_state = FFS_NO_SETUP;
ffs->flags = 0; ffs->flags = 0;
ffs->ms_os_descs_ext_prop_count = 0;
ffs->ms_os_descs_ext_prop_name_len = 0;
ffs->ms_os_descs_ext_prop_data_len = 0;
} }
......
...@@ -81,6 +81,7 @@ static int raw_event_queue_add(struct raw_event_queue *queue, ...@@ -81,6 +81,7 @@ static int raw_event_queue_add(struct raw_event_queue *queue,
static struct usb_raw_event *raw_event_queue_fetch( static struct usb_raw_event *raw_event_queue_fetch(
struct raw_event_queue *queue) struct raw_event_queue *queue)
{ {
int ret;
unsigned long flags; unsigned long flags;
struct usb_raw_event *event; struct usb_raw_event *event;
...@@ -89,11 +90,18 @@ static struct usb_raw_event *raw_event_queue_fetch( ...@@ -89,11 +90,18 @@ static struct usb_raw_event *raw_event_queue_fetch(
* there's at least one event queued by decrementing the semaphore, * there's at least one event queued by decrementing the semaphore,
* and then take the lock to protect queue struct fields. * and then take the lock to protect queue struct fields.
*/ */
if (down_interruptible(&queue->sema)) ret = down_interruptible(&queue->sema);
return NULL; if (ret)
return ERR_PTR(ret);
spin_lock_irqsave(&queue->lock, flags); spin_lock_irqsave(&queue->lock, flags);
if (WARN_ON(!queue->size)) /*
return NULL; * queue->size must have the same value as queue->sema counter (before
* the down_interruptible() call above), so this check is a fail-safe.
*/
if (WARN_ON(!queue->size)) {
spin_unlock_irqrestore(&queue->lock, flags);
return ERR_PTR(-ENODEV);
}
event = queue->events[0]; event = queue->events[0];
queue->size--; queue->size--;
memmove(&queue->events[0], &queue->events[1], memmove(&queue->events[0], &queue->events[1],
...@@ -392,9 +400,8 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value) ...@@ -392,9 +400,8 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)
char *udc_device_name; char *udc_device_name;
unsigned long flags; unsigned long flags;
ret = copy_from_user(&arg, (void __user *)value, sizeof(arg)); if (copy_from_user(&arg, (void __user *)value, sizeof(arg)))
if (ret) return -EFAULT;
return ret;
switch (arg.speed) { switch (arg.speed) {
case USB_SPEED_UNKNOWN: case USB_SPEED_UNKNOWN:
...@@ -501,15 +508,13 @@ static int raw_ioctl_run(struct raw_dev *dev, unsigned long value) ...@@ -501,15 +508,13 @@ static int raw_ioctl_run(struct raw_dev *dev, unsigned long value)
static int raw_ioctl_event_fetch(struct raw_dev *dev, unsigned long value) static int raw_ioctl_event_fetch(struct raw_dev *dev, unsigned long value)
{ {
int ret = 0;
struct usb_raw_event arg; struct usb_raw_event arg;
unsigned long flags; unsigned long flags;
struct usb_raw_event *event; struct usb_raw_event *event;
uint32_t length; uint32_t length;
ret = copy_from_user(&arg, (void __user *)value, sizeof(arg)); if (copy_from_user(&arg, (void __user *)value, sizeof(arg)))
if (ret) return -EFAULT;
return ret;
spin_lock_irqsave(&dev->lock, flags); spin_lock_irqsave(&dev->lock, flags);
if (dev->state != STATE_DEV_RUNNING) { if (dev->state != STATE_DEV_RUNNING) {
...@@ -525,25 +530,31 @@ static int raw_ioctl_event_fetch(struct raw_dev *dev, unsigned long value) ...@@ -525,25 +530,31 @@ static int raw_ioctl_event_fetch(struct raw_dev *dev, unsigned long value)
spin_unlock_irqrestore(&dev->lock, flags); spin_unlock_irqrestore(&dev->lock, flags);
event = raw_event_queue_fetch(&dev->queue); event = raw_event_queue_fetch(&dev->queue);
if (!event) { if (PTR_ERR(event) == -EINTR) {
dev_dbg(&dev->gadget->dev, "event fetching interrupted\n"); dev_dbg(&dev->gadget->dev, "event fetching interrupted\n");
return -EINTR; return -EINTR;
} }
if (IS_ERR(event)) {
dev_err(&dev->gadget->dev, "failed to fetch event\n");
spin_lock_irqsave(&dev->lock, flags);
dev->state = STATE_DEV_FAILED;
spin_unlock_irqrestore(&dev->lock, flags);
return -ENODEV;
}
length = min(arg.length, event->length); length = min(arg.length, event->length);
ret = copy_to_user((void __user *)value, event, if (copy_to_user((void __user *)value, event, sizeof(*event) + length))
sizeof(*event) + length); return -EFAULT;
return ret;
return 0;
} }
static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr,
bool get_from_user) bool get_from_user)
{ {
int ret;
void *data; void *data;
ret = copy_from_user(io, ptr, sizeof(*io)); if (copy_from_user(io, ptr, sizeof(*io)))
if (ret) return ERR_PTR(-EFAULT);
return ERR_PTR(ret);
if (io->ep >= USB_RAW_MAX_ENDPOINTS) if (io->ep >= USB_RAW_MAX_ENDPOINTS)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
if (!usb_raw_io_flags_valid(io->flags)) if (!usb_raw_io_flags_valid(io->flags))
...@@ -658,12 +669,13 @@ static int raw_ioctl_ep0_read(struct raw_dev *dev, unsigned long value) ...@@ -658,12 +669,13 @@ static int raw_ioctl_ep0_read(struct raw_dev *dev, unsigned long value)
if (IS_ERR(data)) if (IS_ERR(data))
return PTR_ERR(data); return PTR_ERR(data);
ret = raw_process_ep0_io(dev, &io, data, false); ret = raw_process_ep0_io(dev, &io, data, false);
if (ret < 0) { if (ret)
kfree(data); goto free;
return ret;
}
length = min(io.length, (unsigned int)ret); length = min(io.length, (unsigned int)ret);
ret = copy_to_user((void __user *)(value + sizeof(io)), data, length); if (copy_to_user((void __user *)(value + sizeof(io)), data, length))
ret = -EFAULT;
free:
kfree(data); kfree(data);
return ret; return ret;
} }
...@@ -952,12 +964,13 @@ static int raw_ioctl_ep_read(struct raw_dev *dev, unsigned long value) ...@@ -952,12 +964,13 @@ static int raw_ioctl_ep_read(struct raw_dev *dev, unsigned long value)
if (IS_ERR(data)) if (IS_ERR(data))
return PTR_ERR(data); return PTR_ERR(data);
ret = raw_process_ep_io(dev, &io, data, false); ret = raw_process_ep_io(dev, &io, data, false);
if (ret < 0) { if (ret)
kfree(data); goto free;
return ret;
}
length = min(io.length, (unsigned int)ret); length = min(io.length, (unsigned int)ret);
ret = copy_to_user((void __user *)(value + sizeof(io)), data, length); if (copy_to_user((void __user *)(value + sizeof(io)), data, length))
ret = -EFAULT;
free:
kfree(data); kfree(data);
return ret; return ret;
} }
......
...@@ -1951,10 +1951,10 @@ static irqreturn_t usba_vbus_irq_thread(int irq, void *devid) ...@@ -1951,10 +1951,10 @@ static irqreturn_t usba_vbus_irq_thread(int irq, void *devid)
usba_start(udc); usba_start(udc);
} else { } else {
udc->suspended = false; udc->suspended = false;
usba_stop(udc);
if (udc->driver->disconnect) if (udc->driver->disconnect)
udc->driver->disconnect(&udc->gadget); udc->driver->disconnect(&udc->gadget);
usba_stop(udc);
} }
udc->vbus_prev = vbus; udc->vbus_prev = vbus;
} }
......
...@@ -540,7 +540,7 @@ static void bdc_req_complete(struct bdc_ep *ep, struct bdc_req *req, ...@@ -540,7 +540,7 @@ static void bdc_req_complete(struct bdc_ep *ep, struct bdc_req *req,
{ {
struct bdc *bdc = ep->bdc; struct bdc *bdc = ep->bdc;
if (req == NULL || &req->queue == NULL || &req->usb_req == NULL) if (req == NULL)
return; return;
dev_dbg(bdc->dev, "%s ep:%s status:%d\n", __func__, ep->name, status); dev_dbg(bdc->dev, "%s ep:%s status:%d\n", __func__, ep->name, status);
......
...@@ -1571,6 +1571,8 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) ...@@ -1571,6 +1571,8 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
} }
if ((temp & PORT_RC)) if ((temp & PORT_RC))
reset_change = true; reset_change = true;
if (temp & PORT_OC)
status = 1;
} }
if (!status && !reset_change) { if (!status && !reset_change) {
xhci_dbg(xhci, "%s: stopping port polling.\n", __func__); xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
...@@ -1636,6 +1638,13 @@ int xhci_bus_suspend(struct usb_hcd *hcd) ...@@ -1636,6 +1638,13 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
port_index); port_index);
goto retry; goto retry;
} }
/* bail out if port detected a over-current condition */
if (t1 & PORT_OC) {
bus_state->bus_suspended = 0;
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_dbg(xhci, "Bus suspend bailout, port over-current detected\n");
return -EBUSY;
}
/* suspend ports in U0, or bail out for new connect changes */ /* suspend ports in U0, or bail out for new connect changes */
if ((t1 & PORT_PE) && (t1 & PORT_PLS_MASK) == XDEV_U0) { if ((t1 & PORT_PE) && (t1 & PORT_PLS_MASK) == XDEV_U0) {
if ((t1 & PORT_CSC) && wake_enabled) { if ((t1 & PORT_CSC) && wake_enabled) {
......
...@@ -547,6 +547,23 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, ...@@ -547,6 +547,23 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
stream_id); stream_id);
return; return;
} }
/*
* A cancelled TD can complete with a stall if HW cached the trb.
* In this case driver can't find cur_td, but if the ring is empty we
* can move the dequeue pointer to the current enqueue position.
*/
if (!cur_td) {
if (list_empty(&ep_ring->td_list)) {
state->new_deq_seg = ep_ring->enq_seg;
state->new_deq_ptr = ep_ring->enqueue;
state->new_cycle_state = ep_ring->cycle_state;
goto done;
} else {
xhci_warn(xhci, "Can't find new dequeue state, missing cur_td\n");
return;
}
}
/* Dig out the cycle state saved by the xHC during the stop ep cmd */ /* Dig out the cycle state saved by the xHC during the stop ep cmd */
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"Finding endpoint context"); "Finding endpoint context");
...@@ -592,6 +609,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, ...@@ -592,6 +609,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
state->new_deq_seg = new_seg; state->new_deq_seg = new_seg;
state->new_deq_ptr = new_deq; state->new_deq_ptr = new_deq;
done:
/* Don't update the ring cycle state for the producer (us). */ /* Don't update the ring cycle state for the producer (us). */
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"Cycle state = 0x%x", state->new_cycle_state); "Cycle state = 0x%x", state->new_cycle_state);
...@@ -1856,8 +1874,8 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, ...@@ -1856,8 +1874,8 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
if (reset_type == EP_HARD_RESET) { if (reset_type == EP_HARD_RESET) {
ep->ep_state |= EP_HARD_CLEAR_TOGGLE; ep->ep_state |= EP_HARD_CLEAR_TOGGLE;
xhci_cleanup_stalled_ring(xhci, ep_index, stream_id, td); xhci_cleanup_stalled_ring(xhci, slot_id, ep_index, stream_id,
xhci_clear_hub_tt_buffer(xhci, td, ep); td);
} }
xhci_ring_cmd_db(xhci); xhci_ring_cmd_db(xhci);
} }
...@@ -1978,11 +1996,18 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td, ...@@ -1978,11 +1996,18 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
if (trb_comp_code == COMP_STALL_ERROR || if (trb_comp_code == COMP_STALL_ERROR ||
xhci_requires_manual_halt_cleanup(xhci, ep_ctx, xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
trb_comp_code)) { trb_comp_code)) {
/* Issue a reset endpoint command to clear the host side /*
* halt, followed by a set dequeue command to move the * xhci internal endpoint state will go to a "halt" state for
* dequeue pointer past the TD. * any stall, including default control pipe protocol stall.
* The class driver clears the device side halt later. * To clear the host side halt we need to issue a reset endpoint
* command, followed by a set dequeue command to move past the
* TD.
* Class drivers clear the device side halt from a functional
* stall later. Hub TT buffer should only be cleared for FS/LS
* devices behind HS hubs for functional stalls.
*/ */
if ((ep_index != 0) || (trb_comp_code != COMP_STALL_ERROR))
xhci_clear_hub_tt_buffer(xhci, td, ep);
xhci_cleanup_halted_endpoint(xhci, slot_id, ep_index, xhci_cleanup_halted_endpoint(xhci, slot_id, ep_index,
ep_ring->stream_id, td, EP_HARD_RESET); ep_ring->stream_id, td, EP_HARD_RESET);
} else { } else {
...@@ -2539,6 +2564,15 @@ static int handle_tx_event(struct xhci_hcd *xhci, ...@@ -2539,6 +2564,15 @@ static int handle_tx_event(struct xhci_hcd *xhci,
xhci_dbg(xhci, "td_list is empty while skip flag set. Clear skip flag for slot %u ep %u.\n", xhci_dbg(xhci, "td_list is empty while skip flag set. Clear skip flag for slot %u ep %u.\n",
slot_id, ep_index); slot_id, ep_index);
} }
if (trb_comp_code == COMP_STALL_ERROR ||
xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
trb_comp_code)) {
xhci_cleanup_halted_endpoint(xhci, slot_id,
ep_index,
ep_ring->stream_id,
NULL,
EP_HARD_RESET);
}
goto cleanup; goto cleanup;
} }
......
...@@ -3031,19 +3031,19 @@ static void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, ...@@ -3031,19 +3031,19 @@ static void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
added_ctxs, added_ctxs); added_ctxs, added_ctxs);
} }
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index, void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int slot_id,
unsigned int stream_id, struct xhci_td *td) unsigned int ep_index, unsigned int stream_id,
struct xhci_td *td)
{ {
struct xhci_dequeue_state deq_state; struct xhci_dequeue_state deq_state;
struct usb_device *udev = td->urb->dev;
xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep, xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
"Cleaning up stalled endpoint ring"); "Cleaning up stalled endpoint ring");
/* We need to move the HW's dequeue pointer past this TD, /* We need to move the HW's dequeue pointer past this TD,
* or it will attempt to resend it on the next doorbell ring. * or it will attempt to resend it on the next doorbell ring.
*/ */
xhci_find_new_dequeue_state(xhci, udev->slot_id, xhci_find_new_dequeue_state(xhci, slot_id, ep_index, stream_id, td,
ep_index, stream_id, td, &deq_state); &deq_state);
if (!deq_state.new_deq_ptr || !deq_state.new_deq_seg) if (!deq_state.new_deq_ptr || !deq_state.new_deq_seg)
return; return;
...@@ -3054,7 +3054,7 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index, ...@@ -3054,7 +3054,7 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index,
if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) { if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep, xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
"Queueing new dequeue state"); "Queueing new dequeue state");
xhci_queue_new_dequeue_state(xhci, udev->slot_id, xhci_queue_new_dequeue_state(xhci, slot_id,
ep_index, &deq_state); ep_index, &deq_state);
} else { } else {
/* Better hope no one uses the input context between now and the /* Better hope no one uses the input context between now and the
...@@ -3065,7 +3065,7 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index, ...@@ -3065,7 +3065,7 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index,
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"Setting up input context for " "Setting up input context for "
"configure endpoint command"); "configure endpoint command");
xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id, xhci_setup_input_ctx_for_quirk(xhci, slot_id,
ep_index, &deq_state); ep_index, &deq_state);
} }
} }
......
...@@ -2116,8 +2116,9 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, ...@@ -2116,8 +2116,9 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
unsigned int slot_id, unsigned int ep_index, unsigned int slot_id, unsigned int ep_index,
struct xhci_dequeue_state *deq_state); struct xhci_dequeue_state *deq_state);
void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index, void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int slot_id,
unsigned int stream_id, struct xhci_td *td); unsigned int ep_index, unsigned int stream_id,
struct xhci_td *td);
void xhci_stop_endpoint_command_watchdog(struct timer_list *t); void xhci_stop_endpoint_command_watchdog(struct timer_list *t);
void xhci_handle_command_timeout(struct work_struct *work); void xhci_handle_command_timeout(struct work_struct *work);
......
...@@ -1199,18 +1199,18 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, ...@@ -1199,18 +1199,18 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
/* High level: Gfx (indexed) register access */ /* High level: Gfx (indexed) register access */
#ifdef CONFIG_USB_SISUSBVGA_CON #ifdef CONFIG_USB_SISUSBVGA_CON
int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data) int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data)
{ {
return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data); return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
} }
int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data) int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 *data)
{ {
return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port, data); return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
} }
#endif #endif
int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port,
u8 index, u8 data) u8 index, u8 data)
{ {
int ret; int ret;
...@@ -1220,7 +1220,7 @@ int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, ...@@ -1220,7 +1220,7 @@ int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port,
return ret; return ret;
} }
int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port,
u8 index, u8 *data) u8 index, u8 *data)
{ {
int ret; int ret;
...@@ -1230,7 +1230,7 @@ int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, ...@@ -1230,7 +1230,7 @@ int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port,
return ret; return ret;
} }
int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx, int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx,
u8 myand, u8 myor) u8 myand, u8 myor)
{ {
int ret; int ret;
...@@ -1245,7 +1245,7 @@ int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx, ...@@ -1245,7 +1245,7 @@ int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx,
} }
static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb, static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb,
int port, u8 idx, u8 data, u8 mask) u32 port, u8 idx, u8 data, u8 mask)
{ {
int ret; int ret;
u8 tmp; u8 tmp;
...@@ -1258,13 +1258,13 @@ static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb, ...@@ -1258,13 +1258,13 @@ static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb,
return ret; return ret;
} }
int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port,
u8 index, u8 myor) u8 index, u8 myor)
{ {
return sisusb_setidxregandor(sisusb, port, index, 0xff, myor); return sisusb_setidxregandor(sisusb, port, index, 0xff, myor);
} }
int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port,
u8 idx, u8 myand) u8 idx, u8 myand)
{ {
return sisusb_setidxregandor(sisusb, port, idx, myand, 0x00); return sisusb_setidxregandor(sisusb, port, idx, myand, 0x00);
...@@ -2785,8 +2785,8 @@ static loff_t sisusb_lseek(struct file *file, loff_t offset, int orig) ...@@ -2785,8 +2785,8 @@ static loff_t sisusb_lseek(struct file *file, loff_t offset, int orig)
static int sisusb_handle_command(struct sisusb_usb_data *sisusb, static int sisusb_handle_command(struct sisusb_usb_data *sisusb,
struct sisusb_command *y, unsigned long arg) struct sisusb_command *y, unsigned long arg)
{ {
int retval, port, length; int retval, length;
u32 address; u32 port, address;
/* All our commands require the device /* All our commands require the device
* to be initialized. * to be initialized.
......
...@@ -812,17 +812,17 @@ static const struct SiS_VCLKData SiSUSB_VCLKData[] = { ...@@ -812,17 +812,17 @@ static const struct SiS_VCLKData SiSUSB_VCLKData[] = {
int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
extern int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data); extern int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data);
extern int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 * data); extern int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 * data);
extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port,
u8 index, u8 data); u8 index, u8 data);
extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port,
u8 index, u8 * data); u8 index, u8 * data);
extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port,
u8 idx, u8 myand, u8 myor); u8 idx, u8 myand, u8 myor);
extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port,
u8 index, u8 myor); u8 index, u8 myor);
extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port,
u8 idx, u8 myand); u8 idx, u8 myand);
void sisusb_delete(struct kref *kref); void sisusb_delete(struct kref *kref);
......
...@@ -81,6 +81,19 @@ static void uas_free_streams(struct uas_dev_info *devinfo); ...@@ -81,6 +81,19 @@ static void uas_free_streams(struct uas_dev_info *devinfo);
static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix, static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix,
int status); int status);
/*
* This driver needs its own workqueue, as we need to control memory allocation.
*
* In the course of error handling and power management uas_wait_for_pending_cmnds()
* needs to flush pending work items. In these contexts we cannot allocate memory
* by doing block IO as we would deadlock. For the same reason we cannot wait
* for anything allocating memory not heeding these constraints.
*
* So we have to control all work items that can be on the workqueue we flush.
* Hence we cannot share a queue and need our own.
*/
static struct workqueue_struct *workqueue;
static void uas_do_work(struct work_struct *work) static void uas_do_work(struct work_struct *work)
{ {
struct uas_dev_info *devinfo = struct uas_dev_info *devinfo =
...@@ -109,7 +122,7 @@ static void uas_do_work(struct work_struct *work) ...@@ -109,7 +122,7 @@ static void uas_do_work(struct work_struct *work)
if (!err) if (!err)
cmdinfo->state &= ~IS_IN_WORK_LIST; cmdinfo->state &= ~IS_IN_WORK_LIST;
else else
schedule_work(&devinfo->work); queue_work(workqueue, &devinfo->work);
} }
out: out:
spin_unlock_irqrestore(&devinfo->lock, flags); spin_unlock_irqrestore(&devinfo->lock, flags);
...@@ -134,7 +147,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo) ...@@ -134,7 +147,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo)
lockdep_assert_held(&devinfo->lock); lockdep_assert_held(&devinfo->lock);
cmdinfo->state |= IS_IN_WORK_LIST; cmdinfo->state |= IS_IN_WORK_LIST;
schedule_work(&devinfo->work); queue_work(workqueue, &devinfo->work);
} }
static void uas_zap_pending(struct uas_dev_info *devinfo, int result) static void uas_zap_pending(struct uas_dev_info *devinfo, int result)
...@@ -190,6 +203,9 @@ static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix, ...@@ -190,6 +203,9 @@ static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix,
struct uas_cmd_info *ci = (void *)&cmnd->SCp; struct uas_cmd_info *ci = (void *)&cmnd->SCp;
struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
if (status == -ENODEV) /* too late */
return;
scmd_printk(KERN_INFO, cmnd, scmd_printk(KERN_INFO, cmnd,
"%s %d uas-tag %d inflight:%s%s%s%s%s%s%s%s%s%s%s%s ", "%s %d uas-tag %d inflight:%s%s%s%s%s%s%s%s%s%s%s%s ",
prefix, status, cmdinfo->uas_tag, prefix, status, cmdinfo->uas_tag,
...@@ -1226,7 +1242,31 @@ static struct usb_driver uas_driver = { ...@@ -1226,7 +1242,31 @@ static struct usb_driver uas_driver = {
.id_table = uas_usb_ids, .id_table = uas_usb_ids,
}; };
module_usb_driver(uas_driver); static int __init uas_init(void)
{
int rv;
workqueue = alloc_workqueue("uas", WQ_MEM_RECLAIM, 0);
if (!workqueue)
return -ENOMEM;
rv = usb_register(&uas_driver);
if (rv) {
destroy_workqueue(workqueue);
return -ENOMEM;
}
return 0;
}
static void __exit uas_exit(void)
{
usb_deregister(&uas_driver);
destroy_workqueue(workqueue);
}
module_init(uas_init);
module_exit(uas_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(USB_STORAGE); MODULE_IMPORT_NS(USB_STORAGE);
......
...@@ -2323,6 +2323,13 @@ UNUSUAL_DEV( 0x3340, 0xffff, 0x0000, 0x0000, ...@@ -2323,6 +2323,13 @@ UNUSUAL_DEV( 0x3340, 0xffff, 0x0000, 0x0000,
USB_SC_DEVICE,USB_PR_DEVICE,NULL, USB_SC_DEVICE,USB_PR_DEVICE,NULL,
US_FL_MAX_SECTORS_64 ), US_FL_MAX_SECTORS_64 ),
/* Reported by Cyril Roelandt <tipecaml@gmail.com> */
UNUSUAL_DEV( 0x357d, 0x7788, 0x0114, 0x0114,
"JMicron",
"USB to ATA/ATAPI Bridge",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BROKEN_FUA ),
/* Reported by Andrey Rahmatullin <wrar@altlinux.org> */ /* Reported by Andrey Rahmatullin <wrar@altlinux.org> */
UNUSUAL_DEV( 0x4102, 0x1020, 0x0100, 0x0100, UNUSUAL_DEV( 0x4102, 0x1020, 0x0100, 0x0100,
"iRiver", "iRiver",
......
...@@ -198,7 +198,10 @@ EXPORT_SYMBOL_GPL(typec_altmode_vdm); ...@@ -198,7 +198,10 @@ EXPORT_SYMBOL_GPL(typec_altmode_vdm);
const struct typec_altmode * const struct typec_altmode *
typec_altmode_get_partner(struct typec_altmode *adev) typec_altmode_get_partner(struct typec_altmode *adev)
{ {
return adev ? &to_altmode(adev)->partner->adev : NULL; if (!adev || !to_altmode(adev)->partner)
return NULL;
return &to_altmode(adev)->partner->adev;
} }
EXPORT_SYMBOL_GPL(typec_altmode_get_partner); EXPORT_SYMBOL_GPL(typec_altmode_get_partner);
......
...@@ -114,8 +114,8 @@ pi3usb30532_mux_set(struct typec_mux *mux, struct typec_mux_state *state) ...@@ -114,8 +114,8 @@ pi3usb30532_mux_set(struct typec_mux *mux, struct typec_mux_state *state)
static int pi3usb30532_probe(struct i2c_client *client) static int pi3usb30532_probe(struct i2c_client *client)
{ {
struct device *dev = &client->dev; struct device *dev = &client->dev;
struct typec_switch_desc sw_desc; struct typec_switch_desc sw_desc = { };
struct typec_mux_desc mux_desc; struct typec_mux_desc mux_desc = { };
struct pi3usb30532 *pi; struct pi3usb30532 *pi;
int ret; int ret;
......
...@@ -3794,6 +3794,14 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, ...@@ -3794,6 +3794,14 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
*/ */
break; break;
case PORT_RESET:
case PORT_RESET_WAIT_OFF:
/*
* State set back to default mode once the timer completes.
* Ignore CC changes here.
*/
break;
default: default:
if (tcpm_port_is_disconnected(port)) if (tcpm_port_is_disconnected(port))
tcpm_set_state(port, unattached_state(port), 0); tcpm_set_state(port, unattached_state(port), 0);
...@@ -3855,6 +3863,15 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port) ...@@ -3855,6 +3863,15 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port)
case SRC_TRY_DEBOUNCE: case SRC_TRY_DEBOUNCE:
/* Do nothing, waiting for sink detection */ /* Do nothing, waiting for sink detection */
break; break;
case PORT_RESET:
case PORT_RESET_WAIT_OFF:
/*
* State set back to default mode once the timer completes.
* Ignore vbus changes here.
*/
break;
default: default:
break; break;
} }
...@@ -3908,10 +3925,19 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port) ...@@ -3908,10 +3925,19 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)
case PORT_RESET_WAIT_OFF: case PORT_RESET_WAIT_OFF:
tcpm_set_state(port, tcpm_default_state(port), 0); tcpm_set_state(port, tcpm_default_state(port), 0);
break; break;
case SRC_TRY_WAIT: case SRC_TRY_WAIT:
case SRC_TRY_DEBOUNCE: case SRC_TRY_DEBOUNCE:
/* Do nothing, waiting for sink detection */ /* Do nothing, waiting for sink detection */
break; break;
case PORT_RESET:
/*
* State set back to default mode once the timer completes.
* Ignore vbus changes here.
*/
break;
default: default:
if (port->pwr_role == TYPEC_SINK && if (port->pwr_role == TYPEC_SINK &&
port->attached) port->attached)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment