mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 09:33:31 +02:00
USB fixes for 6.15-rc4
Here are some small USB driver fixes and new device ids for 6.15-rc4. Nothing major in here, just the normal set of issues that have cropped up after -rc1: - new device ids for usb-serial drivers - new device quirks added - typec driver fixes - chipidea driver fixes - xhci driver fixes - wdm driver fixes - cdns3 driver fixes - MAINTAINERS file update All of these, except for the MAINTAINERS file update, have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaAtzuQ8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ynJ+gCgnnXV+nmrAvFffI5LQWlui2xOT8AAoKGt8e8v +FBjTEXoyXzzsbQCYBNS =P5vR -----END PGP SIGNATURE----- Merge tag 'usb-6.15-rc4' 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.15-rc4. Nothing major in here, just the normal set of issues that have cropped up after -rc1: - new device ids for usb-serial drivers - new device quirks added - typec driver fixes - chipidea driver fixes - xhci driver fixes - wdm driver fixes - cdns3 driver fixes - MAINTAINERS file update All of these, except for the MAINTAINERS file update, have been in linux-next for a while with no reported issues" * tag 'usb-6.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (27 commits) MAINTAINERS: Assign maintainer for the port controller drivers USB: serial: simple: add OWON HDS200 series oscilloscope support USB: serial: ftdi_sio: add support for Abacus Electrics Optical Probe USB: serial: option: add Sierra Wireless EM9291 usb: typec: class: Unlocked on error in typec_register_partner() usb: quirks: Add delay init quirk for SanDisk 3.2Gen1 Flash Drive USB: wdm: add annotation USB: wdm: wdm_wwan_port_tx_complete mutex in atomic context USB: wdm: close race between wdm_open and wdm_wwan_port_stop USB: wdm: handle IO errors in wdm_wwan_port_start USB: VLI disk crashes if LPM is used usb: dwc3: gadget: check that event count does not exceed event buffer length USB: storage: quirk for ADATA Portable HDD CH94 usb: quirks: add DELAY_INIT quirk for Silicon Motion Flash Drive USB: OHCI: Add quirk for LS7A OHCI controller (rev 0x02) usb: dwc3: xilinx: Prevent spike in reset signal usb: cdns3: Fix deadlock when using NCM gadget usb: chipidea: ci_hdrc_imx: implement usb_phy_init() error handling usb: chipidea: ci_hdrc_imx: fix call balance of regulator routines usb: chipidea: ci_hdrc_imx: fix usbmisc handling ...
This commit is contained in:
commit
2d5c7fe097
|
|
@ -25204,9 +25204,13 @@ S: Maintained
|
|||
F: drivers/usb/typec/mux/pi3usb30532.c
|
||||
|
||||
USB TYPEC PORT CONTROLLER DRIVERS
|
||||
M: Badhri Jagan Sridharan <badhri@google.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Orphan
|
||||
F: drivers/usb/typec/tcpm/
|
||||
S: Maintained
|
||||
F: drivers/usb/typec/tcpm/tcpci.c
|
||||
F: drivers/usb/typec/tcpm/tcpm.c
|
||||
F: include/linux/usb/tcpci.h
|
||||
F: include/linux/usb/tcpm.h
|
||||
|
||||
USB TYPEC TUSB1046 MUX DRIVER
|
||||
M: Romain Gantois <romain.gantois@bootlin.com>
|
||||
|
|
|
|||
|
|
@ -1963,6 +1963,7 @@ static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
|
|||
unsigned int bit;
|
||||
unsigned long reg;
|
||||
|
||||
local_bh_disable();
|
||||
spin_lock_irqsave(&priv_dev->lock, flags);
|
||||
|
||||
reg = readl(&priv_dev->regs->usb_ists);
|
||||
|
|
@ -2004,6 +2005,7 @@ static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
|
|||
irqend:
|
||||
writel(~0, &priv_dev->regs->ep_ien);
|
||||
spin_unlock_irqrestore(&priv_dev->lock, flags);
|
||||
local_bh_enable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -336,6 +336,13 @@ static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void ci_hdrc_imx_disable_regulator(void *arg)
|
||||
{
|
||||
struct ci_hdrc_imx_data *data = arg;
|
||||
|
||||
regulator_disable(data->hsic_pad_regulator);
|
||||
}
|
||||
|
||||
static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ci_hdrc_imx_data *data;
|
||||
|
|
@ -394,6 +401,13 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||
"Failed to enable HSIC pad regulator\n");
|
||||
goto err_put;
|
||||
}
|
||||
ret = devm_add_action_or_reset(dev,
|
||||
ci_hdrc_imx_disable_regulator, data);
|
||||
if (ret) {
|
||||
dev_err(dev,
|
||||
"Failed to add regulator devm action\n");
|
||||
goto err_put;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -432,11 +446,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||
|
||||
ret = imx_get_clks(dev);
|
||||
if (ret)
|
||||
goto disable_hsic_regulator;
|
||||
goto qos_remove_request;
|
||||
|
||||
ret = imx_prepare_enable_clks(dev);
|
||||
if (ret)
|
||||
goto disable_hsic_regulator;
|
||||
goto qos_remove_request;
|
||||
|
||||
ret = clk_prepare_enable(data->clk_wakeup);
|
||||
if (ret)
|
||||
|
|
@ -470,7 +484,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||
of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
|
||||
pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
|
||||
data->override_phy_control = true;
|
||||
usb_phy_init(pdata.usb_phy);
|
||||
ret = usb_phy_init(pdata.usb_phy);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to init phy\n");
|
||||
goto err_clk;
|
||||
}
|
||||
}
|
||||
|
||||
if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
|
||||
|
|
@ -479,7 +497,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||
ret = imx_usbmisc_init(data->usbmisc_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
|
||||
goto err_clk;
|
||||
goto phy_shutdown;
|
||||
}
|
||||
|
||||
data->ci_pdev = ci_hdrc_add_device(dev,
|
||||
|
|
@ -488,7 +506,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(data->ci_pdev)) {
|
||||
ret = PTR_ERR(data->ci_pdev);
|
||||
dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n");
|
||||
goto err_clk;
|
||||
goto phy_shutdown;
|
||||
}
|
||||
|
||||
if (data->usbmisc_data) {
|
||||
|
|
@ -522,19 +540,20 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||
|
||||
disable_device:
|
||||
ci_hdrc_remove_device(data->ci_pdev);
|
||||
phy_shutdown:
|
||||
if (data->override_phy_control)
|
||||
usb_phy_shutdown(data->phy);
|
||||
err_clk:
|
||||
clk_disable_unprepare(data->clk_wakeup);
|
||||
err_wakeup_clk:
|
||||
imx_disable_unprepare_clks(dev);
|
||||
disable_hsic_regulator:
|
||||
if (data->hsic_pad_regulator)
|
||||
/* don't overwrite original ret (cf. EPROBE_DEFER) */
|
||||
regulator_disable(data->hsic_pad_regulator);
|
||||
qos_remove_request:
|
||||
if (pdata.flags & CI_HDRC_PMQOS)
|
||||
cpu_latency_qos_remove_request(&data->pm_qos_req);
|
||||
data->ci_pdev = NULL;
|
||||
err_put:
|
||||
put_device(data->usbmisc_data->dev);
|
||||
if (data->usbmisc_data)
|
||||
put_device(data->usbmisc_data->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -556,10 +575,9 @@ static void ci_hdrc_imx_remove(struct platform_device *pdev)
|
|||
clk_disable_unprepare(data->clk_wakeup);
|
||||
if (data->plat_data->flags & CI_HDRC_PMQOS)
|
||||
cpu_latency_qos_remove_request(&data->pm_qos_req);
|
||||
if (data->hsic_pad_regulator)
|
||||
regulator_disable(data->hsic_pad_regulator);
|
||||
}
|
||||
put_device(data->usbmisc_data->dev);
|
||||
if (data->usbmisc_data)
|
||||
put_device(data->usbmisc_data->dev);
|
||||
}
|
||||
|
||||
static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -726,7 +726,7 @@ static int wdm_open(struct inode *inode, struct file *file)
|
|||
rv = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
smp_rmb(); /* ordered against wdm_wwan_port_stop() */
|
||||
rv = usb_autopm_get_interface(desc->intf);
|
||||
if (rv < 0) {
|
||||
dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
|
||||
|
|
@ -829,6 +829,7 @@ static struct usb_class_driver wdm_class = {
|
|||
static int wdm_wwan_port_start(struct wwan_port *port)
|
||||
{
|
||||
struct wdm_device *desc = wwan_port_get_drvdata(port);
|
||||
int rv;
|
||||
|
||||
/* The interface is both exposed via the WWAN framework and as a
|
||||
* legacy usbmisc chardev. If chardev is already open, just fail
|
||||
|
|
@ -848,7 +849,15 @@ static int wdm_wwan_port_start(struct wwan_port *port)
|
|||
wwan_port_txon(port);
|
||||
|
||||
/* Start getting events */
|
||||
return usb_submit_urb(desc->validity, GFP_KERNEL);
|
||||
rv = usb_submit_urb(desc->validity, GFP_KERNEL);
|
||||
if (rv < 0) {
|
||||
wwan_port_txoff(port);
|
||||
desc->manage_power(desc->intf, 0);
|
||||
/* this must be last lest we race with chardev open */
|
||||
clear_bit(WDM_WWAN_IN_USE, &desc->flags);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void wdm_wwan_port_stop(struct wwan_port *port)
|
||||
|
|
@ -859,8 +868,10 @@ static void wdm_wwan_port_stop(struct wwan_port *port)
|
|||
poison_urbs(desc);
|
||||
desc->manage_power(desc->intf, 0);
|
||||
clear_bit(WDM_READ, &desc->flags);
|
||||
clear_bit(WDM_WWAN_IN_USE, &desc->flags);
|
||||
unpoison_urbs(desc);
|
||||
smp_wmb(); /* ordered against wdm_open() */
|
||||
/* this must be last lest we open a poisoned device */
|
||||
clear_bit(WDM_WWAN_IN_USE, &desc->flags);
|
||||
}
|
||||
|
||||
static void wdm_wwan_port_tx_complete(struct urb *urb)
|
||||
|
|
@ -868,7 +879,7 @@ static void wdm_wwan_port_tx_complete(struct urb *urb)
|
|||
struct sk_buff *skb = urb->context;
|
||||
struct wdm_device *desc = skb_shinfo(skb)->destructor_arg;
|
||||
|
||||
usb_autopm_put_interface(desc->intf);
|
||||
usb_autopm_put_interface_async(desc->intf);
|
||||
wwan_port_txon(desc->wwanp);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
|
@ -898,7 +909,7 @@ static int wdm_wwan_port_tx(struct wwan_port *port, struct sk_buff *skb)
|
|||
req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
|
||||
req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
|
||||
req->wValue = 0;
|
||||
req->wIndex = desc->inum;
|
||||
req->wIndex = desc->inum; /* already converted */
|
||||
req->wLength = cpu_to_le16(skb->len);
|
||||
|
||||
skb_shinfo(skb)->destructor_arg = desc;
|
||||
|
|
|
|||
|
|
@ -369,6 +369,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
{ USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM },
|
||||
{ USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
/* SanDisk Corp. SanDisk 3.2Gen1 */
|
||||
{ USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
/* Realforce 87U Keyboard */
|
||||
{ USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
|
|
@ -383,6 +386,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
{ USB_DEVICE(0x0904, 0x6103), .driver_info =
|
||||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
|
||||
|
||||
/* Silicon Motion Flash Drive */
|
||||
{ USB_DEVICE(0x090c, 0x1000), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
/* Sound Devices USBPre2 */
|
||||
{ USB_DEVICE(0x0926, 0x0202), .driver_info =
|
||||
USB_QUIRK_ENDPOINT_IGNORE },
|
||||
|
|
@ -539,6 +545,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
{ USB_DEVICE(0x2040, 0x7200), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
/* VLI disk */
|
||||
{ USB_DEVICE(0x2109, 0x0711), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
/* Raydium Touchscreen */
|
||||
{ USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
|
|
|
|||
|
|
@ -207,15 +207,13 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
|
|||
|
||||
skip_usb3_phy:
|
||||
/* ulpi reset via gpio-modepin or gpio-framework driver */
|
||||
reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
|
||||
reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(reset_gpio)) {
|
||||
return dev_err_probe(dev, PTR_ERR(reset_gpio),
|
||||
"Failed to request reset GPIO\n");
|
||||
}
|
||||
|
||||
if (reset_gpio) {
|
||||
/* Toggle ulpi to reset the phy. */
|
||||
gpiod_set_value_cansleep(reset_gpio, 1);
|
||||
usleep_range(5000, 10000);
|
||||
gpiod_set_value_cansleep(reset_gpio, 0);
|
||||
usleep_range(5000, 10000);
|
||||
|
|
|
|||
|
|
@ -4617,6 +4617,12 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
|
|||
if (!count)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (count > evt->length) {
|
||||
dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n",
|
||||
count, evt->length);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
evt->count = count;
|
||||
evt->flags |= DWC3_EVENT_PENDING;
|
||||
|
||||
|
|
|
|||
|
|
@ -165,6 +165,25 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ohci_quirk_loongson(struct usb_hcd *hcd)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
|
||||
/*
|
||||
* Loongson's LS7A OHCI controller (rev 0x02) has a
|
||||
* flaw. MMIO register with offset 0x60/64 is treated
|
||||
* as legacy PS2-compatible keyboard/mouse interface.
|
||||
* Since OHCI only use 4KB BAR resource, LS7A OHCI's
|
||||
* 32KB BAR is wrapped around (the 2nd 4KB BAR space
|
||||
* is the same as the 1st 4KB internally). So add 4KB
|
||||
* offset (0x1000) to the OHCI registers as a quirk.
|
||||
*/
|
||||
if (pdev->revision == 0x2)
|
||||
hcd->regs += SZ_4K; /* SZ_4K = 0x1000 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ohci_quirk_qemu(struct usb_hcd *hcd)
|
||||
{
|
||||
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||||
|
|
@ -224,6 +243,10 @@ static const struct pci_device_id ohci_pci_quirks[] = {
|
|||
PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
|
||||
.driver_data = (unsigned long)ohci_quirk_amd700,
|
||||
},
|
||||
{
|
||||
PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, 0x7a24),
|
||||
.driver_data = (unsigned long)ohci_quirk_loongson,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_APPLE,
|
||||
.device = 0x003f,
|
||||
|
|
|
|||
|
|
@ -1878,9 +1878,10 @@ int xhci_bus_resume(struct usb_hcd *hcd)
|
|||
int max_ports, port_index;
|
||||
int sret;
|
||||
u32 next_state;
|
||||
u32 temp, portsc;
|
||||
u32 portsc;
|
||||
struct xhci_hub *rhub;
|
||||
struct xhci_port **ports;
|
||||
bool disabled_irq = false;
|
||||
|
||||
rhub = xhci_get_rhub(hcd);
|
||||
ports = rhub->ports;
|
||||
|
|
@ -1896,17 +1897,20 @@ int xhci_bus_resume(struct usb_hcd *hcd)
|
|||
return -ESHUTDOWN;
|
||||
}
|
||||
|
||||
/* delay the irqs */
|
||||
temp = readl(&xhci->op_regs->command);
|
||||
temp &= ~CMD_EIE;
|
||||
writel(temp, &xhci->op_regs->command);
|
||||
|
||||
/* bus specific resume for ports we suspended at bus_suspend */
|
||||
if (hcd->speed >= HCD_USB3)
|
||||
if (hcd->speed >= HCD_USB3) {
|
||||
next_state = XDEV_U0;
|
||||
else
|
||||
} else {
|
||||
next_state = XDEV_RESUME;
|
||||
|
||||
if (bus_state->bus_suspended) {
|
||||
/*
|
||||
* prevent port event interrupts from interfering
|
||||
* with usb2 port resume process
|
||||
*/
|
||||
xhci_disable_interrupter(xhci->interrupters[0]);
|
||||
disabled_irq = true;
|
||||
}
|
||||
}
|
||||
port_index = max_ports;
|
||||
while (port_index--) {
|
||||
portsc = readl(ports[port_index]->addr);
|
||||
|
|
@ -1974,11 +1978,9 @@ int xhci_bus_resume(struct usb_hcd *hcd)
|
|||
(void) readl(&xhci->op_regs->command);
|
||||
|
||||
bus_state->next_statechange = jiffies + msecs_to_jiffies(5);
|
||||
/* re-enable irqs */
|
||||
temp = readl(&xhci->op_regs->command);
|
||||
temp |= CMD_EIE;
|
||||
writel(temp, &xhci->op_regs->command);
|
||||
temp = readl(&xhci->op_regs->command);
|
||||
/* re-enable interrupter */
|
||||
if (disabled_irq)
|
||||
xhci_enable_interrupter(xhci->interrupters[0]);
|
||||
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -561,8 +561,8 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci,
|
|||
* pointer command pending because the device can choose to start any
|
||||
* stream once the endpoint is on the HW schedule.
|
||||
*/
|
||||
if (ep_state & (EP_STOP_CMD_PENDING | SET_DEQ_PENDING | EP_HALTED |
|
||||
EP_CLEARING_TT | EP_STALLED))
|
||||
if ((ep_state & EP_STOP_CMD_PENDING) || (ep_state & SET_DEQ_PENDING) ||
|
||||
(ep_state & EP_HALTED) || (ep_state & EP_CLEARING_TT))
|
||||
return;
|
||||
|
||||
trace_xhci_ring_ep_doorbell(slot_id, DB_VALUE(ep_index, stream_id));
|
||||
|
|
@ -2573,9 +2573,6 @@ static void process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
|
|||
|
||||
xhci_handle_halted_endpoint(xhci, ep, td, EP_SOFT_RESET);
|
||||
return;
|
||||
case COMP_STALL_ERROR:
|
||||
ep->ep_state |= EP_STALLED;
|
||||
break;
|
||||
default:
|
||||
/* do nothing */
|
||||
break;
|
||||
|
|
@ -2916,7 +2913,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
|||
if (xhci_spurious_success_tx_event(xhci, ep_ring)) {
|
||||
xhci_dbg(xhci, "Spurious event dma %pad, comp_code %u after %u\n",
|
||||
&ep_trb_dma, trb_comp_code, ep_ring->old_trb_comp_code);
|
||||
ep_ring->old_trb_comp_code = trb_comp_code;
|
||||
ep_ring->old_trb_comp_code = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3780,7 +3777,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
|||
* enqueue a No Op TRB, this can prevent the Setup and Data Stage
|
||||
* TRB to be breaked by the Link TRB.
|
||||
*/
|
||||
if (trb_is_link(ep_ring->enqueue + 1)) {
|
||||
if (last_trb_on_seg(ep_ring->enq_seg, ep_ring->enqueue + 1)) {
|
||||
field = TRB_TYPE(TRB_TR_NOOP) | ep_ring->cycle_state;
|
||||
queue_trb(xhci, ep_ring, false, 0, 0,
|
||||
TRB_INTR_TARGET(0), field);
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
|
|||
xhci_info(xhci, "Fault detected\n");
|
||||
}
|
||||
|
||||
static int xhci_enable_interrupter(struct xhci_interrupter *ir)
|
||||
int xhci_enable_interrupter(struct xhci_interrupter *ir)
|
||||
{
|
||||
u32 iman;
|
||||
|
||||
|
|
@ -335,7 +335,7 @@ static int xhci_enable_interrupter(struct xhci_interrupter *ir)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int xhci_disable_interrupter(struct xhci_interrupter *ir)
|
||||
int xhci_disable_interrupter(struct xhci_interrupter *ir)
|
||||
{
|
||||
u32 iman;
|
||||
|
||||
|
|
@ -1605,11 +1605,6 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
|
|||
goto free_priv;
|
||||
}
|
||||
|
||||
/* Class driver might not be aware ep halted due to async URB giveback */
|
||||
if (*ep_state & EP_STALLED)
|
||||
dev_dbg(&urb->dev->dev, "URB %p queued before clearing halt\n",
|
||||
urb);
|
||||
|
||||
switch (usb_endpoint_type(&urb->ep->desc)) {
|
||||
|
||||
case USB_ENDPOINT_XFER_CONTROL:
|
||||
|
|
@ -1770,8 +1765,8 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* In these cases no commands are pending but the endpoint is stopped */
|
||||
if (ep->ep_state & (EP_CLEARING_TT | EP_STALLED)) {
|
||||
/* In this case no commands are pending but the endpoint is stopped */
|
||||
if (ep->ep_state & EP_CLEARING_TT) {
|
||||
/* and cancelled TDs can be given back right away */
|
||||
xhci_dbg(xhci, "Invalidating TDs instantly on slot %d ep %d in state 0x%x\n",
|
||||
urb->dev->slot_id, ep_index, ep->ep_state);
|
||||
|
|
@ -3209,11 +3204,8 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
|
|||
|
||||
ep = &vdev->eps[ep_index];
|
||||
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
|
||||
ep->ep_state &= ~EP_STALLED;
|
||||
|
||||
/* Bail out if toggle is already being cleared by a endpoint reset */
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
if (ep->ep_state & EP_HARD_CLEAR_TOGGLE) {
|
||||
ep->ep_state &= ~EP_HARD_CLEAR_TOGGLE;
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
|
|
|
|||
|
|
@ -664,7 +664,7 @@ struct xhci_virt_ep {
|
|||
unsigned int err_count;
|
||||
unsigned int ep_state;
|
||||
#define SET_DEQ_PENDING (1 << 0)
|
||||
#define EP_HALTED (1 << 1) /* Halted host ep handling */
|
||||
#define EP_HALTED (1 << 1) /* For stall handling */
|
||||
#define EP_STOP_CMD_PENDING (1 << 2) /* For URB cancellation */
|
||||
/* Transitioning the endpoint to using streams, don't enqueue URBs */
|
||||
#define EP_GETTING_STREAMS (1 << 3)
|
||||
|
|
@ -675,7 +675,6 @@ struct xhci_virt_ep {
|
|||
#define EP_SOFT_CLEAR_TOGGLE (1 << 7)
|
||||
/* usb_hub_clear_tt_buffer is in progress */
|
||||
#define EP_CLEARING_TT (1 << 8)
|
||||
#define EP_STALLED (1 << 9) /* For stall handling */
|
||||
/* ---- Related to URB cancellation ---- */
|
||||
struct list_head cancelled_td_list;
|
||||
struct xhci_hcd *xhci;
|
||||
|
|
@ -1891,6 +1890,8 @@ int xhci_alloc_tt_info(struct xhci_hcd *xhci,
|
|||
struct usb_tt *tt, gfp_t mem_flags);
|
||||
int xhci_set_interrupter_moderation(struct xhci_interrupter *ir,
|
||||
u32 imod_interval);
|
||||
int xhci_enable_interrupter(struct xhci_interrupter *ir);
|
||||
int xhci_disable_interrupter(struct xhci_interrupter *ir);
|
||||
|
||||
/* xHCI ring, segment, TRB, and TD functions */
|
||||
dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb);
|
||||
|
|
|
|||
|
|
@ -1093,6 +1093,8 @@ static const struct usb_device_id id_table_combined[] = {
|
|||
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 1) },
|
||||
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 2) },
|
||||
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 3) },
|
||||
/* Abacus Electrics */
|
||||
{ USB_DEVICE(FTDI_VID, ABACUS_OPTICAL_PROBE_PID) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -442,6 +442,11 @@
|
|||
#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */
|
||||
#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */
|
||||
|
||||
/*
|
||||
* Abacus Electrics
|
||||
*/
|
||||
#define ABACUS_OPTICAL_PROBE_PID 0xf458 /* ABACUS ELECTRICS Optical Probe */
|
||||
|
||||
/*
|
||||
* Oceanic product ids
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -611,6 +611,7 @@ static void option_instat_callback(struct urb *urb);
|
|||
/* Sierra Wireless products */
|
||||
#define SIERRA_VENDOR_ID 0x1199
|
||||
#define SIERRA_PRODUCT_EM9191 0x90d3
|
||||
#define SIERRA_PRODUCT_EM9291 0x90e3
|
||||
|
||||
/* UNISOC (Spreadtrum) products */
|
||||
#define UNISOC_VENDOR_ID 0x1782
|
||||
|
|
@ -2432,6 +2433,8 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x30) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
|
||||
|
|
|
|||
|
|
@ -100,6 +100,11 @@ DEVICE(nokia, NOKIA_IDS);
|
|||
{ USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */
|
||||
DEVICE_N(novatel_gps, NOVATEL_IDS, 3);
|
||||
|
||||
/* OWON electronic test and measurement equipment driver */
|
||||
#define OWON_IDS() \
|
||||
{ USB_DEVICE(0x5345, 0x1234) } /* HDS200 oscilloscopes and others */
|
||||
DEVICE(owon, OWON_IDS);
|
||||
|
||||
/* Siemens USB/MPI adapter */
|
||||
#define SIEMENS_IDS() \
|
||||
{ USB_DEVICE(0x908, 0x0004) }
|
||||
|
|
@ -134,6 +139,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
|
|||
&motorola_tetra_device,
|
||||
&nokia_device,
|
||||
&novatel_gps_device,
|
||||
&owon_device,
|
||||
&siemens_mpi_device,
|
||||
&suunto_device,
|
||||
&vivopay_device,
|
||||
|
|
@ -153,6 +159,7 @@ static const struct usb_device_id id_table[] = {
|
|||
MOTOROLA_TETRA_IDS(),
|
||||
NOKIA_IDS(),
|
||||
NOVATEL_IDS(),
|
||||
OWON_IDS(),
|
||||
SIEMENS_IDS(),
|
||||
SUUNTO_IDS(),
|
||||
VIVOPAY_IDS(),
|
||||
|
|
|
|||
|
|
@ -83,6 +83,13 @@ UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999,
|
|||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_NO_REPORT_LUNS),
|
||||
|
||||
/* Reported-by: Oliver Neukum <oneukum@suse.com> */
|
||||
UNUSUAL_DEV(0x125f, 0xa94a, 0x0160, 0x0160,
|
||||
"ADATA",
|
||||
"Portable HDD CH94",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_NO_ATA_1X),
|
||||
|
||||
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
|
||||
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
|
||||
"Initio Corporation",
|
||||
|
|
|
|||
|
|
@ -1052,9 +1052,11 @@ struct typec_partner *typec_register_partner(struct typec_port *port,
|
|||
partner->usb_mode = USB_MODE_USB3;
|
||||
}
|
||||
|
||||
mutex_lock(&port->partner_link_lock);
|
||||
ret = device_register(&partner->dev);
|
||||
if (ret) {
|
||||
dev_err(&port->dev, "failed to register partner (%d)\n", ret);
|
||||
mutex_unlock(&port->partner_link_lock);
|
||||
put_device(&partner->dev);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
|
@ -1063,6 +1065,7 @@ struct typec_partner *typec_register_partner(struct typec_port *port,
|
|||
typec_partner_link_device(partner, port->usb2_dev);
|
||||
if (port->usb3_dev)
|
||||
typec_partner_link_device(partner, port->usb3_dev);
|
||||
mutex_unlock(&port->partner_link_lock);
|
||||
|
||||
return partner;
|
||||
}
|
||||
|
|
@ -1083,12 +1086,18 @@ void typec_unregister_partner(struct typec_partner *partner)
|
|||
|
||||
port = to_typec_port(partner->dev.parent);
|
||||
|
||||
if (port->usb2_dev)
|
||||
mutex_lock(&port->partner_link_lock);
|
||||
if (port->usb2_dev) {
|
||||
typec_partner_unlink_device(partner, port->usb2_dev);
|
||||
if (port->usb3_dev)
|
||||
port->usb2_dev = NULL;
|
||||
}
|
||||
if (port->usb3_dev) {
|
||||
typec_partner_unlink_device(partner, port->usb3_dev);
|
||||
port->usb3_dev = NULL;
|
||||
}
|
||||
|
||||
device_unregister(&partner->dev);
|
||||
mutex_unlock(&port->partner_link_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(typec_unregister_partner);
|
||||
|
||||
|
|
@ -2041,10 +2050,11 @@ static struct typec_partner *typec_get_partner(struct typec_port *port)
|
|||
static void typec_partner_attach(struct typec_connector *con, struct device *dev)
|
||||
{
|
||||
struct typec_port *port = container_of(con, struct typec_port, con);
|
||||
struct typec_partner *partner = typec_get_partner(port);
|
||||
struct typec_partner *partner;
|
||||
struct usb_device *udev = to_usb_device(dev);
|
||||
enum usb_mode usb_mode;
|
||||
|
||||
mutex_lock(&port->partner_link_lock);
|
||||
if (udev->speed < USB_SPEED_SUPER) {
|
||||
usb_mode = USB_MODE_USB2;
|
||||
port->usb2_dev = dev;
|
||||
|
|
@ -2053,18 +2063,22 @@ static void typec_partner_attach(struct typec_connector *con, struct device *dev
|
|||
port->usb3_dev = dev;
|
||||
}
|
||||
|
||||
partner = typec_get_partner(port);
|
||||
if (partner) {
|
||||
typec_partner_set_usb_mode(partner, usb_mode);
|
||||
typec_partner_link_device(partner, dev);
|
||||
put_device(&partner->dev);
|
||||
}
|
||||
mutex_unlock(&port->partner_link_lock);
|
||||
}
|
||||
|
||||
static void typec_partner_deattach(struct typec_connector *con, struct device *dev)
|
||||
{
|
||||
struct typec_port *port = container_of(con, struct typec_port, con);
|
||||
struct typec_partner *partner = typec_get_partner(port);
|
||||
struct typec_partner *partner;
|
||||
|
||||
mutex_lock(&port->partner_link_lock);
|
||||
partner = typec_get_partner(port);
|
||||
if (partner) {
|
||||
typec_partner_unlink_device(partner, dev);
|
||||
put_device(&partner->dev);
|
||||
|
|
@ -2074,6 +2088,7 @@ static void typec_partner_deattach(struct typec_connector *con, struct device *d
|
|||
port->usb2_dev = NULL;
|
||||
else if (port->usb3_dev == dev)
|
||||
port->usb3_dev = NULL;
|
||||
mutex_unlock(&port->partner_link_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2614,6 +2629,7 @@ struct typec_port *typec_register_port(struct device *parent,
|
|||
|
||||
ida_init(&port->mode_ids);
|
||||
mutex_init(&port->port_type_lock);
|
||||
mutex_init(&port->partner_link_lock);
|
||||
|
||||
port->id = id;
|
||||
port->ops = cap->ops;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ struct typec_port {
|
|||
enum typec_port_type port_type;
|
||||
enum usb_mode usb_mode;
|
||||
struct mutex port_type_lock;
|
||||
struct mutex partner_link_lock;
|
||||
|
||||
enum typec_orientation orientation;
|
||||
struct typec_switch *sw;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user