Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec014873 authored by Linus Torvalds's avatar Linus Torvalds
Browse files


Pull USB fixes from Greg Kroah-Hartman:
 "Here are some USB fixes for the 3.7 tree.

  Nothing huge here, just a number of tiny bugfixes resolving issues
  that have been found, and two reverts of patches that were found to
  have caused problems.

  All of these have been in linux-next already.

  Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org&gt;">

* tag 'usb-3.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  Revert "USB/host: Cleanup unneccessary irq disable code"
  USB: option: add Alcatel X220/X500D USB IDs
  USB: option: add Novatel E362 and Dell Wireless 5800 USB IDs
  USB: keyspan: fix typo causing GPF on open
  USB: fix build with XEN and EARLY_PRINTK_DBGP enabled but USB_SUPPORT disabled
  USB: usb_wwan: fix bulk-urb allocation
  usb: otg: Fix build errors if USB_MUSB_OMAP2PLUS is selected as module
  usb: musb: ux500: fix 'musbid' undeclared error in ux500_remove()
  Revert "usb: musb: use DMA mode 1 whenever possible"
parents d6ee1a28 e592c5d0
Loading
Loading
Loading
Loading
+16 −0
Original line number Original line Diff line number Diff line
@@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum);
irqreturn_t usb_hcd_irq (int irq, void *__hcd)
irqreturn_t usb_hcd_irq (int irq, void *__hcd)
{
{
	struct usb_hcd		*hcd = __hcd;
	struct usb_hcd		*hcd = __hcd;
	unsigned long		flags;
	irqreturn_t		rc;
	irqreturn_t		rc;


	/* IRQF_DISABLED doesn't work correctly with shared IRQs
	 * when the first handler doesn't use it.  So let's just
	 * assume it's never used.
	 */
	local_irq_save(flags);

	if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd)))
	if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd)))
		rc = IRQ_NONE;
		rc = IRQ_NONE;
	else if (hcd->driver->irq(hcd) == IRQ_NONE)
	else if (hcd->driver->irq(hcd) == IRQ_NONE)
@@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
	else
	else
		rc = IRQ_HANDLED;
		rc = IRQ_HANDLED;


	local_irq_restore(flags);
	return rc;
	return rc;
}
}
EXPORT_SYMBOL_GPL(usb_hcd_irq);
EXPORT_SYMBOL_GPL(usb_hcd_irq);
@@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd,
	int retval;
	int retval;


	if (hcd->driver->irq) {
	if (hcd->driver->irq) {

		/* IRQF_DISABLED doesn't work as advertised when used together
		 * with IRQF_SHARED. As usb_hcd_irq() will always disable
		 * interrupts we can remove it here.
		 */
		if (irqflags & IRQF_SHARED)
			irqflags &= ~IRQF_DISABLED;

		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
				hcd->driver->description, hcd->self.busnum);
				hcd->driver->description, hcd->self.busnum);
		retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
		retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
+9 −6
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/usb/ehci_def.h>
#include <linux/usb/ehci_def.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/serial_core.h>
#include <linux/serial_core.h>
#include <linux/kconfig.h>
#include <linux/kgdb.h>
#include <linux/kgdb.h>
#include <linux/kthread.h>
#include <linux/kthread.h>
#include <asm/io.h>
#include <asm/io.h>
@@ -614,12 +615,6 @@ static int _dbgp_external_startup(void)
	return -ENODEV;
	return -ENODEV;
}
}


int dbgp_external_startup(struct usb_hcd *hcd)
{
	return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
}
EXPORT_SYMBOL_GPL(dbgp_external_startup);

static int ehci_reset_port(int port)
static int ehci_reset_port(int port)
{
{
	u32 portsc;
	u32 portsc;
@@ -979,6 +974,7 @@ struct console early_dbgp_console = {
	.index =	-1,
	.index =	-1,
};
};


#if IS_ENABLED(CONFIG_USB_EHCI_HCD)
int dbgp_reset_prep(struct usb_hcd *hcd)
int dbgp_reset_prep(struct usb_hcd *hcd)
{
{
	int ret = xen_dbgp_reset_prep(hcd);
	int ret = xen_dbgp_reset_prep(hcd);
@@ -1007,6 +1003,13 @@ int dbgp_reset_prep(struct usb_hcd *hcd)
}
}
EXPORT_SYMBOL_GPL(dbgp_reset_prep);
EXPORT_SYMBOL_GPL(dbgp_reset_prep);


int dbgp_external_startup(struct usb_hcd *hcd)
{
	return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
}
EXPORT_SYMBOL_GPL(dbgp_external_startup);
#endif /* USB_EHCI_HCD */

#ifdef CONFIG_KGDB
#ifdef CONFIG_KGDB


static char kgdbdbgp_buf[DBGP_MAX_PACKET];
static char kgdbdbgp_buf[DBGP_MAX_PACKET];
+1 −1
Original line number Original line Diff line number Diff line
@@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev)
		goto err_put_hcd;
		goto err_put_hcd;
	}
	}


	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (ret)
	if (ret)
		goto err_put_hcd;
		goto err_put_hcd;


+1 −1
Original line number Original line Diff line number Diff line
@@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver,
		goto err3;
		goto err3;
	}
	}


	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (retval != 0)
	if (retval != 0)
		goto err4;
		goto err4;
	return retval;
	return retval;
+26 −4
Original line number Original line Diff line number Diff line
@@ -707,11 +707,12 @@ static void rxstate(struct musb *musb, struct musb_request *req)
		fifo_count = musb_readw(epio, MUSB_RXCOUNT);
		fifo_count = musb_readw(epio, MUSB_RXCOUNT);


		/*
		/*
		 *  use mode 1 only if we expect data of at least ep packet_sz
		 * Enable Mode 1 on RX transfers only when short_not_ok flag
		 *  and have not yet received a short packet
		 * is set. Currently short_not_ok flag is set only from
		 * file_storage and f_mass_storage drivers
		 */
		 */
		if ((request->length - request->actual >= musb_ep->packet_sz) &&

			(fifo_count >= musb_ep->packet_sz))
		if (request->short_not_ok && fifo_count == musb_ep->packet_sz)
			use_mode_1 = 1;
			use_mode_1 = 1;
		else
		else
			use_mode_1 = 0;
			use_mode_1 = 0;
@@ -727,6 +728,27 @@ static void rxstate(struct musb *musb, struct musb_request *req)
				c = musb->dma_controller;
				c = musb->dma_controller;
				channel = musb_ep->dma;
				channel = musb_ep->dma;


	/* We use DMA Req mode 0 in rx_csr, and DMA controller operates in
	 * mode 0 only. So we do not get endpoint interrupts due to DMA
	 * completion. We only get interrupts from DMA controller.
	 *
	 * We could operate in DMA mode 1 if we knew the size of the tranfer
	 * in advance. For mass storage class, request->length = what the host
	 * sends, so that'd work.  But for pretty much everything else,
	 * request->length is routinely more than what the host sends. For
	 * most these gadgets, end of is signified either by a short packet,
	 * or filling the last byte of the buffer.  (Sending extra data in
	 * that last pckate should trigger an overflow fault.)  But in mode 1,
	 * we don't get DMA completion interrupt for short packets.
	 *
	 * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1),
	 * to get endpoint interrupt on every DMA req, but that didn't seem
	 * to work reliably.
	 *
	 * REVISIT an updated g_file_storage can set req->short_not_ok, which
	 * then becomes usable as a runtime "use mode 1" hint...
	 */

				/* Experimental: Mode1 works with mass storage use cases */
				/* Experimental: Mode1 works with mass storage use cases */
				if (use_mode_1) {
				if (use_mode_1) {
					csr |= MUSB_RXCSR_AUTOCLEAR;
					csr |= MUSB_RXCSR_AUTOCLEAR;
Loading