[PATCH 0/7] USB changes for rare warnings

2016-01-28 Thread Arnd Bergmann
Hi Felipe,

This set of patches addresses warnings I got in randconfig builds,
in the USB drivers. The first three patches are for the pxa25x
UDC driver and are a larger scale cleanup triggered by finding
the initial bug. The other four are relatively simple but still
need to be reviewed properly, as I have done only compile-time
testing. After these patches, I get no other warnings for USB
drivers at the moment.

Arnd Bergmann (7):
  usb: gadget: pxa25x_udc: move register definitions from arch
  usb: gadget: pxa25x_udc cleanup
  usb: gadget: pxa25x_udc: use readl/writel for mmio
  usb: fsl: drop USB_FSL_MPH_DR_OF Kconfig symbol
  usb: isp1301-omap: mark power_up as __maybe_unused
  usb: musb: use %pad format string from dma_addr_t
  usb: musb/ux500: remove duplicate check for dma_is_compatible

 arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h | 198 -
 arch/arm/mach-pxa/include/mach/pxa25x-udc.h | 163 
 drivers/usb/Makefile|   2 +-
 drivers/usb/gadget/udc/Kconfig  |   1 -
 drivers/usb/gadget/udc/pxa25x_udc.c | 530 +---
 drivers/usb/gadget/udc/pxa25x_udc.h |  11 +-
 drivers/usb/host/Kconfig|   4 -
 drivers/usb/host/Makefile   |   3 +-
 drivers/usb/musb/musbhsdma.c|   8 +-
 drivers/usb/musb/tusb6010_omap.c|   4 +-
 drivers/usb/musb/ux500_dma.c|   3 -
 drivers/usb/phy/phy-isp1301-omap.c  |   2 +-
 12 files changed, 400 insertions(+), 529 deletions(-)

-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/7] usb: gadget: pxa25x_udc: move register definitions from arch

2016-01-28 Thread Arnd Bergmann
ixp4xx and pxa25x both use this driver and provide a slightly
different set of register definitions for it. Aside from that,
the definition in the ixp4xx-regs.h header conflicts with the
on in the pxa27x device driver when compile-testing that:

In file included from ../drivers/usb/gadget/udc/pxa27x_udc.c:37:0:
../drivers/usb/gadget/udc/pxa27x_udc.h:26:0: warning: "UDCCR" redefined
 #define UDCCR  0x  /* UDC Control Register */
 ^
In file included from ../arch/arm/mach-ixp4xx/include/mach/hardware.h:27:0,
 from ../arch/arm/mach-ixp4xx/include/mach/io.h:18,
 from ../arch/arm/include/asm/io.h:194,
 from ../include/linux/io.h:25,
 from ../include/linux/irq.h:24,
 from ../drivers/usb/gadget/udc/pxa27x_udc.c:23:
../arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h:415:0: note: this is the 
location of the previous definition
 #define UDCCR  IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x)

This addresses both issues by moving all the definitions into the
pxa25x_udc driver itself. It turns out the only difference between
them was 'UDCCS_IO_ROF', and that could well be a mistake when it
was incorrectly copied from pxa25x to ixp4xx.

Signed-off-by: Arnd Bergmann 
---
 arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h | 198 
 arch/arm/mach-pxa/include/mach/pxa25x-udc.h | 163 ---
 drivers/usb/gadget/udc/pxa25x_udc.c | 161 ++-
 3 files changed, 155 insertions(+), 367 deletions(-)

diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h 
b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
index c5bae9c035d5..b7ddd27419c2 100644
--- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -395,204 +395,6 @@
 #define CRP_AD_CBE_BESL 20
 #define CRP_AD_CBE_WRITE   0x0001
 
-
-/*
- * USB Device Controller
- *
- * These are used by the USB gadget driver, so they don't follow the
- * IXP4XX_ naming convetions.
- *
- */
-# define IXP4XX_USB_REG(x)   (*((volatile u32 *)(x)))
-
-/* UDC Undocumented - Reserved1 */
-#define UDC_RES1   IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0004)  
-/* UDC Undocumented - Reserved2 */
-#define UDC_RES2   IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0008)  
-/* UDC Undocumented - Reserved3 */
-#define UDC_RES3   IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x000C)  
-/* UDC Control Register */
-#define UDCCR  IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x)  
-/* UDC Endpoint 0 Control/Status Register */
-#define UDCCS0 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0010)  
-/* UDC Endpoint 1 (IN) Control/Status Register */
-#define UDCCS1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0014)  
-/* UDC Endpoint 2 (OUT) Control/Status Register */
-#define UDCCS2 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0018)  
-/* UDC Endpoint 3 (IN) Control/Status Register */
-#define UDCCS3 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x001C)  
-/* UDC Endpoint 4 (OUT) Control/Status Register */
-#define UDCCS4 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0020)  
-/* UDC Endpoint 5 (Interrupt) Control/Status Register */
-#define UDCCS5 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0024)  
-/* UDC Endpoint 6 (IN) Control/Status Register */
-#define UDCCS6 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0028)  
-/* UDC Endpoint 7 (OUT) Control/Status Register */
-#define UDCCS7 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x002C)  
-/* UDC Endpoint 8 (IN) Control/Status Register */
-#define UDCCS8 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0030)  
-/* UDC Endpoint 9 (OUT) Control/Status Register */
-#define UDCCS9 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0034)  
-/* UDC Endpoint 10 (Interrupt) Control/Status Register */
-#define UDCCS10IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0038)  
-/* UDC Endpoint 11 (IN) Control/Status Register */
-#define UDCCS11IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x003C)  
-/* UDC Endpoint 12 (OUT) Control/Status Register */
-#define UDCCS12IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0040)  
-/* UDC Endpoint 13 (IN) Control/Status Register */
-#define UDCCS13IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0044)  
-/* UDC Endpoint 14 (OUT) Control/Status Register */
-#define UDCCS14IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0048)  
-/* UDC Endpoint 15 (Interrupt) Control/Status Register */
-#define UDCCS15IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x004C)  
-/* UDC Frame Number Register High */
-#define UFNRH  IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0060)  
-/* UDC Frame Number Register Low */
-#define UFNRL  IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0064)  
-/* UDC Byte Count Reg 2 */
-#define UBCR2  IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0068)  
-/* UDC Byte Count Reg 4 */
-#define UBCR4  IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x006c)  
-/* UDC Byte Count Reg 7 */

我的个人主页是

2016-01-28 Thread 我的个人主页是
你的老朋友邀你来Q群:343257759


[PATCH 7/7] usb: musb/ux500: remove duplicate check for dma_is_compatible

2016-01-28 Thread Arnd Bergmann
When dma_addr_t is 64-bit, we get a warning about an invalid cast
in the call to ux500_dma_is_compatible() from ux500_dma_channel_program():

drivers/usb/musb/ux500_dma.c: In function 'ux500_dma_channel_program':
drivers/usb/musb/ux500_dma.c:210:51: error: cast to pointer from integer of 
different size [-Werror=int-to-pointer-cast]
  if (!ux500_dma_is_compatible(channel, packet_sz, (void *)dma_addr, len))

The problem is that ux500_dma_is_compatible() is called from the
main musb driver on the virtual address, but here we pass in a
DMA address, so the types are fundamentally different but it works
because the function only checks the alignment of the buffer and
that is the same.

We could work around this by adding another cast, but I have checked
that the buffer we get passed here is already checked before it
gets mapped, so the second check seems completely unnecessary
and removing it must be the cleanest solution.

Signed-off-by: Arnd Bergmann 
---
 drivers/usb/musb/ux500_dma.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c
index d0b6a1cd7f62..c92a295049ad 100644
--- a/drivers/usb/musb/ux500_dma.c
+++ b/drivers/usb/musb/ux500_dma.c
@@ -207,9 +207,6 @@ static int ux500_dma_channel_program(struct dma_channel 
*channel,
BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
channel->status == MUSB_DMA_STATUS_BUSY);
 
-   if (!ux500_dma_is_compatible(channel, packet_sz, (void *)dma_addr, len))
-   return false;
-
channel->status = MUSB_DMA_STATUS_BUSY;
channel->actual_len = 0;
ret = ux500_configure_channel(channel, packet_sz, mode, dma_addr, len);
-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 6/7] usb: musb: use %pad format string from dma_addr_t

2016-01-28 Thread Arnd Bergmann
The musb driver prints DMA addresses in a few places, using the
0x%x format string. This is wrong on 64-bit architectures (which
need %lx) and 32-bit ARM with CONFIG_LPAE set (which needs
%llx), otherwise we print the wrong data, as gcc warns:

musb/musbhsdma.c: In function 'configure_channel':
musb/musbhsdma.c:120:53: error: format '%x' expects argument of type 'unsigned 
int', but argument 6 has type 'dma_addr_t {aka long long unsigned int}' 
[-Werror=format=]
  dev_dbg(musb->controller, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
musb/musbhsdma.c: In function 'dma_channel_program':
musb/musbhsdma.c:155:53: error: format '%x' expects argument of type 'unsigned 
int', but argument 7 has type 'dma_addr_t {aka long long unsigned int}' 
[-Werror=format=]
  dev_dbg(musb->controller, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode 
%d\n",
musb/tusb6010_omap.c: In function 'tusb_omap_dma_program':
musb/tusb6010_omap.c:313:53: error: format '%x' expects argument of type 
'unsigned int', but argument 7 has type 'dma_addr_t {aka long long unsigned 
int}' [-Werror=format=]
  dev_dbg(musb->controller, "ep%i %s dma ch%i dma: %08x len: %u(%u) packet_sz: 
%i(%i)\n",

This uses the %pad format string, which prints a dma_addr_t that
gets passed by reference, which works for all combinations.

Signed-off-by: Arnd Bergmann 
---
 drivers/usb/musb/musbhsdma.c | 8 
 drivers/usb/musb/tusb6010_omap.c | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 7539c3188ffc..8abfe4ec62fb 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -117,8 +117,8 @@ static void configure_channel(struct dma_channel *channel,
u8 bchannel = musb_channel->idx;
u16 csr = 0;
 
-   dev_dbg(musb->controller, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
-   channel, packet_sz, dma_addr, len, mode);
+   dev_dbg(musb->controller, "%p, pkt_sz %d, addr %pad, len %d, mode %d\n",
+   channel, packet_sz, _addr, len, mode);
 
if (mode) {
csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
@@ -152,10 +152,10 @@ static int dma_channel_program(struct dma_channel 
*channel,
struct musb_dma_controller *controller = musb_channel->controller;
struct musb *musb = controller->private_data;
 
-   dev_dbg(musb->controller, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, 
mode %d\n",
+   dev_dbg(musb->controller, "ep%d-%s pkt_sz %d, dma_addr %pad length %d, 
mode %d\n",
musb_channel->epnum,
musb_channel->transmit ? "Tx" : "Rx",
-   packet_sz, dma_addr, len, mode);
+   packet_sz, _addr, len, mode);
 
BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
channel->status == MUSB_DMA_STATUS_BUSY);
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 4c82077da475..e6959ccb4453 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -310,9 +310,9 @@ static int tusb_omap_dma_program(struct dma_channel 
*channel, u16 packet_sz,
 
dma_params.frame_count  = chdat->transfer_len / 32; /* Burst sz frame */
 
-   dev_dbg(musb->controller, "ep%i %s dma ch%i dma: %08x len: %u(%u) 
packet_sz: %i(%i)\n",
+   dev_dbg(musb->controller, "ep%i %s dma ch%i dma: %pad len: %u(%u) 
packet_sz: %i(%i)\n",
chdat->epnum, chdat->tx ? "tx" : "rx",
-   ch, dma_addr, chdat->transfer_len, len,
+   ch, _addr, chdat->transfer_len, len,
chdat->transfer_packet_sz, packet_sz);
 
/*
-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/7] usb: isp1301-omap: mark power_up as __maybe_unused

2016-01-28 Thread Arnd Bergmann
The power_up function is used for otg or udc mode, but nost when
the driver is only configured for host mode:

drivers/usb/phy/phy-isp1301-omap.c:261:13: error: 'power_up' defined but not 
used [-Werror=unused-function]

This marks the function __maybe_unused to avoid the warning and
silently drop the definition when it is unused.

Signed-off-by: Arnd Bergmann 
---
 drivers/usb/phy/phy-isp1301-omap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/phy/phy-isp1301-omap.c 
b/drivers/usb/phy/phy-isp1301-omap.c
index 3af263cc0caa..8d111ec653e4 100644
--- a/drivers/usb/phy/phy-isp1301-omap.c
+++ b/drivers/usb/phy/phy-isp1301-omap.c
@@ -258,7 +258,7 @@ static void power_down(struct isp1301 *isp)
isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0);
 }
 
-static void power_up(struct isp1301 *isp)
+static void __maybe_unused power_up(struct isp1301 *isp)
 {
// isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN);
isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND);
-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/7] usb: fsl: drop USB_FSL_MPH_DR_OF Kconfig symbol

2016-01-28 Thread Arnd Bergmann
The USB_FSL_MPH_DR_OF symbol is used to ensure the code that interprets
the DR device node is built whenever one of the two drivers (EHCI or
UDC) for the platform is enabled. However, if CONFIG_USB is disabled
and we only support gadget mode, this causes a Kconfig warning:

warning: (USB_FSL_USB2) selects USB_FSL_MPH_DR_OF which has unmet direct 
dependencies (USB_SUPPORT && USB)

We can avoid this warning by simply no longer using the symbol,
and making sure we enter the drivers/usb/host/ directory when
the UDC driver is enabled that needs the file, and then we use
Makefile syntax to ensure the file is built-in if needed.

There is currently a dependency on CONFIG_OF, but this is redundant,
as we already know that this is set unconditionally for the platforms
that use this driver.

Signed-off-by: Arnd Bergmann 
---
 drivers/usb/Makefile   | 2 +-
 drivers/usb/gadget/udc/Kconfig | 1 -
 drivers/usb/host/Kconfig   | 4 
 drivers/usb/host/Makefile  | 3 ++-
 4 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index d5c57f1e98fd..dca78565eb55 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -26,7 +26,7 @@ obj-$(CONFIG_USB_U132_HCD)+= host/
 obj-$(CONFIG_USB_R8A66597_HCD) += host/
 obj-$(CONFIG_USB_HWA_HCD)  += host/
 obj-$(CONFIG_USB_IMX21_HCD)+= host/
-obj-$(CONFIG_USB_FSL_MPH_DR_OF)+= host/
+obj-$(CONFIG_USB_FSL_USB2) += host/
 obj-$(CONFIG_USB_FOTG210_HCD)  += host/
 obj-$(CONFIG_USB_MAX3421_HCD)  += host/
 
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
index 753c29bd11ad..d38cd69b470e 100644
--- a/drivers/usb/gadget/udc/Kconfig
+++ b/drivers/usb/gadget/udc/Kconfig
@@ -74,7 +74,6 @@ config USB_BCM63XX_UDC
 config USB_FSL_USB2
tristate "Freescale Highspeed USB DR Peripheral Controller"
depends on FSL_SOC || ARCH_MXC
-   select USB_FSL_MPH_DR_OF if OF
help
   Some of Freescale PowerPC and i.MX processors have a High Speed
   Dual-Role(DR) USB controller, which supports device mode.
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 1f117c360ebb..2f73cc5fab71 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -121,9 +121,6 @@ config USB_EHCI_TT_NEWSCHED
 
  If unsure, say Y.
 
-config USB_FSL_MPH_DR_OF
-   tristate
-
 if USB_EHCI_HCD
 
 config USB_EHCI_PCI
@@ -156,7 +153,6 @@ config USB_EHCI_FSL
tristate "Support for Freescale PPC on-chip EHCI USB controller"
depends on FSL_SOC
select USB_EHCI_ROOT_HUB_TT
-   select USB_FSL_MPH_DR_OF if OF
---help---
  Variation of ARC USB block used in some Freescale chips.
 
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 65a06b4382bf..a9ddd3c9ec94 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -74,7 +74,8 @@ obj-$(CONFIG_USB_U132_HCD)+= u132-hcd.o
 obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
 obj-$(CONFIG_USB_HWA_HCD)  += hwa-hc.o
 obj-$(CONFIG_USB_IMX21_HCD)+= imx21-hcd.o
-obj-$(CONFIG_USB_FSL_MPH_DR_OF)+= fsl-mph-dr-of.o
+obj-$(CONFIG_USB_FSL_USB2) += fsl-mph-dr-of.o
+obj-$(CONFIG_USB_EHCI_FSL) += fsl-mph-dr-of.o
 obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
 obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o
 obj-$(CONFIG_USB_HCD_SSB)  += ssb-hcd.o
-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/7] usb: gadget: pxa25x_udc: use readl/writel for mmio

2016-01-28 Thread Arnd Bergmann
This converts the pxa25x udc driver to use readl/writel as normal
driver should do, rather than dereferencing __iomem pointers
themselves.

Based on the earlier preparation work, we can now also pass
the register start in the device pointer so we no longer need
the global variable.

The unclear part here is for IXP4xx, which supports both big-endian
and little-endian configurations. So far, the driver has done
no byteswap in either case. I suspect that is wrong and it would
actually need to swap in one or the other case, but I don't know
which. It's also possible that there is some magic setting in
the chip that makes the endianess of the MMIO register match the
CPU, and in that case, the code actually does the right thing
for all configurations, both before and after this patch.

Signed-off-by: Arnd Bergmann 
---
 drivers/usb/gadget/udc/pxa25x_udc.c | 61 -
 drivers/usb/gadget/udc/pxa25x_udc.h |  1 +
 2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c 
b/drivers/usb/gadget/udc/pxa25x_udc.c
index 5db429f3cfb2..6d3acbf3b311 100644
--- a/drivers/usb/gadget/udc/pxa25x_udc.c
+++ b/drivers/usb/gadget/udc/pxa25x_udc.c
@@ -52,9 +52,6 @@
 #include 
 #endif
 
-static void __iomem *pxa25x_udc_reg_base;
-#define __UDC_REG(x) (*((volatile u32 *)(pxa25x_udc_reg_base + (x
-
 #define UDCCR   0x /* UDC Control Register */
 #define UDC_RES1 0x0004 /* UDC Undocumented - Reserved1 */
 #define UDC_RES2 0x0008 /* UDC Undocumented - Reserved2 */
@@ -292,16 +289,36 @@ static void pullup_on(void)
mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
 }
 
-static inline void udc_set_reg(struct pxa25x_udc *dev, u32 reg, u32 uicr)
+#if defined(CONFIG_ARCH_IXP4XX) && defined(CONFIG_CPU_BIG_ENDIAN)
+/*
+ * not sure if this is the correct behavior on ixp4xx in both
+ * bit-endian and little-endian modes, but it's what the driver
+ * has always done using direct pointer dereferences:
+ * We assume that there is a byteswap done in hardware at the
+ * MMIO register that matches what the CPU setting is, so we
+ * never swap in software.
+ */
+static inline void udc_set_reg(struct pxa25x_udc *dev, u32 reg, u32 val)
 {
-   __UDC_REG(reg) = uicr;
+   iowrite32be(val, dev->regs + reg);
 }
 
 static inline u32 udc_get_reg(struct pxa25x_udc *dev, u32 reg)
 {
-   return __UDC_REG(reg);
+   return ioread32be(dev->regs + reg);
+}
+#else
+static inline void udc_set_reg(struct pxa25x_udc *dev, u32 reg, u32 val)
+{
+   writel(val, dev->regs + reg);
 }
 
+static inline u32 udc_get_reg(struct pxa25x_udc *dev, u32 reg)
+{
+   return readl(dev->regs + reg);
+}
+#endif
+
 static void pio_irq_enable(struct pxa25x_ep *ep)
 {
u32 bEndpointAddress = ep->bEndpointAddress & 0xf;
@@ -337,59 +354,59 @@ static void pio_irq_disable(struct pxa25x_ep *ep)
 
 static inline void udc_set_mask_UDCCR(struct pxa25x_udc *dev, int mask)
 {
-   u32 udccr = __UDC_REG(UDCCR);
+   u32 udccr = udc_get_reg(dev, UDCCR);
 
-   __UDC_REG(UDCCR) = (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS);
+   udc_set_reg(dev, (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS), 
UDCCR);
 }
 
 static inline void udc_clear_mask_UDCCR(struct pxa25x_udc *dev, int mask)
 {
-   u32 udccr = __UDC_REG(UDCCR);
+   u32 udccr = udc_get_reg(dev, UDCCR);
 
-   __UDC_REG(UDCCR) = (udccr & UDCCR_MASK_BITS) & ~(mask & 
UDCCR_MASK_BITS);
+   udc_set_reg(dev, (udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS), 
UDCCR);
 }
 
 static inline void udc_ack_int_UDCCR(struct pxa25x_udc *dev, int mask)
 {
/* udccr contains the bits we dont want to change */
-   u32 udccr = __UDC_REG(UDCCR) & UDCCR_MASK_BITS;
+   u32 udccr = udc_get_reg(dev, UDCCR) & UDCCR_MASK_BITS;
 
-   __UDC_REG(UDCCR) = udccr | (mask & ~UDCCR_MASK_BITS);
+   udc_set_reg(dev, udccr | (mask & ~UDCCR_MASK_BITS), UDCCR);
 }
 
 static inline u32 udc_ep_get_UDCCS(struct pxa25x_ep *ep)
 {
-   return __UDC_REG(ep->regoff_udccs);
+   return udc_get_reg(ep->dev, ep->regoff_udccs);
 }
 
 static inline void udc_ep_set_UDCCS(struct pxa25x_ep *ep, u32 data)
 {
-   __UDC_REG(ep->regoff_udccs) = data;
+   udc_set_reg(ep->dev, data, ep->regoff_udccs);
 }
 
 static inline u32 udc_ep0_get_UDCCS(struct pxa25x_udc *dev)
 {
-   return __UDC_REG(UDCCS0);
+   return udc_get_reg(dev, UDCCS0);
 }
 
 static inline void udc_ep0_set_UDCCS(struct pxa25x_udc *dev, u32 data)
 {
-   __UDC_REG(UDCCS0) = data;
+   udc_set_reg(dev, data, UDCCS0);
 }
 
 static inline u32 udc_ep_get_UDDR(struct pxa25x_ep *ep)
 {
-   return __UDC_REG(ep->regoff_uddr);
+   return udc_get_reg(ep->dev, ep->regoff_uddr);
 }
 
 static inline void udc_ep_set_UDDR(struct pxa25x_ep *ep, u32 data)
 {
-   __UDC_REG(ep->regoff_uddr) = data;
+   udc_set_reg(ep->dev, data, ep->regoff_uddr);
 }
 
 static inline u32 udc_ep_get_UBCR(struct pxa25x_ep *ep)
 {
-   

[PATCH 2/7] usb: gadget: pxa25x_udc cleanup

2016-01-28 Thread Arnd Bergmann
This removes the dependency on the mach/hardware.h header file
from the pxa25x_udc driver after the register definitions were
already unified in the previous patch.

Following the model of pxa27x_udc (and basically all other drivers
in the kernel), we define the register numbers as offsets from
the register base address and use accessor functions to read/write
them.

For the moment, this still leaves the direct pointer dereference
in place, instead of using readl/writel, so this patch should
not be changing the behavior of the driver, other than using
ioremap() on the platform resource to replace the hardcoded
virtual address pointers.

Signed-off-by: Arnd Bergmann 
---
 drivers/usb/gadget/udc/pxa25x_udc.c | 468 +---
 drivers/usb/gadget/udc/pxa25x_udc.h |  10 +-
 2 files changed, 275 insertions(+), 203 deletions(-)

diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c 
b/drivers/usb/gadget/udc/pxa25x_udc.c
index 26537f50374d..5db429f3cfb2 100644
--- a/drivers/usb/gadget/udc/pxa25x_udc.c
+++ b/drivers/usb/gadget/udc/pxa25x_udc.c
@@ -48,70 +48,63 @@
 #include 
 #include 
 
-#include 
-
 #ifdef CONFIG_ARCH_LUBBOCK
 #include 
 #endif
 
-#ifdef CONFIG_ARCH_IXP4XX
-#define __UDC_REG(x) (*((volatile u32 *)(IXP4XX_USB_BASE_VIRT + (x
-#endif
-
-#ifdef CONFIG_ARCH_PXA
-#define __UDC_REG(x) __REG(0x4060 + (x))
-#endif
-
-#define UDCCR  __UDC_REG(0x)  /* UDC Control Register */
-#define UDC_RES1   __UDC_REG(0x0004)  /* UDC Undocumented - Reserved1 */
-#define UDC_RES2   __UDC_REG(0x0008)  /* UDC Undocumented - Reserved2 */
-#define UDC_RES3   __UDC_REG(0x000C)  /* UDC Undocumented - Reserved3 */
-#define UDCCS0 __UDC_REG(0x0010)  /* UDC Endpoint 0 Control/Status 
Register */
-#define UDCCS1 __UDC_REG(0x0014)  /* UDC Endpoint 1 (IN) 
Control/Status Register */
-#define UDCCS2 __UDC_REG(0x0018)  /* UDC Endpoint 2 (OUT) 
Control/Status Register */
-#define UDCCS3 __UDC_REG(0x001C)  /* UDC Endpoint 3 (IN) 
Control/Status Register */
-#define UDCCS4 __UDC_REG(0x0020)  /* UDC Endpoint 4 (OUT) 
Control/Status Register */
-#define UDCCS5 __UDC_REG(0x0024)  /* UDC Endpoint 5 (Interrupt) 
Control/Status Register */
-#define UDCCS6 __UDC_REG(0x0028)  /* UDC Endpoint 6 (IN) 
Control/Status Register */
-#define UDCCS7 __UDC_REG(0x002C)  /* UDC Endpoint 7 (OUT) 
Control/Status Register */
-#define UDCCS8 __UDC_REG(0x0030)  /* UDC Endpoint 8 (IN) 
Control/Status Register */
-#define UDCCS9 __UDC_REG(0x0034)  /* UDC Endpoint 9 (OUT) 
Control/Status Register */
-#define UDCCS10__UDC_REG(0x0038)  /* UDC Endpoint 10 
(Interrupt) Control/Status Register */
-#define UDCCS11__UDC_REG(0x003C)  /* UDC Endpoint 11 (IN) 
Control/Status Register */
-#define UDCCS12__UDC_REG(0x0040)  /* UDC Endpoint 12 (OUT) 
Control/Status Register */
-#define UDCCS13__UDC_REG(0x0044)  /* UDC Endpoint 13 (IN) 
Control/Status Register */
-#define UDCCS14__UDC_REG(0x0048)  /* UDC Endpoint 14 (OUT) 
Control/Status Register */
-#define UDCCS15__UDC_REG(0x004C)  /* UDC Endpoint 15 
(Interrupt) Control/Status Register */
-#define UFNRH  __UDC_REG(0x0060)  /* UDC Frame Number Register High */
-#define UFNRL  __UDC_REG(0x0064)  /* UDC Frame Number Register Low */
-#define UBCR2  __UDC_REG(0x0068)  /* UDC Byte Count Reg 2 */
-#define UBCR4  __UDC_REG(0x006c)  /* UDC Byte Count Reg 4 */
-#define UBCR7  __UDC_REG(0x0070)  /* UDC Byte Count Reg 7 */
-#define UBCR9  __UDC_REG(0x0074)  /* UDC Byte Count Reg 9 */
-#define UBCR12 __UDC_REG(0x0078)  /* UDC Byte Count Reg 12 */
-#define UBCR14 __UDC_REG(0x007c)  /* UDC Byte Count Reg 14 */
-#define UDDR0  __UDC_REG(0x0080)  /* UDC Endpoint 0 Data Register */
-#define UDDR1  __UDC_REG(0x0100)  /* UDC Endpoint 1 Data Register */
-#define UDDR2  __UDC_REG(0x0180)  /* UDC Endpoint 2 Data Register */
-#define UDDR3  __UDC_REG(0x0200)  /* UDC Endpoint 3 Data Register */
-#define UDDR4  __UDC_REG(0x0400)  /* UDC Endpoint 4 Data Register */
-#define UDDR5  __UDC_REG(0x00A0)  /* UDC Endpoint 5 Data Register */
-#define UDDR6  __UDC_REG(0x0600)  /* UDC Endpoint 6 Data Register */
-#define UDDR7  __UDC_REG(0x0680)  /* UDC Endpoint 7 Data Register */
-#define UDDR8  __UDC_REG(0x0700)  /* UDC Endpoint 8 Data Register */
-#define UDDR9  __UDC_REG(0x0900)  /* UDC Endpoint 9 Data Register */
-#define UDDR10 __UDC_REG(0x00C0)  /* UDC Endpoint 10 Data Register */
-#define UDDR11 __UDC_REG(0x0B00)  /* UDC Endpoint 11 Data Register */
-#define UDDR12 __UDC_REG(0x0B80)  /* UDC Endpoint 12 Data Register */
-#define UDDR13 __UDC_REG(0x0C00)  /* UDC Endpoint 13 Data Register */
-#define UDDR14 __UDC_REG(0x0E00)  /* UDC 

Re: [GIT PULL] USB-serial fixes for v4.5-rc2

2016-01-28 Thread Greg Kroah-Hartman
On Thu, Jan 28, 2016 at 04:12:03PM +0100, Johan Hovold wrote:
> Hi Greg,
> 
> Here's a first set of fixes for 4.5-rc.
> 
> Thanks,
> Johan
> 
> 
> The following changes since commit 92e963f50fc74041b5e9e744c330dca48e04f08d:
> 
>   Linux 4.5-rc1 (2016-01-24 13:06:47 -0800)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git 
> tags/usb-serial-4.5-rc2

Pulled and pushed out, thanks.

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 04/21] usb: dwc2: host: Set host_perio_tx_fifo_size to 304 for rk3066

2016-01-28 Thread Doug Anderson
Kever,


On Wed, Jan 27, 2016 at 10:41 PM, Kever Yang  wrote:
> Hi Doug,
>
> We are in HOST mode, we only need to receive data from USB camera
> with RX FIFO, and no need to use TX FIFO for USB webcam, right? :)
>
> Any way, I think we need to NAK this patch after look into the design
> of dwc2 controller. Because all the dwc2 controller inside the Rockchip
> chips don't support the thresholding FIFO mode, in this case, there is
> no more transaction before a whole packet is send out and the dwc2 only
> care if the available FIFO is enough for next packet or not.
>
> So, the addition 48 words won't help to shorten the latency for data prepare
> in this case.

Ah ha!  I see where I messed up.  It wasn't lack of FIFO space that I
was running into, it was lack of queue space.  :-P  I had conflated
the two of them in my mind.  We still use the TX queue to transmit
small packets so that we can receive our data...

OK, so it's pretty sane to assume that exhausting the periodic TX FIFO
isn't terribly common, I think.  Audio won't do it by itself and you
probably won't have more than one audio device.  I guess if you had a
video _output_ device hooked over USB then it could possible exhaust
things.  ...but I think dwc2 still has a ways to do before I'd suggest
anyone hooking that up.  :-P  At some point in time you could imagine
the driver being more dynamic.

OK, so the non periodic FIFO it is, then.

-Doug
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 04/21] usb: dwc2: host: Set host_perio_tx_fifo_size to 304 for rk3066

2016-01-28 Thread Doug Anderson
Hi,

On Thu, Jan 28, 2016 at 10:16 AM, Doug Anderson  wrote:
> Kever,
>
>
> On Wed, Jan 27, 2016 at 10:41 PM, Kever Yang  
> wrote:
>> Hi Doug,
>>
>> We are in HOST mode, we only need to receive data from USB camera
>> with RX FIFO, and no need to use TX FIFO for USB webcam, right? :)
>>
>> Any way, I think we need to NAK this patch after look into the design
>> of dwc2 controller. Because all the dwc2 controller inside the Rockchip
>> chips don't support the thresholding FIFO mode, in this case, there is
>> no more transaction before a whole packet is send out and the dwc2 only
>> care if the available FIFO is enough for next packet or not.
>>
>> So, the addition 48 words won't help to shorten the latency for data prepare
>> in this case.
>
> Ah ha!  I see where I messed up.  It wasn't lack of FIFO space that I
> was running into, it was lack of queue space.  :-P  I had conflated
> the two of them in my mind.  We still use the TX queue to transmit
> small packets so that we can receive our data...
>
> OK, so it's pretty sane to assume that exhausting the periodic TX FIFO
> isn't terribly common, I think.  Audio won't do it by itself and you
> probably won't have more than one audio device.  I guess if you had a
> video _output_ device hooked over USB then it could possible exhaust
> things.  ...but I think dwc2 still has a ways to do before I'd suggest
> anyone hooking that up.  :-P  At some point in time you could imagine
> the driver being more dynamic.
>
> OK, so the non periodic FIFO it is, then.

Actually, in my simple tests adding it to the non periodic FIFO didn't
help at all.  I'll just drop this patch.

-Doug
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 05/21] usb: dwc2: host: Avoid use of chan->qh after qh freed

2016-01-28 Thread Doug Anderson
Hi,

On Wed, Jan 27, 2016 at 7:25 PM, Kever Yang  wrote:
> Hi Doug,
>
> The NULL pointer bug is one of the most frequent issue we met
> during hot plug stress test, thanks for this bug fix.
>
> Reviewed-by: Kever Yang 
>
> Thanks,
> - Kever

Thanks for your review.  I think I actually found one more place where
I needed to clean up the channel->qh, so I'll include that in my next
version.  I'll plan to keep your reviewed-by.  Please yell if you want
it removed.

-Doug
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] USB: option: add support for SIM7100E

2016-01-28 Thread Andrey Skvortsov
$ lsusb:
Bus 001 Device 101: ID 1e0e:9001 Qualcomm / Option

$ usb-devices:
T:  Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=101 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  2
P:  Vendor=1e0e ProdID=9001 Rev= 2.32
S:  Manufacturer=SimTech, Incorporated
S:  Product=SimTech, Incorporated
S:  SerialNumber=0123456789ABCDEF
C:* #Ifs= 7 Cfg#= 1 Atr=80 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
I:* If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)

The last interface (6) is used for Android Composite ADB interface.

Serial port layout:
0: QCDM/DIAG
1: NMEA
2: AT
3: AT/PPP
4: audio

Signed-off-by: Andrey Skvortsov 
---
 v2: respin v1 against usb-linus branch of 
git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git
 move SIM7100E product id to ALINK entries
 move SIM7100E usb_device_id initialization to ALINK initializations
 
 drivers/usb/serial/option.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index db86e51..1a22950 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -317,6 +317,7 @@ static void option_instat_callback(struct urb *urb);
 #define ALINK_VENDOR_ID0x1e0e
 #define ALINK_PRODUCT_PH3000x9100
 #define ALINK_PRODUCT_3GU  0x9200
+#define SIMCOM_PRODUCT_SIM7100E0x9001 /* Yes, 
ALINK_VENDOR_ID */
 
 /* ALCATEL PRODUCTS */
 #define ALCATEL_VENDOR_ID  0x1bbb
@@ -627,6 +628,10 @@ static const struct option_blacklist_info 
telit_le922_blacklist_usbcfg3 = {
.reserved = BIT(1) | BIT(2) | BIT(3),
 };
 
+static const struct option_blacklist_info simcom_sim7100e_blacklist = {
+   .reserved = BIT(5) | BIT(6),
+};
+
 static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -1645,6 +1650,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
{ USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) },
{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 
0xff, 0xff, 0xff) },
+   { USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E),
+ .driver_info = (kernel_ulong_t)_sim7100e_blacklist },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
  .driver_info = (kernel_ulong_t)_x200_blacklist
},
-- 
2.7.0.rc3

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] HID: quirks: Add no_init_reports for AKAI midi controller

2016-01-28 Thread Oliver Neukum
On Wed, 2016-01-27 at 22:31 +0100, Jiri Kosina wrote:
> On Wed, 27 Jan 2016, Stafford Horne wrote:
> 
> > The midi controller times-out while initializing reports, this
> > causes boot to take an extra 10 seconds. The device descriptor
> > advertises that it has an internal HID device but seems to not
> > actually do anything useful.
> > 
> > Signed-off-by: Stafford Horne 
> > ---
> >  drivers/hid/hid-ids.h   | 3 +++
> >  drivers/hid/usbhid/hid-quirks.c | 1 +
> >  2 files changed, 4 insertions(+)
> > 
> > diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> > index b6ff6e7..3dfb166 100644
> > --- a/drivers/hid/hid-ids.h
> > +++ b/drivers/hid/hid-ids.h
> > @@ -61,6 +61,9 @@
> >  #define USB_VENDOR_ID_AIREN0x1a2c
> >  #define USB_DEVICE_ID_AIREN_SLIMPLUS   0x0002
> >  
> > +#define USB_VENDOR_ID_AKAI  0x2011
> > +#define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715
> > +
> >  #define USB_VENDOR_ID_ALCOR0x058f
> >  #define USB_DEVICE_ID_ALCOR_USBRS232   0x9720
> >  
> > diff --git a/drivers/hid/usbhid/hid-quirks.c 
> > b/drivers/hid/usbhid/hid-quirks.c
> > index 7dd0953..055e740 100644
> > --- a/drivers/hid/usbhid/hid-quirks.c
> > +++ b/drivers/hid/usbhid/hid-quirks.c
> > @@ -55,6 +55,7 @@ static const struct hid_blacklist {
> > { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, 
> > HID_QUIRK_MULTI_INPUT },
> >  
> > { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET },
> > +   { USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, 
> > HID_QUIRK_NO_INIT_REPORTS },
> 
> If the (proclaimed) HID device is completely silent, wouldn't 
> HID_QUIRK_IGNORE be more appropriate?

If it really is impossible to use the device.
That quirk would preclude any use you are not aware of with almost
no added benefit. I would take the patch as is.

Regards
Oliver



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 03/21] usb: dwc2: host: Set host_rx_fifo_size to 528 for rk3066

2016-01-28 Thread Kever Yang

Hi Doug,

On 01/28/2016 03:44 AM, Doug Anderson wrote:

If it's all the same to you, I'll probably change it back to 525 and
then increase the periodic FIFO size by 3 DWORDS in the next patch.
12 bytes may not be much, but might as well make use of them to
improve performance / compatibility?

Presumably you're also OK with the next patch in the series: ("usb:
dwc2: host: Set host_perio_tx_fifo_size to 304 for rk3066")?

I'm OK for change in this patch, but I think we don't need next patch,
pls see the reply in another mail.

Thank,
- Kever

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7 0/5] usb: usbtmc: Add support for missing functions in USBTMC-USB488 spec

2016-01-28 Thread Clemens Ladisch
Dave Penkler wrote:
> Implement support for the USB488 defined READ_STATUS_BYTE ioctl (1/5)
> and SRQ notifications with fasync (2/5) and poll/select (3/5) in order
> to be able to synchronize with variable duration instrument
> operations.
>
> Add convenience ioctl to return all device capabilities (4/5)
>
> Add ioctls for other USB488 requests: REN_CONTROL, GOTO_LOCAL and
> LOCAL_LOCKOUT. (5/5)
> [...]
>  Testing:
> All functions tested ok on an USBTMC-USB488 compliant oscilloscope

How?  Did you extend the usbtmc_ioctl tool?


Regards,
Clemens
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] HID: quirks: Add no_init_reports for AKAI midi controller

2016-01-28 Thread Stafford Horne



On Thu, 28 Jan 2016, Oliver Neukum wrote:


On Wed, 2016-01-27 at 22:31 +0100, Jiri Kosina wrote:

On Wed, 27 Jan 2016, Stafford Horne wrote:


The midi controller times-out while initializing reports, this
causes boot to take an extra 10 seconds. The device descriptor
advertises that it has an internal HID device but seems to not
actually do anything useful.

Signed-off-by: Stafford Horne 
---
 drivers/hid/hid-ids.h   | 3 +++
 drivers/hid/usbhid/hid-quirks.c | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index b6ff6e7..3dfb166 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -61,6 +61,9 @@
 #define USB_VENDOR_ID_AIREN0x1a2c
 #define USB_DEVICE_ID_AIREN_SLIMPLUS   0x0002

+#define USB_VENDOR_ID_AKAI  0x2011
+#define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715
+
 #define USB_VENDOR_ID_ALCOR0x058f
 #define USB_DEVICE_ID_ALCOR_USBRS232   0x9720

diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 7dd0953..055e740 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -55,6 +55,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, 
HID_QUIRK_MULTI_INPUT },

{ USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET },
+   { USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, 
HID_QUIRK_NO_INIT_REPORTS },


If the (proclaimed) HID device is completely silent, wouldn't
HID_QUIRK_IGNORE be more appropriate?


If it really is impossible to use the device.
That quirk would preclude any use you are not aware of with almost
no added benefit. I would take the patch as is.


That may be right, after having a look at usbhid quirks, no device yet has 
HID_QUIRK_IGNORE.  Also, I have a feeling the HID enpoints might have some 
proprietary functionality.


The defined interface descriptors are 1 HID, 2 Audio Control Device, 3 Audio
MIDI streaming. I tried to write and read from the HID endpoints using 
hidraw with no luck. But someone else might figure it out.

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] usb: musb: ux500: Fix NULL pointer dereference at system PM

2016-01-28 Thread Linus Walleij
On Mon, Jan 25, 2016 at 1:01 PM, Ulf Hansson  wrote:

> The commit 7d32cdef5356 ("usb: musb: fail with error when no DMA
> controller set"), caused the core platform driver to correctly return an
> error code when fail probing.
>
> Unfurtante it also caused bug for a NULL pointer dereference, during
> system suspend for the ux500 driver. The reason is a lacking validation
> of the corresponding ->driver_data pointer, which won't be set when the
> musb core driver fails to probe (or haven't yet been probed).
>
> Fixes: 7d32cdef5356 ("usb: musb: fail with error when no DMA...")
> Signed-off-by: Ulf Hansson 

Acked-by: Linus Walleij 

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V8 1/1] usb:serial: Add Fintek F81532/534 driver

2016-01-28 Thread kbuild test robot
Hi Peter,

[auto build test ERROR on usb/usb-testing]
[also build test ERROR on v4.5-rc1 next-20160128]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improving the system]

url:
https://github.com/0day-ci/linux/commits/Peter-Hung/usb-serial-Add-Fintek-F81532-534-driver/20160128-153805
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git 
usb-testing
config: parisc-allmodconfig (attached as .config)
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=parisc 

All errors (new ones prefixed by >>):

   drivers/usb/serial/f81534.c: In function 'f81534_get_serial_info':
>> drivers/usb/serial/f81534.c:1559:2: error: implicit declaration of function 
>> 'copy_to_user' [-Werror=implicit-function-declaration]
 if (copy_to_user(retinfo, , sizeof(*retinfo)))
 ^
   cc1: some warnings being treated as errors

vim +/copy_to_user +1559 drivers/usb/serial/f81534.c

  1553  
  1554  tmp.type = PORT_16550A;
  1555  tmp.port = port->port_number;
  1556  tmp.line = port->minor;
  1557  tmp.baud_base = port_priv->current_baud_base;
  1558  
> 1559  if (copy_to_user(retinfo, , sizeof(*retinfo)))
  1560  return -EFAULT;
  1561  
  1562  return 0;

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: Binary data


Re: [PATCH 6/7] usb: musb: use %pad format string from dma_addr_t

2016-01-28 Thread Tony Lindgren
* Arnd Bergmann  [160128 08:26]:
> The musb driver prints DMA addresses in a few places, using the
> 0x%x format string. This is wrong on 64-bit architectures (which
> need %lx) and 32-bit ARM with CONFIG_LPAE set (which needs
> %llx), otherwise we print the wrong data, as gcc warns:
> 
> musb/musbhsdma.c: In function 'configure_channel':
> musb/musbhsdma.c:120:53: error: format '%x' expects argument of type 
> 'unsigned int', but argument 6 has type 'dma_addr_t {aka long long unsigned 
> int}' [-Werror=format=]
>   dev_dbg(musb->controller, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
> musb/musbhsdma.c: In function 'dma_channel_program':
> musb/musbhsdma.c:155:53: error: format '%x' expects argument of type 
> 'unsigned int', but argument 7 has type 'dma_addr_t {aka long long unsigned 
> int}' [-Werror=format=]
>   dev_dbg(musb->controller, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode 
> %d\n",
> musb/tusb6010_omap.c: In function 'tusb_omap_dma_program':
> musb/tusb6010_omap.c:313:53: error: format '%x' expects argument of type 
> 'unsigned int', but argument 7 has type 'dma_addr_t {aka long long unsigned 
> int}' [-Werror=format=]
>   dev_dbg(musb->controller, "ep%i %s dma ch%i dma: %08x len: %u(%u) 
> packet_sz: %i(%i)\n",
> 
> This uses the %pad format string, which prints a dma_addr_t that
> gets passed by reference, which works for all combinations.
> 
> Signed-off-by: Arnd Bergmann 

Looks good to me:

Acked-by: Tony Lindgren 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 20/22] usb: dwc2: host: Properly set even/odd frame

2016-01-28 Thread Douglas Anderson
When setting up ISO and INT transfers dwc2 needs to specify whether the
transfer is for an even or an odd frame (or microframe if the controller
is running in high speed mode).

The controller appears to use this as a simple way to figure out if a
transfer should happen right away (in the current microframe) or should
happen at the start of the next microframe.  Said another way:

- If you set "odd" and the current frame number is odd it appears that
  the controller will try to transfer right away.  Same thing if you set
  "even" and the current frame number is even.
- If the oddness you set and the oddness of the frame number are
  _different_, the transfer will be delayed until the frame number
  changes.

As I understand it, the above technique allows you to plan ahead of time
where possible by always working on the next frame.  ...but it still
allows you to properly respond immediately to things that happened in
the previous frame.

The old dwc2_hc_set_even_odd_frame() didn't really handle this concept.
It always looked at the frame number and setup the transfer to happen in
the next frame.  In some cases that meant that certain transactions
would be transferred in the wrong frame.

We'll try our best to set the even / odd to do the transfer in the
scheduled frame.  If that fails then we'll do an ugly "schedule ASAP".
We'll also modify the scheduler code to handle this and not try to
schedule a second transfer for the same frame.

Note that this change relies on the work to redo the microframe
scheduler.  It can work atop ("usb: dwc2: host: Manage frame nums better
in scheduler") but it works even better after ("usb: dwc2: host: Totally
redo the microframe scheduler").

With this change my stressful USB test (USB webcam + USB audio +
keyboards) has less audio crackling than before.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Properly set even/odd frame new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/core.c  | 92 +++-
 drivers/usb/dwc2/hcd_queue.c | 11 +-
 2 files changed, 100 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index a5db20f12ee4..c143f26bd9d9 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -1703,9 +1703,97 @@ static void dwc2_hc_set_even_odd_frame(struct dwc2_hsotg 
*hsotg,
 {
if (chan->ep_type == USB_ENDPOINT_XFER_INT ||
chan->ep_type == USB_ENDPOINT_XFER_ISOC) {
-   /* 1 if _next_ frame is odd, 0 if it's even */
-   if (!(dwc2_hcd_get_frame_number(hsotg) & 0x1))
+   int host_speed;
+   int xfer_ns;
+   int xfer_us;
+   int bytes_in_fifo;
+   u16 fifo_space;
+   u16 frame_number;
+   u16 wire_frame;
+
+   /*
+* Try to figure out if we're an even or odd frame. If we set
+* even and the current frame number is even the the transfer
+* will happen immediately.  Similar if both are odd. If one is
+* even and the other is odd then the transfer will happen when
+* the frame number ticks.
+*
+* There's a bit of a balancing act to get this right.
+* Sometimes we may want to send data in the current frame (AK
+* right away).  We might want to do this if the frame number
+* _just_ ticked, but we might also want to do this in order
+* to continue a split transaction that happened late in a
+* microframe (so we didn't know to queue the next transfer
+* until the frame number had ticked).  The problem is that we
+* need a lot of knowledge to know if there's actually still
+* time to send things or if it would be better to wait until
+* the next frame.
+*
+* We can look at how much time is left in the current frame
+* and make a guess about whether we'll have time to transfer.
+* We'll do that.
+*/
+
+   /* Get speed host is running at */
+   host_speed = (chan->speed != USB_SPEED_HIGH &&
+ !chan->do_split) ? chan->speed : USB_SPEED_HIGH;
+
+   /* See how many bytes are in the periodic FIFO right now */
+   fifo_space = (dwc2_readl(hsotg->regs + HPTXSTS) &
+ TXSTS_FSPCAVAIL_MASK) >> TXSTS_FSPCAVAIL_SHIFT;
+   bytes_in_fifo = sizeof(u32) *
+   (hsotg->core_params->host_perio_tx_fifo_size -
+fifo_space);
+
+

[PATCH v6 21/22] usb: dwc2: host: Totally redo the microframe scheduler

2016-01-28 Thread Douglas Anderson
This totally reimplements the microframe scheduler in dwc2 to attempt to
handle periodic splits properly.  The old code didn't even try, so this
was a significant effort since periodic splits are one of the most
complicated things in USB.

I've attempted to keep the old "don't use the microframe" schduler
around for now, but not sure it's needed.  It has also only been lightly
tested.

I think it's pretty certain that this scheduler isn't perfect and might
have some bugs, but it seems much better than what was there before.
With this change my stressful USB test (USB webcam + USB audio + some
keyboards) crackles less.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Removed incorrect limit on number of channels (Heiko Stuebner).
- Fixed order of operations bug in debug print.
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5:
- Moved defines outside of ifdef to avoid gadget-only compile error.

Changes in v4:
- Figured out what the microframe scheduler was supposed to do.
- Microframe rewrite is totally different from v3, hopefully more right.
- Microframe rewrite is later in the series now.

Changes in v3:
- The uframe scheduler patch is folded into optimization series.
- Optimize uframe scheduler "single uframe" case a little.
- uframe scheduler now atop logging patches.
- uframe scheduler now before delayed bandwidth release patches.
- Add defines like EARLY_FRAME_USEC
- Reorder dwc2_deschedule_periodic() in prep for future patches.
- uframe scheduler now shows real usefulness w/ future patches!
- Assuming single_tt is new for v3; not terribly well tested (yet).
- Keep track and use our uframe new for v3.

Changes in v2:
- Totally rewrote uframe scheduler again after writing test code.
- uframe scheduler atop delayed bandwidth release patches.

 drivers/usb/dwc2/core.h  |   85 ++-
 drivers/usb/dwc2/hcd.c   |   87 +++-
 drivers/usb/dwc2/hcd.h   |   79 ++-
 drivers/usb/dwc2/hcd_queue.c | 1170 --
 4 files changed, 1250 insertions(+), 171 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 52cbea28d0e9..115925909390 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -592,6 +592,84 @@ struct dwc2_hregs_backup {
bool valid;
 };
 
+/*
+ * Constants related to high speed periodic scheduling
+ *
+ * We have a periodic schedule that is DWC2_HS_SCHEDULE_UFRAMES long.  From a
+ * reservation point of view it's assumed that the schedule goes right back to
+ * the beginning after the end of the schedule.
+ *
+ * What does that mean for scheduling things with a long interval?  It means
+ * we'll reserve time for them in every possible microframe that they could
+ * ever be scheduled in.  ...but we'll still only actually schedule them as
+ * often as they were requested.
+ *
+ * We keep our schedule in a "bitmap" structure.  This simplifies having
+ * to keep track of and merge intervals: we just let the bitmap code do most
+ * of the heavy lifting.  In a way scheduling is much like memory allocation.
+ *
+ * We schedule 100us per uframe or 80% of 125us (the maximum amount you're
+ * supposed to schedule for periodic transfers).  That's according to spec.
+ *
+ * Note that though we only schedule 80% of each microframe, the bitmap that we
+ * keep the schedule in is tightly packed (AKA it doesn't have 100us worth of
+ * space for each uFrame).
+ *
+ * Requirements:
+ * - DWC2_HS_SCHEDULE_UFRAMES must even divide 0x4000 (HFNUM_MAX_FRNUM + 1)
+ * - DWC2_HS_SCHEDULE_UFRAMES must be 8 times DWC2_LS_SCHEDULE_FRAMES (probably
+ *   could be any multiple of 8 times DWC2_LS_SCHEDULE_FRAMES, but there might
+ *   be bugs).  The 8 comes from the USB spec: number of microframes per frame.
+ */
+#define DWC2_US_PER_UFRAME 125
+#define DWC2_HS_PERIODIC_US_PER_UFRAME 100
+
+#define DWC2_HS_SCHEDULE_UFRAMES   8
+#define DWC2_HS_SCHEDULE_US(DWC2_HS_SCHEDULE_UFRAMES * \
+DWC2_HS_PERIODIC_US_PER_UFRAME)
+
+/*
+ * Constants related to low speed scheduling
+ *
+ * For high speed we schedule every 1us.  For low speed that's a bit overkill,
+ * so we make up a unit called a "slice" that's worth 25us.  There are 40
+ * slices in a full frame and we can schedule 36 of those (90%) for periodic
+ * transfers.
+ *
+ * Our low speed schedule can be as short as 1 frame or could be longer.  When
+ * we only schedule 1 frame it means that we'll need to reserve a time every
+ * frame even for things that only transfer very rarely, so something that runs
+ * every 2048 frames will get time reserved in every frame.  Our low speed
+ * schedule can be longer and we'll be able to handle more overlap, but that
+ * will come at increased memory cost and increased time to schedule.
+ *
+ * Note: one other advantage of a short low speed schedule 

[PATCH v6 19/22] usb: dwc2: host: Add dwc2_hcd_get_future_frame_number() call

2016-01-28 Thread Douglas Anderson
As we start getting more exact about our scheduling it's becoming more
and more important to know exactly how far through the current frame we
are.  This lets us make decisions about whether there's still time left
to start a new transaction in the current frame.

We'll add dwc2_hcd_get_future_frame_number() which will tell you what
the frame number will be a certain number of microseconds (us) from
now.  We can use this information to help decide if there's enough time
left in the frame for a transaction that will take a certain duration.

This is expected to be used by a future change ("usb: dwc2: host:
Properly set even/odd frame").

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Add dwc2_hcd_get_future_frame_number() call new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/core.h |  4 
 drivers/usb/dwc2/hcd.c  | 29 +
 2 files changed, 33 insertions(+)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 64d45a2053bb..52cbea28d0e9 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1235,12 +1235,16 @@ static inline int dwc2_hsotg_set_test_mode(struct 
dwc2_hsotg *hsotg,
 
 #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
 extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg);
+extern int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, int us);
 extern void dwc2_hcd_connect(struct dwc2_hsotg *hsotg);
 extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force);
 extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg);
 #else
 static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg)
 { return 0; }
+static inline int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg,
+  int us)
+{ return 0; }
 static inline void dwc2_hcd_connect(struct dwc2_hsotg *hsotg) {}
 static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force) {}
 static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {}
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index f48da015fa5e..8edd0b45f41c 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -1947,6 +1947,35 @@ int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg)
return (hfnum & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
 }
 
+int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, int us)
+{
+   u32 hprt = dwc2_readl(hsotg->regs + HPRT0);
+   u32 hfir = dwc2_readl(hsotg->regs + HFIR);
+   u32 hfnum = dwc2_readl(hsotg->regs + HFNUM);
+   unsigned int us_per_frame;
+   unsigned int frame_number;
+   unsigned int remaining;
+   unsigned int interval;
+   unsigned int phy_clks;
+
+   /* High speed has 125 us per (micro) frame; others are 1 ms per */
+   us_per_frame = (hprt & HPRT0_SPD_MASK) ? 1000 : 125;
+
+   /* Extract fields */
+   frame_number = (hfnum & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
+   remaining = (hfnum & HFNUM_FRREM_MASK) >> HFNUM_FRREM_SHIFT;
+   interval = (hfir & HFIR_FRINT_MASK) >> HFIR_FRINT_SHIFT;
+
+   /*
+* Number of phy clocks since the last tick of the frame number after
+* "us" has passed.
+*/
+   phy_clks = (interval - remaining) +
+  DIV_ROUND_UP(interval * us, us_per_frame);
+
+   return dwc2_frame_num_inc(frame_number, phy_clks / interval);
+}
+
 int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg)
 {
return hsotg->op_state == OTG_STATE_B_HOST;
-- 
2.7.0.rc3.207.g0ac5344

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 01/22] usb: dwc2: rockchip: Make the max_transfer_size automatic

2016-01-28 Thread Douglas Anderson
Previously we needed to set the max_transfer_size to explicitly be 65535
because the old driver would detect that our hardware could support much
bigger transfers and then would try to do them.  This wouldn't work
since the DMA alignment code couldn't support it.

Later in commit e8f8c14d9da7 ("usb: dwc2: clip max_transfer_size to
65535") upstream added support for clipping this automatically.  Since
that commit it has been OK to just use "-1" (default), but nobody
bothered to change it.

Let's change it to default now for two reasons:
- It's nice to use autodetected params.
- If we can remove the 65535 limit, we can transfer more!

Signed-off-by: Douglas Anderson 
Acked-by: John Youn 
Tested-by: Heiko Stuebner 
---
Changes in v6: None
Changes in v5: None
Changes in v4:
- Add John's Acks from 

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/platform.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 510f787434b3..5008a467ce06 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -129,7 +129,7 @@ static const struct dwc2_core_params params_rk3066 = {
.host_rx_fifo_size  = 520,  /* 520 DWORDs */
.host_nperio_tx_fifo_size   = 128,  /* 128 DWORDs */
.host_perio_tx_fifo_size= 256,  /* 256 DWORDs */
-   .max_transfer_size  = 65535,
+   .max_transfer_size  = -1,
.max_packet_count   = -1,
.host_channels  = -1,
.phy_type   = -1,
-- 
2.7.0.rc3.207.g0ac5344

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 06/22] usb: dwc2: host: fix split transfer schedule sequence

2016-01-28 Thread Douglas Anderson
We're supposed to keep outstanding splits in order.  Keep track of a
list of the order of splits and process channel interrupts in that
order.

Without this change and the following setup:
* Rockchip rk3288 Chromebook, using port ff54
  -> Pluggable 7-port Hub with Charging (powered)
 -> Microsoft Wireless Keyboard 2000 in port 1.
 -> Das Keyboard in port 2.

...I find that I get dropped keys on the Microsoft keyboard (I'm sure
there are other combinations that fail, but this documents my test).
Specifically I've been typing "hahahahahahaha" on the keyboard and often
see keys dropped or repeated.

After this change the above setup works properly.  This patch is based
on a previous patch proposed by Yunzhi Li ("usb: dwc2: hcd: fix periodic
transfer schedule sequence")

Signed-off-by: Douglas Anderson 
Signed-off-by: Yunzhi Li 
Reviewed-by: Kever Yang 
Tested-by: Heiko Stuebner 
Tested-by: Kever Yang 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Fix patch tags (hcd -> host)
- Add Kever's Reviewed-by.
- Add Kever's Tested-by.
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5:
- Move list maintenance to hcd.c to avoid gadget-only compile error

Changes in v4:
- fix split transfer schedule sequence new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/core.c |  2 ++
 drivers/usb/dwc2/core.h |  2 ++
 drivers/usb/dwc2/hcd.c  |  8 
 drivers/usb/dwc2/hcd.h  |  2 ++
 drivers/usb/dwc2/hcd_intr.c | 17 +
 5 files changed, 31 insertions(+)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 73f2771b7740..ed73b26818c0 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -1676,6 +1676,8 @@ void dwc2_hc_cleanup(struct dwc2_hsotg *hsotg, struct 
dwc2_host_chan *chan)
 
chan->xfer_started = 0;
 
+   list_del_init(>split_order_list_entry);
+
/*
 * Clear channel interrupt enables and any unhandled channel interrupt
 * conditions
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 7fb6434f4639..538cf38af0e4 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -657,6 +657,7 @@ struct dwc2_hregs_backup {
  *  periodic_sched_ready because it must be rescheduled for
  *  the next frame. Otherwise, the item moves to
  *  periodic_sched_inactive.
+ * @split_order:List keeping track of channels doing splits, in order.
  * @periodic_usecs: Total bandwidth claimed so far for periodic transfers.
  *  This value is in microseconds per (micro)frame. The
  *  assumption is that all periodic transfers may occur in
@@ -780,6 +781,7 @@ struct dwc2_hsotg {
struct list_head periodic_sched_ready;
struct list_head periodic_sched_assigned;
struct list_head periodic_sched_queued;
+   struct list_head split_order;
u16 periodic_usecs;
u16 frame_usecs[8];
u16 frame_number;
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 349194342c90..0b6ebc7fff3f 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -1045,6 +1045,11 @@ static int dwc2_queue_transaction(struct dwc2_hsotg 
*hsotg,
 {
int retval = 0;
 
+   if (chan->do_split)
+   /* Put ourselves on the list to keep order straight */
+   list_move_tail(>split_order_list_entry,
+  >split_order);
+
if (hsotg->core_params->dma_enable > 0) {
if (hsotg->core_params->dma_desc_enable > 0) {
if (!chan->xfer_started ||
@@ -3153,6 +3158,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
INIT_LIST_HEAD(>periodic_sched_assigned);
INIT_LIST_HEAD(>periodic_sched_queued);
 
+   INIT_LIST_HEAD(>split_order);
+
/*
 * Create a host channel descriptor for each host channel implemented
 * in the controller. Initialize the channel descriptor array.
@@ -3166,6 +3173,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
if (channel == NULL)
goto error3;
channel->hc_num = i;
+   INIT_LIST_HEAD(>split_order_list_entry);
hsotg->hc_ptr_array[i] = channel;
}
 
diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h
index 42f2e4e233da..1b46e2e617cc 100644
--- a/drivers/usb/dwc2/hcd.h
+++ b/drivers/usb/dwc2/hcd.h
@@ -106,6 +106,7 @@ struct dwc2_qh;
  * @hc_list_entry:  For linking to list of host channels
  * @desc_list_addr: Current QH's descriptor list DMA address
  * @desc_list_sz:   Current QH's descriptor list size
+ * @split_order_list_entry: List entry for keeping track of the order of splits
  *
  * This structure represents the state 

[PATCH v6 05/22] usb: dwc2: host: Always add to the tail of queues

2016-01-28 Thread Douglas Anderson
The queues the the dwc2 host controller used are truly queues.  That
means FIFO or first in first out.

Unfortunately though the code was iterating through these queues
starting from the head, some places in the code was adding things to the
queue by adding at the head instead of the tail.  That means last in
first out.  Doh.

Go through and just always add to the tail.

Doing this makes things much happier when I've got:
* 7-port USB 2.0 Single-TT hub
* - Microsoft 2.4 GHz Transceiver v7.0 dongle
* - Jabra speakerphone playing music

Signed-off-by: Douglas Anderson 
Reviewed-by: Kever Yang 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Kever's Reviewed-by.
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Always add to the tail of queues new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/hcd.c   | 11 ++-
 drivers/usb/dwc2/hcd_ddma.c  |  4 ++--
 drivers/usb/dwc2/hcd_intr.c  |  4 ++--
 drivers/usb/dwc2/hcd_queue.c |  6 --
 4 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index e2d2e9be366e..349194342c90 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -969,7 +969,8 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
 * periodic assigned schedule
 */
qh_ptr = qh_ptr->next;
-   list_move(>qh_list_entry, >periodic_sched_assigned);
+   list_move_tail(>qh_list_entry,
+  >periodic_sched_assigned);
ret_val = DWC2_TRANSACTION_PERIODIC;
}
 
@@ -1002,8 +1003,8 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
 * non-periodic active schedule
 */
qh_ptr = qh_ptr->next;
-   list_move(>qh_list_entry,
- >non_periodic_sched_active);
+   list_move_tail(>qh_list_entry,
+  >non_periodic_sched_active);
 
if (ret_val == DWC2_TRANSACTION_NONE)
ret_val = DWC2_TRANSACTION_NON_PERIODIC;
@@ -1176,8 +1177,8 @@ static void dwc2_process_periodic_channels(struct 
dwc2_hsotg *hsotg)
 * Move the QH from the periodic assigned schedule to
 * the periodic queued schedule
 */
-   list_move(>qh_list_entry,
- >periodic_sched_queued);
+   list_move_tail(>qh_list_entry,
+  >periodic_sched_queued);
 
/* done queuing high bandwidth */
hsotg->queuing_high_bandwidth = 0;
diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c
index 36606fc33c0d..16b261cfa92d 100644
--- a/drivers/usb/dwc2/hcd_ddma.c
+++ b/drivers/usb/dwc2/hcd_ddma.c
@@ -1327,8 +1327,8 @@ void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg,
dwc2_hcd_qh_unlink(hsotg, qh);
} else {
/* Keep in assigned schedule to continue transfer */
-   list_move(>qh_list_entry,
- >periodic_sched_assigned);
+   list_move_tail(>qh_list_entry,
+  >periodic_sched_assigned);
/*
 * If channel has been halted during giveback of urb
 * then prevent any new scheduling.
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index 99efc2bd1617..2c521c00e5e0 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -143,7 +143,7 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg)
 * Move QH to the ready list to be executed next
 * (micro)frame
 */
-   list_move(>qh_list_entry,
+   list_move_tail(>qh_list_entry,
  >periodic_sched_ready);
}
tr_type = dwc2_hcd_select_transactions(hsotg);
@@ -794,7 +794,7 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg,
 * halt to be queued when the periodic schedule is
 * processed.
 */
-   list_move(>qh->qh_list_entry,
+   list_move_tail(>qh->qh_list_entry,
  >periodic_sched_assigned);
 
/*
diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index e0933a9dfad7..bc632a72f611 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -732,9 +732,11 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, 
struct 

[PATCH v6 03/22] usb: dwc2: host: Set host_rx_fifo_size to 525 for rk3066

2016-01-28 Thread Douglas Anderson
As documented in dwc2_calculate_dynamic_fifo(), host_rx_fifo_size should
really be:
 2 * ((Largest Packet size / 4) + 1 + 1) + n
 with n = number of host channel.

We have 9 host channels, so
 2 * ((1024/4) + 2) + 9 = 516 + 9 = 525

We've got 960 / 972 total_fifo_size on rk3288 (and presumably on
rk3066) and 525 + 128 + 256 = 909 so we're still under on both ports
even when we increment by 5.

In the future, it would be nice if dwc2_calculate_dynamic_fifo() could
handle the "too small" FIFO case and come up with something more
dynamically.  When we do that we can figure out how to allocate the
extra 48 / 60 bytes of FIFO that we're currently wasting.

NOTE: no known bugs are fixed by this patch, but it seems like a simple
fix and ought to fix someone.

Signed-off-by: Douglas Anderson 
Reviewed-by: Kever Yang 
Tested-by: Heiko Stuebner 
---
Changes in v6:
- Back to 525 dwords, not 528.
- Add Kever's Reviewed-by.
- Add Heiko's Tested-by.

Changes in v5: None
Changes in v4:
- Set host_rx_fifo_size to 528 for rk3066 new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/platform.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 5008a467ce06..b277e521a311 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -126,7 +126,7 @@ static const struct dwc2_core_params params_rk3066 = {
.speed  = -1,
.enable_dynamic_fifo= 1,
.en_multiple_tx_fifo= -1,
-   .host_rx_fifo_size  = 520,  /* 520 DWORDs */
+   .host_rx_fifo_size  = 525,  /* 525 DWORDs */
.host_nperio_tx_fifo_size   = 128,  /* 128 DWORDs */
.host_perio_tx_fifo_size= 256,  /* 256 DWORDs */
.max_transfer_size  = -1,
-- 
2.7.0.rc3.207.g0ac5344

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 0/22] usb: dwc2: host: Fix and speed up all the stuff, especially with splits

2016-01-28 Thread Douglas Anderson
This is a bit of catchall series for all the bug fix and performance
patches I've been working on over the last few months.  Note that for
dwc2 we need to do LOTS in software and need super low interrupt
latency, so most performance improvements actually fix real bugs.

Patches are structured to start with no-brainer stuff that could be
applied ASAP, especially things I've already gotten Acks for.  Things
get slightly more RFC / RFT like as we get farther down the series.
Anything that can be landed sooner rather than later (especially those
Acked long ago) would help in re-posts (I'm not biased, of course).

It's been a few months since my last post of this series.  In the
meantime I've added a bunch of small bugfixes to the start of it and
also TOTALLY REWROTE the microframe scheduler.  I'll say up front: I
know nothing about USB.  I haven't read the whole spec.  I'm not
terribly familiar with the OHCI, EHCI, and XHCI drivers in the kernel.
...and I'm pretty clueless overall.  Nevertheless, I've attempted to
write up a fancy scheduler based on the portion of the spec talking
about microframe scheduling requirements.  This rewritten scheduler does
seem to help when I start jamming lots of USB things into a hub, so
presumably the code is a reasonably starting point.  Given my current
understanding of USB the old code was fairly insane, so presumably even
if my new patch isn't perfect it's better than what we had.

Anyway, on to the patches:

1. usb: dwc2: rockchip: Make the max_transfer_size automatic

   No brainer.  Can land any time.

2. usb: dwc2: host: Get aligned DMA in a more supported way

   Although this touches a lot of code, it's mostly just deleting
   stuff.  The way this is working is nearly the same as tegra.  Biggest
   objection I expect is that it has too much duplication with tegra and
   musb.  I'd personally prefer to land it now and remove duplication
   later, but up to others.  Speeding up interrupt handler helps with
   SOF scheduling, so this is not just a dumb optimization.

3. usb: dwc2: host: Set host_rx_fifo_size to 525 for rk3066

   Seems like a good idea and small impact, but if someone hates it or
   it breaks on some Rockchip SoC, just drop it.  I've only tested on
   rk3288 so it would be nice if someone with access to more Rockchip
   SoCs can give a tested by.

4. usb: dwc2: host: Avoid use of chan->qh after qh freed

   Simple bugfix.  Unrelated to the series but thrown in here.

5. usb: dwc2: host: Always add to the tail of queues

   Big functionality improvement.  Small patch.  Suggest applying ASAP.

6. usb: dwc2: host: fix split transfer schedule sequence

   Unless I'm misunderstanding, this should be a no-brainer to fix.
   Could be some bikeshedding on how to fix this.  Let me know if/how
   you want me to spin.  Otherwise I'd say land it and it will fix a
   bunch of stuff.

7. usb: dwc2: host: Add scheduler tracing

   Shouldn't hurt anything.  If you have bikesheds, let me know.  Many
   future patches require this one just because they add additional
   traces.

8. usb: dwc2: host: Add a delay before releasing periodic bandwidth
9. usb: dwc2: host: Giveback URB in tasklet context

   I think we should take these.  They improve things a bunch and I have
   found no regressions due to them.  Additional testing appreciated, of
   course.

10. usb: dwc2: host: Properly set the HFIR

   I sent this out on its own, but since I'm resending the series I
   figured I'm jam it in here.  Can really go anywhere in the series or
   applied totally on its own.

11. usb: dwc2: host: There's not really a TT for the root hub

   Seems right to me, but if someone knows better then please drop.
   Wasn't part of the previous series so doesn't have any Tested-by
   tags, though Stefan did indicated that he tried it and it didn't
   appear to break anything for him.

   Can be applied totally on its own.

12. usb: dwc2: host: Use periodic interrupt even with DMA

   Just came up with this one recently so it's had slightly less
   testing.  ...but it certainly fixed a bunch of stuff.  Could probably
   be moved around in the series to be pretty much anywhere.  I don't
   think this has a huge impact until we fix the scheduler (below) but
   at the same time I'm pretty sure it's something that's been wrong for
   a long time.

13. usb: dwc2: host: Rename some fields in struct dwc2_qh
14. usb: dwc2: host: Reorder things in hcd_queue.c
15. usb: dwc2: host: Split code out to make dwc2_do_reserve()

   Cleanups to make future patches easier to understand.  Bikeshed away.
   All no-op changes.

16. usb: dwc2: host: Add scheduler logging for missed SOFs

   I found this to be quite helpful.  If you hate it, drop it from the
   series.

17. usb: dwc2: host: Manage frame nums better in scheduler

   Doesn't totally make sense on its own, but a good halfway point to
   the microframe scheduler.  ...and shouldn't regress anything.  Allows
   us to do the "Properly set even/odd frame" 

[PATCH v6 02/22] usb: dwc2: host: Get aligned DMA in a more supported way

2016-01-28 Thread Douglas Anderson
All other host controllers who want aligned buffers for DMA do it a
certain way.  Let's do that too instead of working behind the USB core's
back.  This makes our interrupt handler not take forever and also rips
out a lot of code, simplifying things a bunch.

This also has the side effect of removing the 65535 max transfer size
limit.

NOTE: The actual code to allocate the aligned buffers is ripped almost
completely from the tegra EHCI driver.  At some point in the future we
may want to add this functionality to the USB core to share more code
everywhere.

Signed-off-by: Douglas Anderson 
Acked-by: John Youn 
Tested-by: Heiko Stuebner 
Tested-by: John Youn 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Add John's Acks from 

Changes in v3: None
Changes in v2:
- Add a warn if setup_dma is not aligned (Julius Werner).

 drivers/usb/dwc2/core.c  |  21 +-
 drivers/usb/dwc2/hcd.c   | 170 +--
 drivers/usb/dwc2/hcd.h   |  10 ---
 drivers/usb/dwc2/hcd_intr.c  |  65 -
 drivers/usb/dwc2/hcd_queue.c |   7 +-
 5 files changed, 87 insertions(+), 186 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 39a0fa8a4c0a..73f2771b7740 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -1958,19 +1958,11 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
}
 
if (hsotg->core_params->dma_enable > 0) {
-   dma_addr_t dma_addr;
-
-   if (chan->align_buf) {
-   if (dbg_hc(chan))
-   dev_vdbg(hsotg->dev, "align_buf\n");
-   dma_addr = chan->align_buf;
-   } else {
-   dma_addr = chan->xfer_dma;
-   }
-   dwc2_writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
+   dwc2_writel((u32)chan->xfer_dma,
+   hsotg->regs + HCDMA(chan->hc_num));
if (dbg_hc(chan))
dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
-(unsigned long)dma_addr, chan->hc_num);
+(unsigned long)chan->xfer_dma, chan->hc_num);
}
 
/* Start the split */
@@ -3363,13 +3355,6 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
width = (hwcfg3 & GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK) >>
GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT;
hw->max_transfer_size = (1 << (width + 11)) - 1;
-   /*
-* Clip max_transfer_size to 65535. dwc2_hc_setup_align_buf() allocates
-* coherent buffers with this size, and if it's too large we can
-* exhaust the coherent DMA pool.
-*/
-   if (hw->max_transfer_size > 65535)
-   hw->max_transfer_size = 65535;
width = (hwcfg3 & GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK) >>
GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT;
hw->max_packet_count = (1 << (width + 4)) - 1;
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 8847c72e55f6..bc4bdbc1534e 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -635,9 +635,9 @@ static void dwc2_hc_init_split(struct dwc2_hsotg *hsotg,
chan->hub_port = (u8)hub_port;
 }
 
-static void *dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
-  struct dwc2_host_chan *chan,
-  struct dwc2_qtd *qtd, void *bufptr)
+static void dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
+ struct dwc2_host_chan *chan,
+ struct dwc2_qtd *qtd)
 {
struct dwc2_hcd_urb *urb = qtd->urb;
struct dwc2_hcd_iso_packet_desc *frame_desc;
@@ -657,7 +657,6 @@ static void *dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
else
chan->xfer_buf = urb->setup_packet;
chan->xfer_len = 8;
-   bufptr = NULL;
break;
 
case DWC2_CONTROL_DATA:
@@ -684,7 +683,6 @@ static void *dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
chan->xfer_dma = hsotg->status_buf_dma;
else
chan->xfer_buf = hsotg->status_buf;
-   bufptr = NULL;
break;
}
break;
@@ -717,14 +715,6 @@ static void *dwc2_hc_init_xfer(struct dwc2_hsotg *hsotg,
 
chan->xfer_len = frame_desc->length - qtd->isoc_split_offset;
 
-   /* For non-dword aligned buffers */
-   if (hsotg->core_params->dma_enable > 0 &&
-   (chan->xfer_dma & 0x3))
-   bufptr = (u8 *)urb->buf 

[PATCH v6 04/22] usb: dwc2: host: Avoid use of chan->qh after qh freed

2016-01-28 Thread Douglas Anderson
When poking around with USB devices with slub_debug enabled, I found
another obvious use after free.  Turns out that in dwc2_hc_n_intr() I
was in a state when the contents of chan->qh was filled with 0x6b,
indicating that chan->qh was freed but chan still had a reference to
it.

Let's make sure that whenever we free qh we also make sure we remove a
reference from its channel.

The bug fixed here doesn't appear to be new--I believe I just got lucky
and happened to see it while stress testing.

Signed-off-by: Douglas Anderson 
Reviewed-by: Kever Yang 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add one more instance of check; kept Reviewed-by / Tested-by (OK?).
- Add Kever's Reviewed-by.
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Avoid use of chan->qh after qh freed new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/hcd.c  | 10 ++
 drivers/usb/dwc2/hcd_intr.c | 10 ++
 2 files changed, 20 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index bc4bdbc1534e..e2d2e9be366e 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -164,6 +164,9 @@ static void dwc2_qh_list_free(struct dwc2_hsotg *hsotg,
 qtd_list_entry)
dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh);
 
+   if (qh->channel && qh->channel->qh == qh)
+   qh->channel->qh = NULL;
+
spin_unlock_irqrestore(>lock, flags);
dwc2_hcd_qh_free(hsotg, qh);
spin_lock_irqsave(>lock, flags);
@@ -554,7 +557,12 @@ static int dwc2_hcd_endpoint_disable(struct dwc2_hsotg 
*hsotg,
dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh);
 
ep->hcpriv = NULL;
+
+   if (qh->channel && qh->channel->qh == qh)
+   qh->channel->qh = NULL;
+
spin_unlock_irqrestore(>lock, flags);
+
dwc2_hcd_qh_free(hsotg, qh);
 
return 0;
@@ -2782,6 +2790,8 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, 
struct urb *urb,
 fail3:
dwc2_urb->priv = NULL;
usb_hcd_unlink_urb_from_ep(hcd, urb);
+   if (qh_allocated && qh->channel && qh->channel->qh == qh)
+   qh->channel->qh = NULL;
 fail2:
spin_unlock_irqrestore(>lock, flags);
urb->hcpriv = NULL;
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index 352c98364317..99efc2bd1617 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -1935,6 +1935,16 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int 
chnum)
}
 
dwc2_writel(hcint, hsotg->regs + HCINT(chnum));
+
+   /*
+* If we got an interrupt after someone called
+* dwc2_hcd_endpoint_disable() we don't want to crash below
+*/
+   if (!chan->qh) {
+   dev_warn(hsotg->dev, "Interrupt on disabled channel\n");
+   return;
+   }
+
chan->hcint = hcint;
hcint &= hcintmsk;
 
-- 
2.7.0.rc3.207.g0ac5344

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 22/22] usb: dwc2: host: If using uframe scheduler, end splits better

2016-01-28 Thread Douglas Anderson
The microframe scheduler figured out exactly how many transfers we need
for a split transaction.  Let's use this knowledge to know when to end
things.

Without this I found that certain devices would just keep responding
with tons of NYET resonses on their INT_IN endpoint.  These would just
keep going and going and eventually we'd decide to terminate the
transfer (because the whole frame changed), but by that time the
scheduler would decide that we "missed" the start of the next transfer.
I can also imagine that if we blow past the end of our scheduled time we
may mess up other things that were scheduled to happen.

No known test cases are improved by this patch except that the scheduler
code doesn't yell about MISSES constantly anymore.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- If using uframe scheduler, end splits better new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/hcd_intr.c | 48 +++--
 1 file changed, 42 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index dc285667233a..f7a325a8c741 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -1363,14 +1363,50 @@ static void dwc2_hc_nyet_intr(struct dwc2_hsotg *hsotg,
 
if (chan->ep_type == USB_ENDPOINT_XFER_INT ||
chan->ep_type == USB_ENDPOINT_XFER_ISOC) {
-   int frnum = dwc2_hcd_get_frame_number(hsotg);
+   struct dwc2_qh *qh = chan->qh;
+   bool past_end;
+
+   if (hsotg->core_params->uframe_sched <= 0) {
+   int frnum = dwc2_hcd_get_frame_number(hsotg);
+
+   /* Don't have num_hs_transfers; simple logic */
+   past_end = dwc2_full_frame_num(frnum) !=
+dwc2_full_frame_num(qh->next_active_frame);
+   } else {
+   int end_frnum;
 
-   if (dwc2_full_frame_num(frnum) !=
-   dwc2_full_frame_num(chan->qh->next_active_frame)) {
/*
-* No longer in the same full speed frame.
-* Treat this as a transaction error.
-*/
+   * Figure out the end frame based on schedule.
+   *
+   * We don't want to go on trying again and again
+   * forever.  Let's stop when we've done all the
+   * transfers that were scheduled.
+   *
+   * We're going to be comparing start_active_frame
+   * and next_active_frame, both of which are 1
+   * before the time the packet goes on the wire,
+   * so that cancels out.  Basically if had 1
+   * transfer and we saw 1 NYET then we're done.
+   * We're getting a NYET here so if next >=
+   * (start + num_transfers) we're done. The
+   * complexity is that for all but ISOC_OUT we
+   * skip one slot.
+   */
+   end_frnum = dwc2_frame_num_inc(
+   qh->start_active_frame,
+   qh->num_hs_transfers);
+
+   if (qh->ep_type != USB_ENDPOINT_XFER_ISOC ||
+   qh->ep_is_in)
+   end_frnum =
+  dwc2_frame_num_inc(end_frnum, 1);
+
+   past_end = dwc2_frame_num_le(
+   end_frnum, qh->next_active_frame);
+   }
+
+   if (past_end) {
+   /* Treat this as a transaction error. */
 #if 0
/*
 * Todo: Fix system performance so this can
-- 
2.7.0.rc3.207.g0ac5344

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 11/22] usb: dwc2: host: There's not really a TT for the root hub

2016-01-28 Thread Douglas Anderson
I find that when I plug a full speed (NOT high speed) hub into a dwc2
port and then I plug a bunch of devices into that full speed hub that
dwc2 goes bat guano crazy.  Specifically, it just spews errors like this
in the console:
  usb usb1: clear tt 1 (9043) error -22

The specific test case I used looks like this:
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc2/1p, 480M
|__ Port 1: Dev 17, If 0, Class=Hub, Driver=hub/4p, 12M
|__ Port 2: Dev 19, If 0, ..., Driver=usbhid, 1.5M
|__ Port 4: Dev 20, If 0, ..., Driver=usbhid, 12M
|__ Port 4: Dev 20, If 1, ..., Driver=usbhid, 12M
|__ Port 4: Dev 20, If 2, ..., Driver=usbhid, 12M

Showing VID/PID:
 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 Bus 001 Device 017: ID 03eb:3301 Atmel Corp. at43301 4-Port Hub
 Bus 001 Device 020: ID 045e:0745 Microsoft Corp. Nano Transceiver ...
 Bus 001 Device 019: ID 046d:c404 Logitech, Inc. TrackMan Wheel

I spent a bunch of time trying to figure out why there are errors to
begin with.  I believe that the issue may be a hardware issue where the
transceiver sometimes accidentally sends a PREAMBLE packet if you send a
packet to a full speed device right after one to a low speed device.
Luckily the USB driver retries and the second time things work OK.

In any case, things kinda seem work despite the errors, except for the
"clear tt" spew mucking up my console.  Chalk it up for a win for
retries and robust protocols.

So getting back to the "clear tt" problem, it appears that we get those
because there's not actually a TT here to clear.  It's my understanding
that when dwc2 operates in low speed or full speed mode that there's no
real TT out there.  That makes all these attempts to "clear the TT"
somewhat meaningless and also causes the spew in the log.

Let's just skip all the useless TT clears.  Eventually we should root
cause the errors, but even if we do this is still a proper fix and is
likely to avoid the "clear tt" error in the future.

Note that hooking up a Full Speed USB Audio Device (Jabra 510) to this
same hub with the keyboard / trackball shows that even audio works over
this janky connection.  As a point to note, this particular change (skip
bogus TT clears) compared to just commenting out the dev_err() in
hub_tt_work() actually produces better audio.

Note: don't ask me where I got a full speed USB hub or whether the
massive amount of dust that accumulated on it while it was in my junk
box affected its funtionality.  Just smile and nod.

Signed-off-by: Douglas Anderson 
---
Changes in v6:
- There's not really a TT for the root hub new for v6

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/hcd_intr.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index 5d25a5ec9736..fe44870f84eb 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -87,6 +87,7 @@ static void dwc2_hc_handle_tt_clear(struct dwc2_hsotg *hsotg,
struct dwc2_host_chan *chan,
struct dwc2_qtd *qtd)
 {
+   struct usb_device *root_hub = dwc2_hsotg_to_hcd(hsotg)->self.root_hub;
struct urb *usb_urb;
 
if (!chan->qh)
@@ -102,6 +103,15 @@ static void dwc2_hc_handle_tt_clear(struct dwc2_hsotg 
*hsotg,
if (!usb_urb || !usb_urb->dev || !usb_urb->dev->tt)
return;
 
+   /*
+* The root hub doesn't really have a TT, but Linux thinks it
+* does because how could you have a "high speed hub" that
+* directly talks directly to low speed devices without a TT?
+* It's all lies.  Lies, I tell you.
+*/
+   if (usb_urb->dev->tt->hub == root_hub)
+   return;
+
if (qtd->urb->status != -EPIPE && qtd->urb->status != -EREMOTEIO) {
chan->qh->tt_buffer_dirty = 1;
if (usb_hub_clear_tt_buffer(usb_urb))
-- 
2.7.0.rc3.207.g0ac5344

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 07/22] usb: dwc2: host: Add scheduler tracing

2016-01-28 Thread Douglas Anderson
In preparation for future changes to the scheduler let's add some
tracing that makes it easy for us to see what's happening.  By default
this tracing will be off.

By changing "core.h" you can easily trace to ftrace, the console, or
nowhere.

Signed-off-by: Douglas Anderson 
Reviewed-by: Kever Yang 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Kever's Reviewed-by.
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Retooled scheduler tracing a bit, so left off John's Ack from v3.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/core.h  | 20 
 drivers/usb/dwc2/hcd.h   |  5 +
 drivers/usb/dwc2/hcd_intr.c  |  6 +-
 drivers/usb/dwc2/hcd_queue.c | 24 +++-
 4 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 538cf38af0e4..18f9e4045643 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -44,6 +44,26 @@
 #include 
 #include "hw.h"
 
+/*
+ * Suggested defines for tracers:
+ * - no_printk:Disable tracing
+ * - pr_info:  Print this info to the console
+ * - trace_printk: Print this info to trace buffer (good for verbose logging)
+ */
+
+#define DWC2_TRACE_SCHEDULER   no_printk
+#define DWC2_TRACE_SCHEDULER_VBno_printk
+
+/* Detailed scheduler tracing, but won't overwhelm console */
+#define dwc2_sch_dbg(hsotg, fmt, ...)  \
+   DWC2_TRACE_SCHEDULER(pr_fmt("%s: SCH: " fmt),   \
+dev_name(hsotg->dev), ##__VA_ARGS__)
+
+/* Verbose scheduler tracing */
+#define dwc2_sch_vdbg(hsotg, fmt, ...) \
+   DWC2_TRACE_SCHEDULER_VB(pr_fmt("%s: SCH: " fmt),\
+   dev_name(hsotg->dev), ##__VA_ARGS__)
+
 static inline u32 dwc2_readl(const void __iomem *addr)
 {
u32 value = __raw_readl(addr);
diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h
index 1b46e2e617cc..809bc4ff9116 100644
--- a/drivers/usb/dwc2/hcd.h
+++ b/drivers/usb/dwc2/hcd.h
@@ -563,6 +563,11 @@ static inline u16 dwc2_frame_num_inc(u16 frame, u16 inc)
return (frame + inc) & HFNUM_MAX_FRNUM;
 }
 
+static inline u16 dwc2_frame_num_dec(u16 frame, u16 dec)
+{
+   return (frame + HFNUM_MAX_FRNUM + 1 - dec) & HFNUM_MAX_FRNUM;
+}
+
 static inline u16 dwc2_full_frame_num(u16 frame)
 {
return (frame & HFNUM_MAX_FRNUM) >> 3;
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index 577c91096a51..5d25a5ec9736 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -138,13 +138,17 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg)
while (qh_entry != >periodic_sched_inactive) {
qh = list_entry(qh_entry, struct dwc2_qh, qh_list_entry);
qh_entry = qh_entry->next;
-   if (dwc2_frame_num_le(qh->sched_frame, hsotg->frame_number))
+   if (dwc2_frame_num_le(qh->sched_frame, hsotg->frame_number)) {
+   dwc2_sch_vdbg(hsotg, "QH=%p ready fn=%04x, sch=%04x\n",
+ qh, hsotg->frame_number, qh->sched_frame);
+
/*
 * Move QH to the ready list to be executed next
 * (micro)frame
 */
list_move_tail(>qh_list_entry,
  >periodic_sched_ready);
+   }
}
tr_type = dwc2_hcd_select_transactions(hsotg);
if (tr_type != DWC2_TRANSACTION_NONE)
diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index bc632a72f611..0e9faa75593c 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -113,6 +113,9 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct 
dwc2_qh *qh,
qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number,
 SCHEDULE_SLOP);
qh->interval = urb->interval;
+   dwc2_sch_dbg(hsotg, "QH=%p init sch=%04x, fn=%04x, int=%#x\n",
+qh, qh->sched_frame, hsotg->frame_number,
+qh->interval);
 #if 0
/* Increase interrupt polling rate for debugging */
if (qh->ep_type == USB_ENDPOINT_XFER_INT)
@@ -126,6 +129,11 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct 
dwc2_qh *qh,
qh->interval *= 8;
qh->sched_frame |= 0x7;
qh->start_split_frame = qh->sched_frame;
+   dwc2_sch_dbg(hsotg,
+"QH=%p init*8 sch=%04x, fn=%04x, 
int=%#x\n",
+qh, 

[PATCH v6 08/22] usb: dwc2: host: Add a delay before releasing periodic bandwidth

2016-01-28 Thread Douglas Anderson
We'd like to be able to use HCD_BH in order to speed up the dwc2 host
interrupt handler quite a bit.  However, according to the kernel doc for
usb_submit_urb() (specifically the part about "Reserved Bandwidth
Transfers"), we need to keep a reservation active as long as a device
driver keeps submitting.  That was easy to do when we gave back the URB
in the interrupt context: we just looked at when our queue was empty and
released the reserved bandwidth then.  ...but now we need a little more
complexity.

We'll follow EHCI's lead in commit 9118f9eb4f1e ("USB: EHCI: improve
interrupt qh unlink") and add a 5ms delay.  Since we don't have a whole
timer infrastructure in dwc2, we'll just add a timer per QH.  The
overhead for this is very small.

Note that the dwc2 scheduler is pretty broken (see future patches to fix
it).  This patch attempts to replicate all old behavior and just add the
proper delay.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Moved periodic bandwidth release delay patch earlier again.

Changes in v3:
- Moved periodic bandwidth release delay patch later in the series.

Changes in v2:
- Periodic bandwidth release delay new for V2

 drivers/usb/dwc2/hcd.h   |   6 ++
 drivers/usb/dwc2/hcd_queue.c | 237 +--
 2 files changed, 187 insertions(+), 56 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h
index 809bc4ff9116..79473ea35bd6 100644
--- a/drivers/usb/dwc2/hcd.h
+++ b/drivers/usb/dwc2/hcd.h
@@ -215,6 +215,7 @@ enum dwc2_transaction_type {
 /**
  * struct dwc2_qh - Software queue head structure
  *
+ * @hsotg:  The HCD state structure for the DWC OTG controller
  * @ep_type:Endpoint type. One of the following values:
  *   - USB_ENDPOINT_XFER_CONTROL
  *   - USB_ENDPOINT_XFER_BULK
@@ -252,13 +253,16 @@ enum dwc2_transaction_type {
  * @n_bytes:Xfer Bytes array. Each element corresponds to a 
transfer
  *  descriptor and indicates original XferSize value for 
the
  *  descriptor
+ * @unreserve_timer:Timer for releasing periodic reservation.
  * @tt_buffer_dirty True if clear_tt_buffer_complete is pending
+ * @unreserve_pending:  True if we planned to unreserve but haven't yet.
  *
  * A Queue Head (QH) holds the static characteristics of an endpoint and
  * maintains a list of transfers (QTDs) for that endpoint. A QH structure may
  * be entered in either the non-periodic or periodic schedule.
  */
 struct dwc2_qh {
+   struct dwc2_hsotg *hsotg;
u8 ep_type;
u8 ep_is_in;
u16 maxp;
@@ -281,7 +285,9 @@ struct dwc2_qh {
dma_addr_t desc_list_dma;
u32 desc_list_sz;
u32 *n_bytes;
+   struct timer_list unreserve_timer;
unsigned tt_buffer_dirty:1;
+   unsigned unreserve_pending:1;
 };
 
 /**
diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index 0e9faa75593c..b9e4867e1afd 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -53,6 +53,94 @@
 #include "core.h"
 #include "hcd.h"
 
+/* Wait this long before releasing periodic reservation */
+#define DWC2_UNRESERVE_DELAY (msecs_to_jiffies(5))
+
+/**
+ * dwc2_do_unreserve() - Actually release the periodic reservation
+ *
+ * This function actually releases the periodic bandwidth that was reserved
+ * by the given qh.
+ *
+ * @hsotg: The HCD state structure for the DWC OTG controller
+ * @qh:QH for the periodic transfer.
+ */
+static void dwc2_do_unreserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
+{
+   assert_spin_locked(>lock);
+
+   WARN_ON(!qh->unreserve_pending);
+
+   /* No more unreserve pending--we're doing it */
+   qh->unreserve_pending = false;
+
+   if (WARN_ON(!list_empty(>qh_list_entry)))
+   list_del_init(>qh_list_entry);
+
+   /* Update claimed usecs per (micro)frame */
+   hsotg->periodic_usecs -= qh->usecs;
+
+   if (hsotg->core_params->uframe_sched > 0) {
+   int i;
+
+   for (i = 0; i < 8; i++) {
+   hsotg->frame_usecs[i] += qh->frame_usecs[i];
+   qh->frame_usecs[i] = 0;
+   }
+   } else {
+   /* Release periodic channel reservation */
+   hsotg->periodic_channels--;
+   }
+}
+
+/**
+ * dwc2_unreserve_timer_fn() - Timer function to release periodic reservation
+ *
+ * According to the kernel doc for usb_submit_urb() (specifically the part 
about
+ * "Reserved Bandwidth Transfers"), we need to keep a reservation active as
+ * long as a device driver keeps submitting.  Since we're using HCD_BH to give
+ * back the URB we need to give the driver a little bit of time 

[PATCH v6 13/22] usb: dwc2: host: Rename some fields in struct dwc2_qh

2016-01-28 Thread Douglas Anderson
This no-op change just does some renames to simplify a future patch.

1. The "interval" field is renamed to "host_interval" to make it more
   obvious that this interval may be 8 times the interval that the
   device sees (if we're doing split transactions).  A future patch will
   also add the "device_interval" field.
2. The "usecs" field is renamed to "host_us" again to make it more
   obvious that this is the time for the transaction as seen by the
   host.  For split transactions the device may see a much longer
   transaction time.  A future patch will also add "device_us".
3. The "sched_frame" field is renamed to "next_active_frame".  The name
   "sched_frame" kept confusing me because it felt like something more
   permament (the QH's reservation or something).  The name
   "next_active_frame" makes it more obvious that this field is
   constantly changing.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Rename some fields in struct dwc2_qh new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/hcd.h   |  20 
 drivers/usb/dwc2/hcd_ddma.c  |  37 ---
 drivers/usb/dwc2/hcd_intr.c  |  10 ++--
 drivers/usb/dwc2/hcd_queue.c | 107 ++-
 4 files changed, 92 insertions(+), 82 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h
index 79473ea35bd6..10c35585a2bd 100644
--- a/drivers/usb/dwc2/hcd.h
+++ b/drivers/usb/dwc2/hcd.h
@@ -236,10 +236,14 @@ enum dwc2_transaction_type {
  * @do_split:   Full/low speed endpoint on high-speed hub requires 
split
  * @td_first:   Index of first activated isochronous transfer 
descriptor
  * @td_last:Index of last activated isochronous transfer descriptor
- * @usecs:  Bandwidth in microseconds per (micro)frame
- * @interval:   Interval between transfers in (micro)frames
- * @sched_frame:(Micro)frame to initialize a periodic transfer.
- *  The transfer executes in the following (micro)frame.
+ * @host_us:Bandwidth in microseconds per transfer as seen by host
+ * @host_interval:  Interval between transfers as seen by the host.  If
+ *  the host is high speed and the device is low speed this
+ *  will be 8 times device interval.
+ * @next_active_frame:  (Micro)frame before we next need to put something on
+ *  the bus.  We'll move the qh to active here.  If the
+ *  host is in high speed mode this will be a uframe.  If
+ *  the host is in low speed mode this will be a full 
frame.
  * @frame_usecs:Internal variable used by the microframe scheduler
  * @start_split_frame:  (Micro)frame at which last start split was initialized
  * @ntd:Actual number of transfer descriptors in a list
@@ -272,9 +276,9 @@ struct dwc2_qh {
u8 do_split;
u8 td_first;
u8 td_last;
-   u16 usecs;
-   u16 interval;
-   u16 sched_frame;
+   u16 host_us;
+   u16 host_interval;
+   u16 next_active_frame;
u16 frame_usecs[8];
u16 start_split_frame;
u16 ntd;
@@ -651,7 +655,7 @@ static inline u16 dwc2_hcd_get_ep_bandwidth(struct 
dwc2_hsotg *hsotg,
return 0;
}
 
-   return qh->usecs;
+   return qh->host_us;
 }
 
 extern void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c
index 16b261cfa92d..26b00270ca0b 100644
--- a/drivers/usb/dwc2/hcd_ddma.c
+++ b/drivers/usb/dwc2/hcd_ddma.c
@@ -81,7 +81,7 @@ static u16 dwc2_max_desc_num(struct dwc2_qh *qh)
 static u16 dwc2_frame_incr_val(struct dwc2_qh *qh)
 {
return qh->dev_speed == USB_SPEED_HIGH ?
-  (qh->interval + 8 - 1) / 8 : qh->interval;
+  (qh->host_interval + 8 - 1) / 8 : qh->host_interval;
 }
 
 static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
@@ -252,7 +252,7 @@ static void dwc2_update_frame_list(struct dwc2_hsotg 
*hsotg, struct dwc2_qh *qh,
chan = qh->channel;
inc = dwc2_frame_incr_val(qh);
if (qh->ep_type == USB_ENDPOINT_XFER_ISOC)
-   i = dwc2_frame_list_idx(qh->sched_frame);
+   i = dwc2_frame_list_idx(qh->next_active_frame);
else
i = 0;
 
@@ -278,13 +278,13 @@ static void dwc2_update_frame_list(struct dwc2_hsotg 
*hsotg, struct dwc2_qh *qh,
return;
 
chan->schinfo = 0;
-   if (chan->speed == USB_SPEED_HIGH && qh->interval) {
+   if (chan->speed == USB_SPEED_HIGH && qh->host_interval) {
j = 1;
/* TODO - check this */
-   inc = (8 + qh->interval - 1) / 

[PATCH v6 12/22] usb: dwc2: host: Use periodic interrupt even with DMA

2016-01-28 Thread Douglas Anderson
The old code in dwc2_process_periodic_channels() would only enable the
"periodic empty" interrupt if we weren't using DMA.  That wasn't right
since we can still get into cases where we have small FIFOs even on
systems that have DMA (the rk3288 is a prime example).

Let's always enable/disable the "periodic empty" when appropriate.  As
part of this:

* Always call dwc2_process_periodic_channels() even if there's nothing
  in periodic_sched_assigned (we move the queue empty check so we still
  avoid the extra work).  That will make extra certain that we will
  properly disable the "periodic empty" interrupt even if there's
  nothing queued up.

* Move the enable of "periodic empty" due to non-empty
  periodic_sched_assigned to be for slave mode (non-DMA mode) only.
  Presumably this was the original intention of the check for DMA since
  it seems to match the comments above where in slave mode we leave
  things on the assigned queue.

Note that even before this change slave mode didn't work for me, so I
can't say for sure that my understanding of slave mode is correct.
However, this shouldn't change anything for slave mode so if slave mode
worked for someone in the past it ought to still work.

With this change, I no longer get constant misses reported by my other
debugging code (and with future patches) when I've got:
* Rockchip rk3288 Chromebook, using port ff54
  -> Pluggable 7-port Hub with Charging (powered)
 -> Microsoft Wireless Keyboard 2000 in port 1.
 -> Das Keyboard in port 2.
 -> Jabra Speaker in port 3
 -> Logitech, Inc. Webcam C600 in port 4
 -> Microsoft Sidewinder X6 Keyboard in port 5

...and I'm playing music on the USB speaker and capturing video from the
webcam.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Use periodic interrupt even with DMA new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/hcd.c | 71 +++---
 1 file changed, 32 insertions(+), 39 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 40558478a192..fd731347daf7 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -1109,10 +1109,14 @@ static void dwc2_process_periodic_channels(struct 
dwc2_hsotg *hsotg)
u32 fspcavail;
u32 gintmsk;
int status;
-   int no_queue_space = 0;
-   int no_fifo_space = 0;
+   bool no_queue_space = false;
+   bool no_fifo_space = false;
u32 qspcavail;
 
+   /* If empty list then just adjust interrupt enables */
+   if (list_empty(>periodic_sched_assigned))
+   goto exit;
+
if (dbg_perio())
dev_vdbg(hsotg->dev, "Queue periodic transactions\n");
 
@@ -1190,42 +1194,32 @@ static void dwc2_process_periodic_channels(struct 
dwc2_hsotg *hsotg)
}
}
 
-   if (hsotg->core_params->dma_enable <= 0) {
-   tx_status = dwc2_readl(hsotg->regs + HPTXSTS);
-   qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
-   TXSTS_QSPCAVAIL_SHIFT;
-   fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
-   TXSTS_FSPCAVAIL_SHIFT;
-   if (dbg_perio()) {
-   dev_vdbg(hsotg->dev,
-"  P Tx Req Queue Space Avail (after queue): 
%d\n",
-qspcavail);
-   dev_vdbg(hsotg->dev,
-"  P Tx FIFO Space Avail (after queue): %d\n",
-fspcavail);
-   }
-
-   if (!list_empty(>periodic_sched_assigned) ||
-   no_queue_space || no_fifo_space) {
-   /*
-* May need to queue more transactions as the request
-* queue or Tx FIFO empties. Enable the periodic Tx
-* FIFO empty interrupt. (Always use the half-empty
-* level to ensure that new requests are loaded as
-* soon as possible.)
-*/
-   gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
+exit:
+   if (no_queue_space || no_fifo_space ||
+   (hsotg->core_params->dma_enable <= 0 &&
+!list_empty(>periodic_sched_assigned))) {
+   /*
+* May need to queue more transactions as the request
+* queue or Tx FIFO empties. Enable the periodic Tx
+* FIFO empty interrupt. (Always use the half-empty
+* level to ensure that new requests are loaded as
+* soon as possible.)
+*/
+   gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
+   if (!(gintmsk 

[PATCH v6 16/22] usb: dwc2: host: Add scheduler logging for missed SOFs

2016-01-28 Thread Douglas Anderson
We'll use the new "scheduler verbose debugging" macro to log missed
SOFs.  This is fast enough (assuming you configure it to use the ftrace
buffer) that we can do it without worrying about the speed hit.  The
overhead hit if the scheduler tracing is set to "no_printk" should be
near zero.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Add scheduler logging for missed SOFs new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/core.h |  3 ++-
 drivers/usb/dwc2/hcd.c  |  2 +-
 drivers/usb/dwc2/hcd_intr.c | 12 
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 18f9e4045643..64d45a2053bb 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -809,9 +809,10 @@ struct dwc2_hsotg {
bool bus_suspended;
bool new_connection;
 
+   u16 last_frame_num;
+
 #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
 #define FRAME_NUM_ARRAY_SIZE 1000
-   u16 last_frame_num;
u16 *frame_num_array;
u16 *last_frame_num_array;
int frame_num_idx;
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index fd731347daf7..f48da015fa5e 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3084,8 +3084,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
FRAME_NUM_ARRAY_SIZE, GFP_KERNEL);
if (!hsotg->last_frame_num_array)
goto error1;
-   hsotg->last_frame_num = HFNUM_MAX_FRNUM;
 #endif
+   hsotg->last_frame_num = HFNUM_MAX_FRNUM;
 
/* Check if the bus driver or platform code has setup a dma_mask */
if (hsotg->core_params->dma_enable > 0 &&
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index d929db5e7f3f..dc285667233a 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -55,12 +55,16 @@
 /* This function is for debug only */
 static void dwc2_track_missed_sofs(struct dwc2_hsotg *hsotg)
 {
-#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
u16 curr_frame_number = hsotg->frame_number;
+   u16 expected = dwc2_frame_num_inc(hsotg->last_frame_num, 1);
+
+   if (expected != curr_frame_number)
+   dwc2_sch_vdbg(hsotg, "MISSED SOF %04x != %04x\n",
+   expected, curr_frame_number);
 
+#ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
if (hsotg->frame_num_idx < FRAME_NUM_ARRAY_SIZE) {
-   if (((hsotg->last_frame_num + 1) & HFNUM_MAX_FRNUM) !=
-   curr_frame_number) {
+   if (expected != curr_frame_number) {
hsotg->frame_num_array[hsotg->frame_num_idx] =
curr_frame_number;
hsotg->last_frame_num_array[hsotg->frame_num_idx] =
@@ -79,8 +83,8 @@ static void dwc2_track_missed_sofs(struct dwc2_hsotg *hsotg)
}
hsotg->dumped_frame_num_array = 1;
}
-   hsotg->last_frame_num = curr_frame_number;
 #endif
+   hsotg->last_frame_num = curr_frame_number;
 }
 
 static void dwc2_hc_handle_tt_clear(struct dwc2_hsotg *hsotg,
-- 
2.7.0.rc3.207.g0ac5344

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 14/22] usb: dwc2: host: Reorder things in hcd_queue.c

2016-01-28 Thread Douglas Anderson
This no-op change just reorders a few functions in hcd_queue.c in order
to prepare for future changes.  Motivations here:

The functions dwc2_hcd_qh_free() and dwc2_hcd_qh_create() are exported
functions.  They are not called within the file.  That means that they
should be near the bottom so that they can easily call static helpers.

The function dwc2_qh_init() is only called by dwc2_hcd_qh_create() and
should move near the bottom with it.

The only reason that the dwc2_unreserve_timer_fn() timer function (and
its subroutine dwc2_do_unreserve()) were so high in the file was that
they needed to be above dwc2_qh_init().  Now that dwc2_qh_init() has
been moved down it can be moved down a bit.  A later patch will split
the reserve code out of dwc2_schedule_periodic() and the reserve
function should be near the unreserve function.  The reserve function
needs to be below dwc2_find_uframe() since it calls that.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Reorder things in hcd_queue.c new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/hcd_queue.c | 600 +--
 1 file changed, 300 insertions(+), 300 deletions(-)

diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index 39f4de6279f8..8a2067bc1e62 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -57,295 +57,6 @@
 #define DWC2_UNRESERVE_DELAY (msecs_to_jiffies(5))
 
 /**
- * dwc2_do_unreserve() - Actually release the periodic reservation
- *
- * This function actually releases the periodic bandwidth that was reserved
- * by the given qh.
- *
- * @hsotg: The HCD state structure for the DWC OTG controller
- * @qh:QH for the periodic transfer.
- */
-static void dwc2_do_unreserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
-{
-   assert_spin_locked(>lock);
-
-   WARN_ON(!qh->unreserve_pending);
-
-   /* No more unreserve pending--we're doing it */
-   qh->unreserve_pending = false;
-
-   if (WARN_ON(!list_empty(>qh_list_entry)))
-   list_del_init(>qh_list_entry);
-
-   /* Update claimed usecs per (micro)frame */
-   hsotg->periodic_usecs -= qh->host_us;
-
-   if (hsotg->core_params->uframe_sched > 0) {
-   int i;
-
-   for (i = 0; i < 8; i++) {
-   hsotg->frame_usecs[i] += qh->frame_usecs[i];
-   qh->frame_usecs[i] = 0;
-   }
-   } else {
-   /* Release periodic channel reservation */
-   hsotg->periodic_channels--;
-   }
-}
-
-/**
- * dwc2_unreserve_timer_fn() - Timer function to release periodic reservation
- *
- * According to the kernel doc for usb_submit_urb() (specifically the part 
about
- * "Reserved Bandwidth Transfers"), we need to keep a reservation active as
- * long as a device driver keeps submitting.  Since we're using HCD_BH to give
- * back the URB we need to give the driver a little bit of time before we
- * release the reservation.  This worker is called after the appropriate
- * delay.
- *
- * @work: Pointer to a qh unreserve_work.
- */
-static void dwc2_unreserve_timer_fn(unsigned long data)
-{
-   struct dwc2_qh *qh = (struct dwc2_qh *)data;
-   struct dwc2_hsotg *hsotg = qh->hsotg;
-   unsigned long flags;
-
-   /*
-* Wait for the lock, or for us to be scheduled again.  We
-* could be scheduled again if:
-* - We started executing but didn't get the lock yet.
-* - A new reservation came in, but cancel didn't take effect
-*   because we already started executing.
-* - The timer has been kicked again.
-* In that case cancel and wait for the next call.
-*/
-   while (!spin_trylock_irqsave(>lock, flags)) {
-   if (timer_pending(>unreserve_timer))
-   return;
-   }
-
-   /*
-* Might be no more unreserve pending if:
-* - We started executing but didn't get the lock yet.
-* - A new reservation came in, but cancel didn't take effect
-*   because we already started executing.
-*
-* We can't put this in the loop above because unreserve_pending needs
-* to be accessed under lock, so we can only check it once we got the
-* lock.
-*/
-   if (qh->unreserve_pending)
-   dwc2_do_unreserve(hsotg, qh);
-
-   spin_unlock_irqrestore(>lock, flags);
-}
-
-/**
- * dwc2_qh_init() - Initializes a QH structure
- *
- * @hsotg: The HCD state structure for the DWC OTG controller
- * @qh:The QH to init
- * @urb:   Holds the information about the device/endpoint needed to initialize
- * the QH
- */
-#define SCHEDULE_SLOP 10
-static void dwc2_qh_init(struct dwc2_hsotg *hsotg, 

[PATCH v6 18/22] usb: dwc2: host: Schedule periodic right away if it's time

2016-01-28 Thread Douglas Anderson
In dwc2_hcd_qh_deactivate() we will put some things on the
periodic_sched_ready list.  These things won't be taken off the ready
list until the next SOF, which might be a little late.  Let's put them
on right away.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Schedule periodic right away if it's time new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/hcd_queue.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index 9b3c435339ee..3abb34a5fc5b 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -1080,12 +1080,26 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, 
struct dwc2_qh *qh,
 * Note: we purposely use the frame_number from the "hsotg" structure
 * since we know SOF interrupt will handle future frames.
 */
-   if (dwc2_frame_num_le(qh->next_active_frame, hsotg->frame_number))
+   if (dwc2_frame_num_le(qh->next_active_frame, hsotg->frame_number)) {
+   enum dwc2_transaction_type tr_type;
+
+   /*
+* We're bypassing the SOF handler which is normally what puts
+* us on the ready list because we're in a hurry and need to
+* try to catch up.
+*/
+   dwc2_sch_vdbg(hsotg, "QH=%p IMM ready fn=%04x, nxt=%04x\n",
+ qh, frame_number, qh->next_active_frame);
list_move_tail(>qh_list_entry,
   >periodic_sched_ready);
-   else
+
+   tr_type = dwc2_hcd_select_transactions(hsotg);
+   if (tr_type != DWC2_TRANSACTION_NONE)
+   dwc2_hcd_queue_transactions(hsotg, tr_type);
+   } else {
list_move_tail(>qh_list_entry,
   >periodic_sched_inactive);
+   }
 }
 
 /**
-- 
2.7.0.rc3.207.g0ac5344

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 17/22] usb: dwc2: host: Manage frame nums better in scheduler

2016-01-28 Thread Douglas Anderson
The dwc2 scheduler (contained in hcd_queue.c) was a bit confusing in the
way it initted / kept track of which frames a QH was going to be active
in.  Let's clean things up a little bit in preparation for a rewrite of
the microframe scheduler.

Specifically:
* Old code would pick a frame number in dwc2_qh_init() and would try to
  pick it "in a slightly future (micro)frame".  As far as I can tell the
  reason for this was that there was a delay between dwc2_qh_init() and
  when we actually wanted to dwc2_hcd_qh_add().  ...but apparently this
  attempt to be slightly in the future wasn't enough because
  dwc2_hcd_qh_add() then had code to reset things if the frame _wasn't_
  in the future.  There's no reason not to just pick the frame later.
  For non-periodic QH we now pick the frame in dwc2_hcd_qh_add().  For
  periodic QH we pick the frame at dwc2_schedule_periodic() time.
* The old "dwc2_qh_init() actually assigned to "hsotg->frame_number".
  This doesn't seem like a great idea since that variable is supposed to
  be used to keep track of which SOF the interrupt handler has seen.
  Let's be clean: anyone who wants the current frame number (instead of
  the one as of the last interrupt) should ask for it.
* The old code wasn't terribly consistent about trying to use the frame
  that the microframe scheduler assigned to it.  In
  dwc2_sched_periodic_split() when it was scheduling the first frame it
  always "ORed" in 0x7 (!).  Since the frame goes on the wire 1 uFrame
  after next_active_frame it meant that the SSPLIT would always try for
  uFrame 0 and the transaction would happen on the low speed bus during
  uFrame 1.  This is irregardless of what the microframe scheduler
  said.
* The old code assumed it would get called to schedule the next in a
  periodic split very quickly.  That is if next_active_frame was
  0 (transfer on wire in uFrame 1) it assumed it was getting called to
  schedule the next uFrame during uFrame 1 too (so it could queue
  something up for uFrame 2).  It should be possible to actually queue
  something up for uFrame 2 while in uFrame 2 (AKA queue up ASAP).  To
  do this, code needs to look at the previously scheduled frame when
  deciding when to next be active, not look at the current frame number.
* If there was no microframe scheduler, the old code would check for
  whether we should be active using "qh->next_active_frame ==
  frame_number".  This seemed like a race waiting to happen.  ...plus
  there's no way that you wouldn't want to schedule if next_active_frame
  was actually less than frame number.

Note that this change doesn't make 100% sense on its own since it's
expecting some sanity in the frame numbers assigned by the microframe
scheduler and (as per the future patch which rewries it) I think that
the current microframe scheduler is quite insane.  However, it seems
like splitting this up from the microframe scheduler patch makes things
into smaller chunks and hopefully adds to clarity rather than reduces
it.  The two patches could certainly be squashed.  Not that in the very
least, I don't see any obvious bad behavior introduced with just this
patch.

I've attempted to keep the config parameter to disable the microframe
scheduler in tact in this change, though I'm not sure it's worth it.
Obviously the code is touched a lot so it's possible I regressed
something when the microframe scheduler is disabled, though I did some
basic testing and it seemed to work OK.  I'm still not 100% sure why you
wouldn't want the microframe scheduler (presuming it works), so maybe a
future patch (or a future version of this patch?) could remove that
parameter.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Fix bug where periodic things get scheduled too quick (Alan Stern)
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Manage frame nums better in scheduler new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/hcd.h   |  10 +-
 drivers/usb/dwc2/hcd_queue.c | 351 ---
 2 files changed, 272 insertions(+), 89 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h
index 10c35585a2bd..fd266ac53a28 100644
--- a/drivers/usb/dwc2/hcd.h
+++ b/drivers/usb/dwc2/hcd.h
@@ -244,8 +244,11 @@ enum dwc2_transaction_type {
  *  the bus.  We'll move the qh to active here.  If the
  *  host is in high speed mode this will be a uframe.  If
  *  the host is in low speed mode this will be a full 
frame.
+ * @start_active_frame: If we are partway through a split transfer, this will 
be
+ * what next_active_frame was when we started.  Otherwise
+ * it should always be the same as next_active_frame.
+ * @assigned_uframe:The uframe (0 -7) assigned by 

[PATCH v6 09/22] usb: dwc2: host: Giveback URB in tasklet context

2016-01-28 Thread Douglas Anderson
In commit 94dfd7edfd5c ("USB: HCD: support giveback of URB in tasklet
context") support was added to give back the URB in tasklet context.
Let's take advantage of this in dwc2.

This speeds up the dwc2 interrupt handler considerably.

Note that this requires the change ("usb: dwc2: host: Add a delay before
releasing periodic bandwidth") to come first.

Note that, as per Alan Stern in
, we also need to make sure
that the extra delay before the device drivers submit more data doesn't
break the scheduler.  At the moment the scheduler is pretty broken (see
future patches) so it's hard to be 100% certain, but I have yet to see
any new breakage introduced by this delay.  ...and speeding up interrupt
processing for dwc2 is a huge deal because it means we've got a better
chance of not missing SOF interrupts.  That means we've got an overall
win here.

Note that when playing USB audio and using a USB webcam and having
several USB keyboards plugged in, the crackling on the USB audio device
is noticably reduced with this patch.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- A bit earlier in the list of patches than in v3.

Changes in v3: None
Changes in v2:
- Commit message now says that URB giveback change needs delay change.

 drivers/usb/dwc2/hcd.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 0b6ebc7fff3f..40558478a192 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -2341,9 +2341,7 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct 
dwc2_qtd *qtd,
kfree(qtd->urb);
qtd->urb = NULL;
 
-   spin_unlock(>lock);
usb_hcd_giveback_urb(dwc2_hsotg_to_hcd(hsotg), urb, status);
-   spin_lock(>lock);
 }
 
 /*
@@ -2964,7 +2962,7 @@ static struct hc_driver dwc2_hc_driver = {
.hcd_priv_size = sizeof(struct wrapper_priv_data),
 
.irq = _dwc2_hcd_irq,
-   .flags = HCD_MEMORY | HCD_USB2,
+   .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
 
.start = _dwc2_hcd_start,
.stop = _dwc2_hcd_stop,
-- 
2.7.0.rc3.207.g0ac5344

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 10/22] usb: dwc2: host: Properly set the HFIR

2016-01-28 Thread Douglas Anderson
According to the most up to date version of the dwc2 databook, the FRINT
field of the HFIR register should be programmed to:
* 125 us * (PHY clock freq for HS) - 1
* 1000 us * (PHY clock freq for FS/LS) - 1

This is opposed to older versions of the doc that claimed it should be:
* 125 us * (PHY clock freq for HS)
* 1000 us * (PHY clock freq for FS/LS)

In case you didn't spot it, the difference is the "- 1".

Let's add the "- 1" to match the newest user manual.  It's presumed that
the "- 1" should have always been there and that this was always a
documentation error.  If some hardware needs the "- 1" and other
hardware doesn't, we'll have to add a configuration parameter for it in
the future.

I checked things before and after this patch on rk3288 using a Total
Phase Beagle 5000 analyzer.

Before this patch, a low speed mouse shows constant Frame Timing Jitter
errors.  After this patch errors have gone away.

Before this patch SOF packets move forward about 1 us per 4 ms.  After
this patch the SOF packets move backward about 1 us per 255 ms.  Some
specific SOF timestamps from the analyzer are below.

Before:
  6.603.790
  6.603.916
  6.604.041
  6.604.166
  ...
  6.607.541
  6.607.667
  6.607.792
  6.607.917
  ...
  6.611.417
  6.611.543
  6.611.668
  6.611.793

After:
  6.215.159
  6.215.284
  6.215.408
  6.215.533
  6.215.658
  ...
  6.470.658
  6.470.783
  6.470.907
  ...
  6.726.032
  6.726.157
  6.725.281
  6.725.406

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
---
Changes in v6:
- Incorporated Properly set the HFIR patch to big series in v6
- Add Heiko's Tested-by.

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index ed73b26818c0..a5db20f12ee4 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -2245,10 +2245,10 @@ u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg)
 
if ((hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT == HPRT0_SPD_HIGH_SPEED)
/* High speed case */
-   return 125 * clock;
+   return 125 * clock - 1;
else
/* FS/LS case */
-   return 1000 * clock;
+   return 1000 * clock - 1;
 }
 
 /**
-- 
2.7.0.rc3.207.g0ac5344

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 15/22] usb: dwc2: host: Split code out to make dwc2_do_reserve()

2016-01-28 Thread Douglas Anderson
This no-op change splits code out of dwc2_schedule_periodic() into a
dwc2_do_reserve() function.  This makes it a little easier to follow the
logic.

Signed-off-by: Douglas Anderson 
Tested-by: Heiko Stuebner 
Tested-by: Stefan Wahren 
---
Changes in v6:
- Add Heiko's Tested-by.
- Add Stefan's Tested-by.

Changes in v5: None
Changes in v4:
- Split code out to make dwc2_do_reserve() new for v4.

Changes in v3: None
Changes in v2: None

 drivers/usb/dwc2/hcd_queue.c | 112 ++-
 1 file changed, 67 insertions(+), 45 deletions(-)

diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index 8a2067bc1e62..9ce407e5017d 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -245,6 +245,70 @@ static int dwc2_find_uframe(struct dwc2_hsotg *hsotg, 
struct dwc2_qh *qh)
 }
 
 /**
+ * dwc2_do_reserve() - Make a periodic reservation
+ *
+ * Try to allocate space in the periodic schedule.  Depending on parameters
+ * this might use the microframe scheduler or the dumb scheduler.
+ *
+ * @hsotg: The HCD state structure for the DWC OTG controller
+ * @qh:QH for the periodic transfer.
+ *
+ * Returns: 0 upon success; error upon failure.
+ */
+static int dwc2_do_reserve(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
+{
+   int status;
+
+   if (hsotg->core_params->uframe_sched > 0) {
+   int frame = -1;
+
+   status = dwc2_find_uframe(hsotg, qh);
+   if (status == 0)
+   frame = 7;
+   else if (status > 0)
+   frame = status - 1;
+
+   /* Set the new frame up */
+   if (frame >= 0) {
+   qh->next_active_frame &= ~0x7;
+   qh->next_active_frame |= (frame & 7);
+   dwc2_sch_dbg(hsotg,
+"QH=%p sched_p nxt=%04x, uf=%d\n",
+qh, qh->next_active_frame, frame);
+   }
+
+   if (status > 0)
+   status = 0;
+   } else {
+   status = dwc2_periodic_channel_available(hsotg);
+   if (status) {
+   dev_info(hsotg->dev,
+"%s: No host channel available for periodic 
transfer\n",
+__func__);
+   return status;
+   }
+
+   status = dwc2_check_periodic_bandwidth(hsotg, qh);
+   }
+
+   if (status) {
+   dev_dbg(hsotg->dev,
+   "%s: Insufficient periodic bandwidth for periodic 
transfer\n",
+   __func__);
+   return status;
+   }
+
+   if (hsotg->core_params->uframe_sched <= 0)
+   /* Reserve periodic channel */
+   hsotg->periodic_channels++;
+
+   /* Update claimed usecs per (micro)frame */
+   hsotg->periodic_usecs += qh->host_us;
+
+   return 0;
+}
+
+/**
  * dwc2_do_unreserve() - Actually release the periodic reservation
  *
  * This function actually releases the periodic bandwidth that was reserved
@@ -393,51 +457,9 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg 
*hsotg, struct dwc2_qh *qh)
 * that case.
 */
if (!qh->unreserve_pending) {
-   if (hsotg->core_params->uframe_sched > 0) {
-   int frame = -1;
-
-   status = dwc2_find_uframe(hsotg, qh);
-   if (status == 0)
-   frame = 7;
-   else if (status > 0)
-   frame = status - 1;
-
-   /* Set the new frame up */
-   if (frame >= 0) {
-   qh->next_active_frame &= ~0x7;
-   qh->next_active_frame |= (frame & 7);
-   dwc2_sch_dbg(hsotg,
-"QH=%p sched_p nxt=%04x, uf=%d\n",
-qh, qh->next_active_frame, frame);
-   }
-
-   if (status > 0)
-   status = 0;
-   } else {
-   status = dwc2_periodic_channel_available(hsotg);
-   if (status) {
-   dev_info(hsotg->dev,
-   "%s: No host channel available for 
periodic transfer\n",
-   __func__);
-   return status;
-   }
-
-   status = dwc2_check_periodic_bandwidth(hsotg, qh);
-   }
-
-   if (status) {
-   dev_dbg(hsotg->dev,
-   "%s: Insufficient periodic bandwidth for 
periodic transfer\n",
-   

regression with S3 and XHCI

2016-01-28 Thread Oliver Neukum
Hi,

with the latest kernels I tested devices connected to XHCI
are gone after resume. The ports are not resumed. An error is in dmesg:

[  614.639506] sd 5:0:0:0: [sdc] Starting disk
[  614.672568] xhci_hcd :00:14.0: port 7 resume PLC timeout
[  614.695152] xhci_hcd :00:14.0: port 6 resume PLC timeout
[  614.716345] xhci_hcd :00:14.0: port 4 resume PLC timeout
[  614.906969] iwlwifi :5c:00.0: L1 Enabled - LTR Disabled
[  614.913933] iwlwifi :5c:00.0: L1 Enabled - LTR Disabled
[  614.914034] iwlwifi :5c:00.0: Radio type=0x1-0x2-0x0
[  614.942266] usb 3-5: reset full-speed USB device number 3 using xhci_hcd
[  614.988670] ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[  614.988706] ata6: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[  614.988719] ata4: SATA link down (SStatus 0 SControl 300)
[  614.988749] ata3: SATA link down (SStatus 0 SControl 300)
[  614.990735] ata6.00: ACPI cmd 00/00:00:00:00:00:a0 (NOP) rejected by device 
(Stat=0x51 Err=0x04)
[  614.990830] ata6.00: supports DRM functions and may not be fully accessible
[  614.990920] ata6.00: failed to get NCQ Send/Recv Log Emask 0x1
[  614.991108] ata6.00: ACPI cmd 00/00:00:00:00:00:a0 (NOP) rejected by device 
(Stat=0x51 Err=0x04)
[  614.991126] ata6.00: supports DRM functions and may not be fully accessible
[  614.991159] ata6.00: failed to get NCQ Send/Recv Log Emask 0x1
[  614.991188] ata6.00: configured for UDMA/133
[  615.114778] ata2.00: configured for UDMA/100
[  615.182266] usb 3-8: reset high-speed USB device number 6 using xhci_hcd
[  615.422230] usb 3-7: reset high-speed USB device number 5 using xhci_hcd
[  616.070075] rtc_cmos 00:04: System wakeup disabled by ACPI

Bisecting this failed as I ran into a period the kernel crashes due to
S3

git bisect start
# bad: [7c553985c6749d9311552d529108104f83b97bc7] Merge branch
'usb-testing' of
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb into
usb-testing
git bisect bad 7c553985c6749d9311552d529108104f83b97bc7
# good: [afd2ff9b7e1b367172f18ba7f693dfb62bdcb2dc] Linux 4.4
git bisect good afd2ff9b7e1b367172f18ba7f693dfb62bdcb2dc
# bad: [f9a03ae123c92c1f45cd2ca88d0f6edd787be78c] Merge tag
'for-f2fs-4.5' of
git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
git bisect bad f9a03ae123c92c1f45cd2ca88d0f6edd787be78c
# bad: [aee3bfa3307cd0da2126bdc0ea359dabea5ee8f7] Merge
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
git bisect bad aee3bfa3307cd0da2126bdc0ea359dabea5ee8f7
# bad: [60b7eca1dc2ec066916b3b7ac6ad89bea13cb9af] Merge tag
'upstream-4.5-rc1' of git://git.infradead.org/linux-ubifs
git bisect bad 60b7eca1dc2ec066916b3b7ac6ad89bea13cb9af
# skip: [581dbc8bfc47ab16c69a67cc20dafea378ddbc60] Merge tag
'pinctrl-v4.5-1' of
git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
git bisect skip 581dbc8bfc47ab16c69a67cc20dafea378ddbc60
# good: [b4bdf7ef301655b85875c9cf04f93a54bd763f97]
clocksource/drivers/vt8500: Add the COMPILE_TEST option
git bisect good b4bdf7ef301655b85875c9cf04f93a54bd763f97
# good: [eb12a1afdc02e59fc09934743490549c77327b1a] perf cpu_map: Add
perf_event__fprintf_cpu_map function
git bisect good eb12a1afdc02e59fc09934743490549c77327b1a
# good: [d870a9d5e31ea69a1ceb7555d0d79364c442c5c0] Merge tag
'edac_for_4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
git bisect good d870a9d5e31ea69a1ceb7555d0d79364c442c5c0
# good: [fa5fd7c628412ee09ccf5e1d6eebe1dba916b8ee] Merge tag
'arm64-upstream' of
git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
git bisect good fa5fd7c628412ee09ccf5e1d6eebe1dba916b8ee
# skip: [1baa5efbeb6eb75de697f7b5931094be33f12005] Merge tag 'for-linus'
of git://git.kernel.org/pub/scm/virt/kvm/kvm
git bisect skip 1baa5efbeb6eb75de697f7b5931094be33f12005
# skip: [9d8415d6c148a16b6d906a96f0596851d7e4d607] arm64: KVM: Turn
system register numbers to an enum
git bisect skip 9d8415d6c148a16b6d906a96f0596851d7e4d607

00:14.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family 
USB xHCI (rev 04) (prog-if 30 [XHCI])
Subsystem: Hewlett-Packard Company Device 190a
Flags: bus master, medium devsel, latency 0, IRQ 31 

  
Memory at cca2 (64-bit, non-prefetchable) [size=64K]

  
Capabilities: [70] Power Management version 2   

  
Capabilities: [80] MSI: Enable+ Count=1/8 Maskable- 64bit+  

   

[GIT PULL] USB-serial fixes for v4.5-rc2

2016-01-28 Thread Johan Hovold
Hi Greg,

Here's a first set of fixes for 4.5-rc.

Thanks,
Johan


The following changes since commit 92e963f50fc74041b5e9e744c330dca48e04f08d:

  Linux 4.5-rc1 (2016-01-24 13:06:47 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git 
tags/usb-serial-4.5-rc2

for you to fetch changes up to 4152b387da81617c80cb2946b2d56e3958906b3e:

  USB: option: fix Cinterion AHxx enumeration (2016-01-25 13:32:53 +0100)


USB-serial fixes for v4.5-rc2

Here are two fixes of crashes in the visor driver that could be
triggered using bad (malicious) descriptors, a fix for two memory leaks
in the new mxu11x0 driver, and an interface-blacklist fix for the option
driver.

Included are also some new device ids.

Signed-off-by: Johan Hovold 


Daniele Palmas (1):
  USB: serial: option: Adding support for Telit LE922

Greg Kroah-Hartman (1):
  USB: serial: ftdi_sio: add support for Yaesu SCU-18 cable

Johan Hovold (1):
  USB: visor: fix null-deref at probe

John Ernberg (1):
  USB: option: fix Cinterion AHxx enumeration

Mathieu OTHACEHE (1):
  USB: mxu11x0: fix memory leak on usb_serial private data

Peter Dedecker (1):
  USB: cp210x: add ID for IAI USB to RS485 adaptor

Vladis Dronov (1):
  USB: serial: visor: fix crash on detecting device without write_urbs

 drivers/usb/serial/cp210x.c   |  1 +
 drivers/usb/serial/ftdi_sio.c |  1 +
 drivers/usb/serial/ftdi_sio_ids.h |  1 +
 drivers/usb/serial/mxu11x0.c  | 20 
 drivers/usb/serial/option.c   | 18 +-
 drivers/usb/serial/visor.c| 11 +--
 6 files changed, 49 insertions(+), 3 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html