[PATCH] USB: gadget: udc: atmel: fix possible oops when unloading module
Executing the 'insmod g_hid.ko', then executing the 'rmmod g_hid.ko', the NULL pointer oops will be triggered. When unloading the module 'g_hid.ko', the urb request will be dequeued and the completion routine will be excuted. If no urb packet, the urb request will not be added to the endpoint queue and the completion routine pointer in urb request is NULL. Accessing to the NULL function pointer will cause the oops issue. Add the code to check the urb request is in the endpoint queue or not.If the urb request is not in the endpoint queue, a negative error code will be returned. This bug was introduced since the file 'atmel_usba_udc.c' was initialized. Fixes: 914a3f3b3754 (USB: add atmel_usba_udc driver) Cc: sta...@vger.kernel.org # always been there... oops dump log is shown in the following. Unable to handle kernel NULL pointer dereference at virtual address pgd = dedf [] *pgd=3ede5831, *pte=, *ppte= Internal error: Oops: 8007 [#1] ARM Modules linked in: g_hid(-) usb_f_hid libcomposite Signed-off-by: Songjun Wu songjun...@atmel.com --- drivers/usb/gadget/udc/atmel_usba_udc.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index ce88237..48629cc 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -828,7 +828,7 @@ static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) { struct usba_ep *ep = to_usba_ep(_ep); struct usba_udc *udc = ep-udc; - struct usba_request *req = to_usba_req(_req); + struct usba_request *req; unsigned long flags; u32 status; @@ -837,6 +837,16 @@ static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) spin_lock_irqsave(udc-lock, flags); + list_for_each_entry(req, ep-queue, queue) { + if (req-req == _req) + break; + } + + if (req-req != _req) { + spin_unlock_irqrestore(udc-lock, flags); + return -EINVAL; + } + if (req-using_dma) { /* * If this request is currently being transferred, -- 1.7.9.5 -- 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: Issues with commit 34b48db6 (block: remove artifical max_hw_sectors cap)
On Sun, Dec 28, 2014 at 10:10:01PM -0500, Alan Stern wrote: (Is this a USB device? Presumably you wouldn't have CC'ed the linux-usb and usb-storage mailing lists if it wasn't...) It's a usb attached device. From the inquity information and the product name it looks like a SATA device attached via a usb bridge. The only limits usb-storage imposes on max_sectors are those needed to work around bugs in the devices' USB bridges. (Okay, there's also something for tape drive devices, but it probably doesn't belong in usb-storage -- it should be handled by the SCSI tape driver.) If the ATA layer needs to set a limit on max_sectors, why doesn't it simply go ahead and do so? Because the ATA layer doesn't control the device, the bridge does. And it seems like it doesn't communicate the maximum transfer size properly. -- 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 v3 02/20] usb: isp1760: Move removal cleanup code to isp1760-hcd.c
The removal cleanup code is duplicated between the different bus glues. Move it to a central location. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Changes since v1: - Call release_mem_region() after iounmap() --- drivers/usb/host/isp1760-hcd.c | 10 ++ drivers/usb/host/isp1760-hcd.h | 2 ++ drivers/usb/host/isp1760-if.c | 16 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index e4a9424..7498727 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -2263,6 +2263,16 @@ err_put: return ERR_PTR(ret); } +void isp1760_unregister(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + + usb_remove_hcd(hcd); + iounmap(hcd-regs); + release_mem_region(hcd-rsrc_start, hcd-rsrc_len); + usb_put_hcd(hcd); +} + MODULE_DESCRIPTION(Driver for the ISP1760 USB-controller from NXP); MODULE_AUTHOR(Sebastian Siewior bige...@linuxtronix.de); MODULE_LICENSE(GPL v2); diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index fda0f2d..ea13a58 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -6,6 +6,8 @@ struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, int irq, unsigned long irqflags, struct device *dev, const char *busname, unsigned int devflags); +void isp1760_unregister(struct device *dev); + int init_kmem_once(void); void deinit_kmem_cache(void); diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 3db98da..b96c62f 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -160,14 +160,7 @@ cleanup1: static void isp1761_pci_remove(struct pci_dev *dev) { - struct usb_hcd *hcd; - - hcd = pci_get_drvdata(dev); - - usb_remove_hcd(hcd); - iounmap(hcd-regs); - release_mem_region(hcd-rsrc_start, hcd-rsrc_len); - usb_put_hcd(hcd); + isp1760_unregister(dev-dev); pci_disable_device(dev); } @@ -291,12 +284,7 @@ cleanup: static int isp1760_plat_remove(struct platform_device *pdev) { - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - iounmap(hcd-regs); - release_mem_region(hcd-rsrc_start, hcd-rsrc_len); - usb_put_hcd(hcd); + isp1760_unregister(pdev-dev); return 0; } -- 2.0.5 -- 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 v3 03/20] usb: isp1760: Manage device driver data in common code
Don't duplicate *_set_drvdata calls in glue code. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/host/isp1760-hcd.c | 2 ++ drivers/usb/host/isp1760-if.c | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 7498727..19fbd69 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -2252,6 +2252,8 @@ struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, goto err_unmap; device_wakeup_enable(hcd-self.controller); + dev_set_drvdata(dev, hcd); + return hcd; err_unmap: diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index b96c62f..64eaf5d 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -146,7 +146,6 @@ static int isp1761_pci_probe(struct pci_dev *dev, iounmap(iobase); release_mem_region(nxp_pci_io_base, iolength); - pci_set_drvdata(dev, hcd); return 0; cleanup3: @@ -272,8 +271,6 @@ static int isp1760_plat_probe(struct platform_device *pdev) goto cleanup; } - platform_set_drvdata(pdev, hcd); - pr_info(ISP1760 USB device initialised\n); return 0; -- 2.0.5 -- 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 v3 16/20] usb: isp1760: Initialize the bus interface in core code
Although the corresponding register is part of the HCD register space, processor bus initialization is not specific to the HCD. To prepare for device controller support, move bus interface initialization to core code. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/host/isp1760-core.c | 62 -- drivers/usb/host/isp1760-core.h | 31 +++ drivers/usb/host/isp1760-hcd.c | 67 - drivers/usb/host/isp1760-hcd.h | 20 +--- 4 files changed, 105 insertions(+), 75 deletions(-) diff --git a/drivers/usb/host/isp1760-core.c b/drivers/usb/host/isp1760-core.c index 35278a8..e840a1d 100644 --- a/drivers/usb/host/isp1760-core.c +++ b/drivers/usb/host/isp1760-core.c @@ -13,7 +13,8 @@ * version 2 as published by the Free Software Foundation. */ -#include linux/gpio.h +#include linux/delay.h +#include linux/gpio/consumer.h #include linux/io.h #include linux/kernel.h #include linux/module.h @@ -22,6 +23,54 @@ #include isp1760-core.h #include isp1760-hcd.h +#include isp1760-regs.h + +static void isp1760_init_core(struct isp1760_device *isp) +{ + u32 hwmode; + + /* Low-level chip reset */ + if (isp-rst_gpio) { + gpiod_set_value_cansleep(isp-rst_gpio, 1); + mdelay(50); + gpiod_set_value_cansleep(isp-rst_gpio, 0); + } + + /* +* Reset the host controller, including the CPU interface +* configuration. +*/ + isp1760_write32(isp-regs, HC_RESET_REG, SW_RESET_RESET_ALL); + msleep(100); + + /* Setup HW Mode Control: This assumes a level active-low interrupt */ + hwmode = HW_DATA_BUS_32BIT; + + if (isp-devflags ISP1760_FLAG_BUS_WIDTH_16) + hwmode = ~HW_DATA_BUS_32BIT; + if (isp-devflags ISP1760_FLAG_ANALOG_OC) + hwmode |= HW_ANA_DIGI_OC; + if (isp-devflags ISP1760_FLAG_DACK_POL_HIGH) + hwmode |= HW_DACK_POL_HIGH; + if (isp-devflags ISP1760_FLAG_DREQ_POL_HIGH) + hwmode |= HW_DREQ_POL_HIGH; + if (isp-devflags ISP1760_FLAG_INTR_POL_HIGH) + hwmode |= HW_INTR_HIGH_ACT; + if (isp-devflags ISP1760_FLAG_INTR_EDGE_TRIG) + hwmode |= HW_INTR_EDGE_TRIG; + + /* +* We have to set this first in case we're in 16-bit mode. +* Write it twice to ensure correct upper bits if switching +* to 16-bit mode. +*/ + isp1760_write32(isp-regs, HC_HW_MODE_CTRL, hwmode); + isp1760_write32(isp-regs, HC_HW_MODE_CTRL, hwmode); + + dev_info(isp-dev, bus width: %u, oc: %s\n, +isp-devflags ISP1760_FLAG_BUS_WIDTH_16 ? 16 : 32, +isp-devflags ISP1760_FLAG_ANALOG_OC ? analog : digital); +} int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, struct device *dev, unsigned int devflags) @@ -39,12 +88,21 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, if (!isp) return -ENOMEM; + isp-dev = dev; + isp-devflags = devflags; + + isp-rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH); + if (IS_ERR(isp-rst_gpio)) + return PTR_ERR(isp-rst_gpio); + isp-regs = devm_ioremap_resource(dev, mem); if (IS_ERR(isp-regs)) return PTR_ERR(isp-regs); + isp1760_init_core(isp); + ret = isp1760_hcd_register(isp-hcd, isp-regs, mem, irq, - irqflags | IRQF_SHARED, dev, devflags); + irqflags | IRQF_SHARED, dev); if (ret 0) return ret; diff --git a/drivers/usb/host/isp1760-core.h b/drivers/usb/host/isp1760-core.h index 0caeb11..cd4a0f3 100644 --- a/drivers/usb/host/isp1760-core.h +++ b/drivers/usb/host/isp1760-core.h @@ -20,8 +20,29 @@ #include isp1760-hcd.h +struct device; +struct gpio_desc; + +/* + * Device flags that can vary from board to board. All of these + * indicate the most atypical case, so that a devflags of 0 is + * a sane default configuration. + */ +#define ISP1760_FLAG_BUS_WIDTH_16 0x0002 /* 16-bit data bus width */ +#define ISP1760_FLAG_OTG_EN0x0004 /* Port 1 supports OTG */ +#define ISP1760_FLAG_ANALOG_OC 0x0008 /* Analog overcurrent */ +#define ISP1760_FLAG_DACK_POL_HIGH 0x0010 /* DACK active high */ +#define ISP1760_FLAG_DREQ_POL_HIGH 0x0020 /* DREQ active high */ +#define ISP1760_FLAG_ISP1761 0x0040 /* Chip is ISP1761 */ +#define ISP1760_FLAG_INTR_POL_HIGH 0x0080 /* Interrupt polarity active high */ +#define ISP1760_FLAG_INTR_EDGE_TRIG0x0100 /* Interrupt edge triggered */ + struct isp1760_device { + struct device *dev; + void __iomem *regs; + unsigned int devflags; +
[PATCH v3 04/20] usb: isp1760: Don't expose hcd to glue code from isp1760_register
The glue code probe functions don't need to access the hcd structure anymore. Modify isp1760_register to return an integer error code instead of the hcd pointer. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/host/isp1760-hcd.c | 18 ++ drivers/usb/host/isp1760-hcd.h | 10 +++--- drivers/usb/host/isp1760-if.c | 19 ++- 3 files changed, 19 insertions(+), 28 deletions(-) diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 19fbd69..4d6e50b 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -60,6 +60,9 @@ struct isp1760_hcd { struct gpio_desc*rst_gpio; }; +typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, + struct isp1760_qtd *qtd); + static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) { return (struct isp1760_hcd *) (hcd-hcd_priv); @@ -2208,24 +2211,23 @@ void deinit_kmem_cache(void) kmem_cache_destroy(urb_listitem_cachep); } -struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, -int irq, unsigned long irqflags, -struct device *dev, const char *busname, -unsigned int devflags) +int isp1760_register(phys_addr_t res_start, resource_size_t res_len, int irq, +unsigned long irqflags, struct device *dev, +const char *busname, unsigned int devflags) { struct usb_hcd *hcd; struct isp1760_hcd *priv; int ret; if (usb_disabled()) - return ERR_PTR(-ENODEV); + return -ENODEV; /* prevent usb-core allocating DMA pages */ dev-dma_mask = NULL; hcd = usb_create_hcd(isp1760_hc_driver, dev, dev_name(dev)); if (!hcd) - return ERR_PTR(-ENOMEM); + return -ENOMEM; priv = hcd_to_priv(hcd); priv-devflags = devflags; @@ -2254,7 +2256,7 @@ struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, dev_set_drvdata(dev, hcd); - return hcd; + return 0; err_unmap: iounmap(hcd-regs); @@ -2262,7 +2264,7 @@ err_unmap: err_put: usb_put_hcd(hcd); -return ERR_PTR(ret); +return ret; } void isp1760_unregister(struct device *dev) diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index ea13a58..372d2e5 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -2,10 +2,9 @@ #define _ISP1760_HCD_H_ /* exports for if */ -struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, -int irq, unsigned long irqflags, -struct device *dev, const char *busname, -unsigned int devflags); +int isp1760_register(phys_addr_t res_start, resource_size_t res_len, int irq, +unsigned long irqflags, struct device *dev, +const char *busname, unsigned int devflags); void isp1760_unregister(struct device *dev); int init_kmem_once(void); @@ -112,9 +111,6 @@ struct slotinfo { }; -typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, - struct isp1760_qtd *qtd); - /* * Device flags that can vary from board to board. All of these * indicate the most atypical case, so that a devflags of 0 is diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 64eaf5d..03243b0 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -31,7 +31,6 @@ static int isp1761_pci_probe(struct pci_dev *dev, u8 latency, limit; __u32 reg_data; int retry_count; - struct usb_hcd *hcd; unsigned int devflags = 0; int ret_status = 0; @@ -134,13 +133,11 @@ static int isp1761_pci_probe(struct pci_dev *dev, writel(reg_data, iobase + PLX_INT_CSR_REG); dev-dev.dma_mask = NULL; - hcd = isp1760_register(pci_mem_phy0, memlength, dev-irq, - IRQF_SHARED, dev-dev, dev_name(dev-dev), - devflags); - if (IS_ERR(hcd)) { - ret_status = -ENODEV; + ret_status = isp1760_register(pci_mem_phy0, memlength, dev-irq, + IRQF_SHARED, dev-dev, + dev_name(dev-dev), devflags); + if (ret_status 0) goto cleanup3; - } /* done with PLX IO access */ iounmap(iobase); @@ -198,7 +195,6 @@ static int isp1760_plat_probe(struct platform_device *pdev) struct resource *mem_res; struct resource *irq_res; resource_size_t mem_size; - struct usb_hcd *hcd; int ret; mem_res
[PATCH v3 14/20] usb: isp1760: Move core code to isp1760-core.c
Move core device initialization to a central location in order to share it with the device mode implementation. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/usb/host/Makefile | 2 +- drivers/usb/host/isp1760-core.c | 65 + drivers/usb/host/isp1760-core.h | 33 + drivers/usb/host/isp1760-hcd.c | 42 +++--- drivers/usb/host/isp1760-hcd.h | 8 ++--- drivers/usb/host/isp1760-if.c | 2 +- 6 files changed, 114 insertions(+), 38 deletions(-) create mode 100644 drivers/usb/host/isp1760-core.c create mode 100644 drivers/usb/host/isp1760-core.h diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index d6216a4..4dea9b1 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -5,7 +5,7 @@ # tell define_trace.h where to find the xhci trace header CFLAGS_xhci-trace.o := -I$(src) -isp1760-y := isp1760-hcd.o isp1760-if.o +isp1760-y := isp1760-core.o isp1760-hcd.o isp1760-if.o fhci-y := fhci-hcd.o fhci-hub.o fhci-q.o fhci-y += fhci-mem.o fhci-tds.o fhci-sched.o diff --git a/drivers/usb/host/isp1760-core.c b/drivers/usb/host/isp1760-core.c new file mode 100644 index 000..d38efa0 --- /dev/null +++ b/drivers/usb/host/isp1760-core.c @@ -0,0 +1,65 @@ +/* + * Driver for the NXP ISP1760 chip + * + * Copyright 2014 Laurent Pinchart + * Copyright 2007 Sebastian Siewior + * + * Contacts: + * Sebastian Siewior bige...@linutronix.de + * Laurent Pinchart laurent.pinch...@ideasonboard.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#include linux/gpio.h +#include linux/io.h +#include linux/kernel.h +#include linux/module.h +#include linux/slab.h +#include linux/usb.h + +#include isp1760-core.h +#include isp1760-hcd.h + +int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, +struct device *dev, unsigned int devflags) +{ + struct isp1760_device *isp; + int ret; + + if (usb_disabled()) + return -ENODEV; + + /* prevent usb-core allocating DMA pages */ + dev-dma_mask = NULL; + + isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL); + if (!isp) + return -ENOMEM; + + isp-regs = devm_ioremap_resource(dev, mem); + if (IS_ERR(isp-regs)) + return PTR_ERR(isp-regs); + + ret = isp1760_hcd_register(isp-hcd, isp-regs, mem, irq, irqflags, + dev, devflags); + if (ret 0) + return ret; + + dev_set_drvdata(dev, isp); + + return 0; +} + +void isp1760_unregister(struct device *dev) +{ + struct isp1760_device *isp = dev_get_drvdata(dev); + + isp1760_hcd_unregister(isp-hcd); +} + +MODULE_DESCRIPTION(Driver for the ISP1760 USB-controller from NXP); +MODULE_AUTHOR(Sebastian Siewior bige...@linuxtronix.de); +MODULE_LICENSE(GPL v2); diff --git a/drivers/usb/host/isp1760-core.h b/drivers/usb/host/isp1760-core.h new file mode 100644 index 000..0caeb11 --- /dev/null +++ b/drivers/usb/host/isp1760-core.h @@ -0,0 +1,33 @@ +/* + * Driver for the NXP ISP1760 chip + * + * Copyright 2014 Laurent Pinchart + * Copyright 2007 Sebastian Siewior + * + * Contacts: + * Sebastian Siewior bige...@linutronix.de + * Laurent Pinchart laurent.pinch...@ideasonboard.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#ifndef _ISP1760_CORE_H_ +#define _ISP1760_CORE_H_ + +#include linux/ioport.h + +#include isp1760-hcd.h + +struct isp1760_device { + void __iomem *regs; + + struct isp1760_hcd hcd; +}; + +int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, +struct device *dev, unsigned int devflags); +void isp1760_unregister(struct device *dev); + +#endif diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 50434cc..0cf620b 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -2232,30 +2232,20 @@ void isp1760_deinit_kmem_cache(void) kmem_cache_destroy(urb_listitem_cachep); } -int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, -struct device *dev, unsigned int devflags) +int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs, +struct resource *mem, int irq, unsigned long irqflags, +struct device *dev, unsigned int devflags) { - struct usb_hcd *hcd = NULL; - struct isp1760_hcd *priv; + struct usb_hcd *hcd; int ret; - if (usb_disabled()) - return -ENODEV; - - priv = devm_kzalloc(dev,
[PATCH v3 05/20] usb: isp1760: Fix indentation in probe error path
Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/host/isp1760-hcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 4d6e50b..aa894a1 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -2259,12 +2259,12 @@ int isp1760_register(phys_addr_t res_start, resource_size_t res_len, int irq, return 0; err_unmap: -iounmap(hcd-regs); + iounmap(hcd-regs); err_put: -usb_put_hcd(hcd); + usb_put_hcd(hcd); -return ret; + return ret; } void isp1760_unregister(struct device *dev) -- 2.0.5 -- 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 v3 01/20] usb: isp1760: Merge platform and OF glue codes
Both handle platform devices, merge them. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/usb/host/isp1760-if.c | 190 -- 1 file changed, 55 insertions(+), 135 deletions(-) diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 730caa1..3db98da 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -12,121 +12,18 @@ #include linux/usb.h #include linux/io.h #include linux/module.h +#include linux/of.h #include linux/platform_device.h +#include linux/slab.h #include linux/usb/isp1760.h #include linux/usb/hcd.h #include isp1760-hcd.h -#if defined(CONFIG_OF) defined(CONFIG_OF_IRQ) -#include linux/slab.h -#include linux/of.h -#include linux/of_platform.h -#include linux/of_address.h -#include linux/of_irq.h -#endif - #ifdef CONFIG_PCI #include linux/pci.h #endif -#if defined(CONFIG_OF) defined(CONFIG_OF_IRQ) -static int of_isp1760_probe(struct platform_device *dev) -{ - struct usb_hcd *hcd; - struct device_node *dp = dev-dev.of_node; - struct resource *res; - struct resource memory; - int virq; - resource_size_t res_len; - int ret; - unsigned int devflags = 0; - u32 bus_width = 0; - - ret = of_address_to_resource(dp, 0, memory); - if (ret) - return -ENXIO; - - res_len = resource_size(memory); - - res = request_mem_region(memory.start, res_len, dev_name(dev-dev)); - if (!res) - return -EBUSY; - - virq = irq_of_parse_and_map(dp, 0); - if (!virq) { - ret = -ENODEV; - goto release_reg; - } - - if (of_device_is_compatible(dp, nxp,usb-isp1761)) - devflags |= ISP1760_FLAG_ISP1761; - - /* Some systems wire up only 16 of the 32 data lines */ - of_property_read_u32(dp, bus-width, bus_width); - if (bus_width == 16) - devflags |= ISP1760_FLAG_BUS_WIDTH_16; - - if (of_get_property(dp, port1-otg, NULL) != NULL) - devflags |= ISP1760_FLAG_OTG_EN; - - if (of_get_property(dp, analog-oc, NULL) != NULL) - devflags |= ISP1760_FLAG_ANALOG_OC; - - if (of_get_property(dp, dack-polarity, NULL) != NULL) - devflags |= ISP1760_FLAG_DACK_POL_HIGH; - - if (of_get_property(dp, dreq-polarity, NULL) != NULL) - devflags |= ISP1760_FLAG_DREQ_POL_HIGH; - - hcd = isp1760_register(memory.start, res_len, virq, IRQF_SHARED, - dev-dev, dev_name(dev-dev), devflags); - if (IS_ERR(hcd)) { - ret = PTR_ERR(hcd); - goto release_reg; - } - - platform_set_drvdata(dev, hcd); - return ret; - -release_reg: - release_mem_region(memory.start, res_len); - return ret; -} - -static int of_isp1760_remove(struct platform_device *dev) -{ - struct usb_hcd *hcd = platform_get_drvdata(dev); - - usb_remove_hcd(hcd); - iounmap(hcd-regs); - release_mem_region(hcd-rsrc_start, hcd-rsrc_len); - usb_put_hcd(hcd); - - return 0; -} - -static const struct of_device_id of_isp1760_match[] = { - { - .compatible = nxp,usb-isp1760, - }, - { - .compatible = nxp,usb-isp1761, - }, - { }, -}; -MODULE_DEVICE_TABLE(of, of_isp1760_match); - -static struct platform_driver isp1760_of_driver = { - .driver = { - .name = nxp-isp1760, - .of_match_table = of_isp1760_match, - }, - .probe = of_isp1760_probe, - .remove = of_isp1760_remove, -}; -#endif - #ifdef CONFIG_PCI static int isp1761_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -304,26 +201,23 @@ static struct pci_driver isp1761_pci_driver = { static int isp1760_plat_probe(struct platform_device *pdev) { - int ret = 0; - struct usb_hcd *hcd; + unsigned long irqflags = IRQF_SHARED; + unsigned int devflags = 0; struct resource *mem_res; struct resource *irq_res; resource_size_t mem_size; - struct isp1760_platform_data *priv = dev_get_platdata(pdev-dev); - unsigned int devflags = 0; - unsigned long irqflags = IRQF_SHARED; + struct usb_hcd *hcd; + int ret; mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_res) { pr_warning(isp1760: Memory resource not available\n); - ret = -ENODEV; - goto out; + return -ENODEV; } mem_size = resource_size(mem_res); if (!request_mem_region(mem_res-start, mem_size, isp1760)) { pr_warning(isp1760: Cannot reserve the memory resource\n); - ret = -EBUSY; - goto out; + return -EBUSY; } irq_res = platform_get_resource(pdev,
[PATCH v3 20/20] usb: isp1760: Make HCD support optional
Enable compilation of the isp1760 driver in pure host mode, pure device mode, or dual-role mode. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/usb/isp1760/Kconfig | 47 ++- drivers/usb/isp1760/Makefile | 3 ++- drivers/usb/isp1760/isp1760-hcd.h | 25 + drivers/usb/isp1760/isp1760-udc.h | 4 ++-- 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/drivers/usb/isp1760/Kconfig b/drivers/usb/isp1760/Kconfig index c09ab8f..c94b7d9 100644 --- a/drivers/usb/isp1760/Kconfig +++ b/drivers/usb/isp1760/Kconfig @@ -1,6 +1,6 @@ config USB_ISP1760 tristate NXP ISP 1760/1761 support - depends on USB + depends on USB || USB_GADGET help Say Y or M here if your system as an ISP1760 USB host controller or an ISP1761 USB dual-role controller. @@ -14,9 +14,46 @@ config USB_ISP1760 To compile this driver as a module, choose M here: the module will be called isp1760. +config USB_ISP1760_HCD + bool + config USB_ISP1761_UDC - boolean NXP ISP1761 USB Device Controller - depends on USB_ISP1760 USB_GADGET + bool + +if USB_ISP1760 + +choice + bool ISP1760 Mode Selection + default USB_ISP1760_DUAL_ROLE if (USB USB_GADGET) + default USB_ISP1760_HOST_ROLE if (USB !USB_GADGET) + default USB_ISP1760_GADGET_ROLE if (!USB USB_GADGET) + +config USB_ISP1760_HOST_ROLE + bool Host only mode + depends on USB=y || USB=USB_ISP1760 + select USB_ISP1760_HCD + help + Select this if you want to use the ISP1760 in host mode only. The + gadget function will be disabled. + +config USB_ISP1760_GADGET_ROLE + bool Gadget only mode + depends on USB_GADGET=y || USB_GADGET=USB_ISP1760 + select USB_ISP1761_UDC + help + Select this if you want to use the ISP1760 in peripheral mode only. + The host function will be disabled. + +config USB_ISP1760_DUAL_ROLE + bool Dual Role mode + depends on USB=y || USB=USB_ISP1760 + depends on USB_GADGET=y || USB_GADGET=USB_ISP1760 + select USB_ISP1760_HCD + select USB_ISP1761_UDC help - The NXP ISP1761 is a dual-role high-speed USB host and device - controller. + Select this if you want to use the ISP1760 in both host and + peripheral modes. + +endchoice + +endif diff --git a/drivers/usb/isp1760/Makefile b/drivers/usb/isp1760/Makefile index 698ccb0..2b74107 100644 --- a/drivers/usb/isp1760/Makefile +++ b/drivers/usb/isp1760/Makefile @@ -1,4 +1,5 @@ -isp1760-y := isp1760-core.o isp1760-hcd.o isp1760-if.o +isp1760-y := isp1760-core.o isp1760-if.o +isp1760-$(CONFIG_USB_ISP1760_HCD) += isp1760-hcd.o isp1760-$(CONFIG_USB_ISP1761_UDC) += isp1760-udc.o obj-$(CONFIG_USB_ISP1760) += isp1760.o diff --git a/drivers/usb/isp1760/isp1760-hcd.h b/drivers/usb/isp1760/isp1760-hcd.h index df7ea36..0c1c98d 100644 --- a/drivers/usb/isp1760/isp1760-hcd.h +++ b/drivers/usb/isp1760/isp1760-hcd.h @@ -47,6 +47,7 @@ enum isp1760_queue_head_types { }; struct isp1760_hcd { +#ifdef CONFIG_USB_ISP1760_HCD struct usb_hcd *hcd; u32 hcs_params; @@ -64,8 +65,10 @@ struct isp1760_hcd { unsignedi_thresh; unsigned long reset_done; unsigned long next_statechange; +#endif }; +#ifdef CONFIG_USB_ISP1760_HCD int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs, struct resource *mem, int irq, unsigned long irqflags, struct device *dev); @@ -73,5 +76,27 @@ void isp1760_hcd_unregister(struct isp1760_hcd *priv); int isp1760_init_kmem_once(void); void isp1760_deinit_kmem_cache(void); +#else +static inline int isp1760_hcd_register(struct isp1760_hcd *priv, + void __iomem *regs, struct resource *mem, + int irq, unsigned long irqflags, + struct device *dev) +{ + return 0; +} + +static inline void isp1760_hcd_unregister(struct isp1760_hcd *priv) +{ +} + +static inline int isp1760_init_kmem_once(void) +{ + return 0; +} + +static inline void isp1760_deinit_kmem_cache(void) +{ +} +#endif #endif /* _ISP1760_HCD_H_ */ diff --git a/drivers/usb/isp1760/isp1760-udc.h b/drivers/usb/isp1760/isp1760-udc.h index 4af6ba6..26899ed 100644 --- a/drivers/usb/isp1760/isp1760-udc.h +++ b/drivers/usb/isp1760/isp1760-udc.h @@ -62,7 +62,7 @@ struct isp1760_ep { * connected: Tracks gadget driver bus connection state */ struct isp1760_udc { -#if CONFIG_USB_ISP1761_UDC +#ifdef CONFIG_USB_ISP1761_UDC struct isp1760_device *isp; int irq; @@ -87,7 +87,7 @@ struct isp1760_udc { #endif }; -#if CONFIG_USB_ISP1761_UDC +#ifdef CONFIG_USB_ISP1761_UDC int isp1760_udc_register(struct isp1760_device *isp,
[PATCH v3 07/20] usb: isp1760: Remove busname argument to isp1760_register
The argument is unused, remove it. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/host/isp1760-hcd.c | 2 +- drivers/usb/host/isp1760-hcd.h | 2 +- drivers/usb/host/isp1760-if.c | 6 ++ 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 0ae1719..9ba3023 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -2213,7 +2213,7 @@ void isp1760_deinit_kmem_cache(void) int isp1760_register(phys_addr_t res_start, resource_size_t res_len, int irq, unsigned long irqflags, struct device *dev, -const char *busname, unsigned int devflags) +unsigned int devflags) { struct usb_hcd *hcd; struct isp1760_hcd *priv; diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index f97c9d6..cc65602 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -4,7 +4,7 @@ /* exports for if */ int isp1760_register(phys_addr_t res_start, resource_size_t res_len, int irq, unsigned long irqflags, struct device *dev, -const char *busname, unsigned int devflags); +unsigned int devflags); void isp1760_unregister(struct device *dev); int isp1760_init_kmem_once(void); diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index e268b20..ce572cc 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -134,8 +134,7 @@ static int isp1761_pci_probe(struct pci_dev *dev, dev-dev.dma_mask = NULL; ret_status = isp1760_register(pci_mem_phy0, memlength, dev-irq, - IRQF_SHARED, dev-dev, - dev_name(dev-dev), devflags); + IRQF_SHARED, dev-dev, devflags); if (ret_status 0) goto cleanup3; @@ -259,8 +258,7 @@ static int isp1760_plat_probe(struct platform_device *pdev) } ret = isp1760_register(mem_res-start, mem_size, irq_res-start, - irqflags, pdev-dev, dev_name(pdev-dev), - devflags); + irqflags, pdev-dev, devflags); if (ret 0) goto cleanup; -- 2.0.5 -- 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 v3 09/20] usb: isp1760: Use the managed devm_ioremap_resource() API
This simplifies error and remove code paths. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/usb/host/isp1760-hcd.c | 20 +++- drivers/usb/host/isp1760-if.c | 37 + 2 files changed, 16 insertions(+), 41 deletions(-) diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index e99dafa..2e38efe 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -2234,14 +2234,14 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, priv-rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH); if (IS_ERR(priv-rst_gpio)) { ret = PTR_ERR(priv-rst_gpio); - goto err_put; + goto error; } init_memory(priv); - hcd-regs = ioremap(mem-start, resource_size(mem)); - if (!hcd-regs) { - ret = -EIO; - goto err_put; + hcd-regs = devm_ioremap_resource(dev, mem); + if (IS_ERR(hcd-regs)) { + ret = PTR_ERR(hcd-regs); + goto error; } hcd-irq = irq; @@ -2250,19 +2250,15 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, ret = usb_add_hcd(hcd, irq, irqflags); if (ret) - goto err_unmap; + goto error; device_wakeup_enable(hcd-self.controller); dev_set_drvdata(dev, hcd); return 0; -err_unmap: - iounmap(hcd-regs); - -err_put: +error: usb_put_hcd(hcd); - return ret; } @@ -2271,8 +2267,6 @@ void isp1760_unregister(struct device *dev) struct usb_hcd *hcd = dev_get_drvdata(dev); usb_remove_hcd(hcd); - iounmap(hcd-regs); - release_mem_region(hcd-rsrc_start, hcd-rsrc_len); usb_put_hcd(hcd); } diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 3a9b4f6..dbb287c 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -85,8 +85,9 @@ static int isp1761_pci_probe(struct pci_dev *dev, chip_addr = ioremap_nocache(pci_mem_phy0,memlength); if (!chip_addr) { printk(KERN_ERR Error ioremap failed\n); + release_mem_region(pci_mem_phy0, memlength); ret_status = -ENOMEM; - goto cleanup3; + goto cleanup2; } /* bad pci latencies can contribute to overruns */ @@ -114,6 +115,7 @@ static int isp1761_pci_probe(struct pci_dev *dev, } iounmap(chip_addr); + release_mem_region(pci_mem_phy0, memlength); /* Host Controller presence is detected by writing to scratch register * and reading back and checking the contents are same or not @@ -121,7 +123,7 @@ static int isp1761_pci_probe(struct pci_dev *dev, if (reg_data != 0xFACE) { dev_err(dev-dev, scratch register mismatch %x\n, reg_data); ret_status = -ENOMEM; - goto cleanup3; + goto cleanup2; } pci_set_master(dev); @@ -132,20 +134,14 @@ static int isp1761_pci_probe(struct pci_dev *dev, reg_data |= 0x900; writel(reg_data, iobase + PLX_INT_CSR_REG); - dev-dev.dma_mask = NULL; - ret_status = isp1760_register(dev-resource[3], dev-irq, IRQF_SHARED, - dev-dev, devflags); - if (ret_status 0) - goto cleanup3; - /* done with PLX IO access */ iounmap(iobase); release_mem_region(nxp_pci_io_base, iolength); - return 0; + dev-dev.dma_mask = NULL; + return isp1760_register(dev-resource[3], dev-irq, IRQF_SHARED, + dev-dev, devflags); -cleanup3: - release_mem_region(pci_mem_phy0, memlength); cleanup2: iounmap(iobase); cleanup1: @@ -193,25 +189,14 @@ static int isp1760_plat_probe(struct platform_device *pdev) unsigned int devflags = 0; struct resource *mem_res; struct resource *irq_res; - resource_size_t mem_size; int ret; mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - pr_warning(isp1760: Memory resource not available\n); - return -ENODEV; - } - mem_size = resource_size(mem_res); - if (!request_mem_region(mem_res-start, mem_size, isp1760)) { - pr_warning(isp1760: Cannot reserve the memory resource\n); - return -EBUSY; - } irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq_res) { pr_warning(isp1760: IRQ resource not available\n); - ret = -ENODEV; - goto cleanup; + return -ENODEV; } irqflags |= irq_res-flags IRQF_TRIGGER_MASK; @@ -260,14 +245,10 @@ static int isp1760_plat_probe(struct platform_device *pdev)
[PATCH v3 00/20] Add UDC support to the isp1760 driver
Hello, This patch set adds UDC support to the isp1760 driver, to be used with the ISP1761 dual-role USB controller. The first 17 patches rework the isp1760 driver to prepare it for UDC support. In particular they removes the direct HCD dependencies from the glue code (01/20 to 04/20), creates core initialization code shared by the HCD and UDC (15/20) and move common initialization code to the core (16/20 to 17/20). Patch 18/20 adds UDC support, and patches 19/20 and 20/20 move the driver to drivers/usb/isp1760/ and make HCD support optional. The ISP1761 has three USB ports, with port 1 configurable in host or peripheral mode with OTG support, and ports 2 and 3 supporting host mode only. OTG support is not implemented yet, port 1 can thus be configured in host or peripheral mode only. The UDC driver has been successfully tested with the g_zero and g_mass_storage gadgets. Global changes compared to v2: - Rebase on top of Felipe's testing/next branch - Drop patches that have been merged already - Add patch 19/20 and 20/20 Global changes compared to v1: - Replace GPIO request move by patch 01/22 - Split PORT1 configuration to separate patch - Drop the shutdown implementation patch - Add patches 02/22, 04/22, 05/22, 13/22, 14/22 See individual patches for patch-specific changes. Laurent Pinchart (20): usb: isp1760: Merge platform and OF glue codes usb: isp1760: Move removal cleanup code to isp1760-hcd.c usb: isp1760: Manage device driver data in common code usb: isp1760: Don't expose hcd to glue code from isp1760_register usb: isp1760: Fix indentation in probe error path usb: isp1760: Prefix init_kmem_once and deinit_kmem_cache with isp1760_ usb: isp1760: Remove busname argument to isp1760_register usb: isp1760: Pass resource pointer to isp1760_register usb: isp1760: Use the managed devm_ioremap_resource() API usb: isp1760: Refactor PCI initialization code usb: isp1760: Decouple usb_hdc and isp1760_priv usb: isp1760: Prefix driver data structures with isp1760_ usb: isp1760: Reorganize header files usb: isp1760: Move core code to isp1760-core.c usb: isp1760: Set IRQF_SHARED flag in core code usb: isp1760: Initialize the bus interface in core code usb: isp1760: Move PORT1 configuration to core code usb: isp1760: Add device controller support usb: isp1760: Move driver from drivers/usb/host/ to drivers/usb/isp1760/ usb: isp1760: Make HCD support optional drivers/usb/Kconfig|2 + drivers/usb/Makefile |2 +- drivers/usb/host/Kconfig | 14 - drivers/usb/host/Makefile |3 +- drivers/usb/host/isp1760-hcd.c | 2268 drivers/usb/host/isp1760-hcd.h | 206 drivers/usb/host/isp1760-if.c | 431 --- drivers/usb/isp1760/Kconfig| 59 + drivers/usb/isp1760/Makefile |5 + drivers/usb/isp1760/isp1760-core.c | 171 +++ drivers/usb/isp1760/isp1760-core.h | 68 ++ drivers/usb/isp1760/isp1760-hcd.c | 2231 +++ drivers/usb/isp1760/isp1760-hcd.h | 102 ++ drivers/usb/isp1760/isp1760-if.c | 312 + drivers/usb/isp1760/isp1760-regs.h | 230 drivers/usb/isp1760/isp1760-udc.c | 1495 drivers/usb/isp1760/isp1760-udc.h | 106 ++ 17 files changed, 4784 insertions(+), 2921 deletions(-) delete mode 100644 drivers/usb/host/isp1760-hcd.c delete mode 100644 drivers/usb/host/isp1760-hcd.h delete mode 100644 drivers/usb/host/isp1760-if.c create mode 100644 drivers/usb/isp1760/Kconfig create mode 100644 drivers/usb/isp1760/Makefile create mode 100644 drivers/usb/isp1760/isp1760-core.c create mode 100644 drivers/usb/isp1760/isp1760-core.h create mode 100644 drivers/usb/isp1760/isp1760-hcd.c create mode 100644 drivers/usb/isp1760/isp1760-hcd.h create mode 100644 drivers/usb/isp1760/isp1760-if.c create mode 100644 drivers/usb/isp1760/isp1760-regs.h create mode 100644 drivers/usb/isp1760/isp1760-udc.c create mode 100644 drivers/usb/isp1760/isp1760-udc.h -- Regards, Laurent Pinchart -- 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 v3 10/20] usb: isp1760: Refactor PCI initialization code
Move the initialization code out of the PCI probe function to a new function in order to simplify and fix error handling. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/usb/host/isp1760-if.c | 134 ++ 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index dbb287c..7c03320 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -25,69 +25,34 @@ #endif #ifdef CONFIG_PCI -static int isp1761_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) +static int isp1761_pci_init(struct pci_dev *dev) { + resource_size_t mem_start; + resource_size_t mem_length; + u8 __iomem *iobase; u8 latency, limit; - __u32 reg_data; int retry_count; - unsigned int devflags = 0; - int ret_status = 0; - - resource_size_t pci_mem_phy0; - resource_size_t memlength; + u32 reg_data; - u8 __iomem *chip_addr; - u8 __iomem *iobase; - resource_size_t nxp_pci_io_base; - resource_size_t iolength; - - if (usb_disabled()) - return -ENODEV; - - if (pci_enable_device(dev) 0) - return -ENODEV; - - if (!dev-irq) - return -ENODEV; - - /* Grab the PLX PCI mem maped port start address we need */ - nxp_pci_io_base = pci_resource_start(dev, 0); - iolength = pci_resource_len(dev, 0); - - if (!request_mem_region(nxp_pci_io_base, iolength, ISP1761 IO MEM)) { - printk(KERN_ERR request region #1\n); - return -EBUSY; - } - - iobase = ioremap_nocache(nxp_pci_io_base, iolength); - if (!iobase) { - printk(KERN_ERR ioremap #1\n); - ret_status = -ENOMEM; - goto cleanup1; - } /* Grab the PLX PCI shared memory of the ISP 1761 we need */ - pci_mem_phy0 = pci_resource_start(dev, 3); - memlength = pci_resource_len(dev, 3); - if (memlength 0x) { + mem_start = pci_resource_start(dev, 3); + mem_length = pci_resource_len(dev, 3); + if (mem_length 0x) { printk(KERN_ERR memory length for this resource is wrong\n); - ret_status = -ENOMEM; - goto cleanup2; + return -ENOMEM; } - if (!request_mem_region(pci_mem_phy0, memlength, ISP-PCI)) { + if (!request_mem_region(mem_start, mem_length, ISP-PCI)) { printk(KERN_ERR host controller already in use\n); - ret_status = -EBUSY; - goto cleanup2; + return -EBUSY; } /* map available memory */ - chip_addr = ioremap_nocache(pci_mem_phy0,memlength); - if (!chip_addr) { + iobase = ioremap_nocache(mem_start, mem_length); + if (!iobase) { printk(KERN_ERR Error ioremap failed\n); - release_mem_region(pci_mem_phy0, memlength); - ret_status = -ENOMEM; - goto cleanup2; + release_mem_region(mem_start, mem_length); + return -ENOMEM; } /* bad pci latencies can contribute to overruns */ @@ -108,25 +73,38 @@ static int isp1761_pci_probe(struct pci_dev *dev, /*by default host is in 16bit mode, so * io operations at this stage must be 16 bit * */ - writel(0xface, chip_addr + HC_SCRATCH_REG); + writel(0xface, iobase + HC_SCRATCH_REG); udelay(100); - reg_data = readl(chip_addr + HC_SCRATCH_REG) 0x; + reg_data = readl(iobase + HC_SCRATCH_REG) 0x; retry_count--; } - iounmap(chip_addr); - release_mem_region(pci_mem_phy0, memlength); + iounmap(iobase); + release_mem_region(mem_start, mem_length); /* Host Controller presence is detected by writing to scratch register * and reading back and checking the contents are same or not */ if (reg_data != 0xFACE) { dev_err(dev-dev, scratch register mismatch %x\n, reg_data); - ret_status = -ENOMEM; - goto cleanup2; + return -ENOMEM; } - pci_set_master(dev); + /* Grab the PLX PCI mem maped port start address we need */ + mem_start = pci_resource_start(dev, 0); + mem_length = pci_resource_len(dev, 0); + + if (!request_mem_region(mem_start, mem_length, ISP1761 IO MEM)) { + printk(KERN_ERR request region #1\n); + return -EBUSY; + } + + iobase = ioremap_nocache(mem_start, mem_length); + if (!iobase) { + printk(KERN_ERR ioremap #1\n); + release_mem_region(mem_start, mem_length); + return -ENOMEM; + }
[PATCH v3 13/20] usb: isp1760: Reorganize header files
The isp1760-rhcd.h header contains PTD constants and structures only useful for the HCD implementation. It also contains register definitions that will be needed by common code when implementing support for the ISP1761 device controller, but doesn't contain the isp1760_hcd structure definition that will also be used by common code. Move definitions to the right location and create an isp1760-regs.h to store register definitions. No change other than moving definitions and modifying indentation is performed. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/host/isp1760-hcd.c | 130 +-- drivers/usb/host/isp1760-hcd.h | 230 +++- drivers/usb/host/isp1760-if.c | 1 + drivers/usb/host/isp1760-regs.h | 120 + 4 files changed, 256 insertions(+), 225 deletions(-) create mode 100644 drivers/usb/host/isp1760-regs.h diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 99f56c6..50434cc 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -27,41 +27,12 @@ #include asm/cacheflush.h #include isp1760-hcd.h +#include isp1760-regs.h static struct kmem_cache *qtd_cachep; static struct kmem_cache *qh_cachep; static struct kmem_cache *urb_listitem_cachep; -enum queue_head_types { - QH_CONTROL, - QH_BULK, - QH_INTERRUPT, - QH_END -}; - -struct isp1760_hcd { - struct usb_hcd *hcd; - - u32 hcs_params; - spinlock_t lock; - struct isp1760_slotinfo atl_slots[32]; - int atl_done_map; - struct isp1760_slotinfo int_slots[32]; - int int_done_map; - struct isp1760_memory_chunk memory_pool[BLOCKS]; - struct list_headqh_list[QH_END]; - - /* periodic schedule support */ -#defineDEFAULT_I_TDPS 1024 - unsignedperiodic_size; - unsignedi_thresh; - unsigned long reset_done; - unsigned long next_statechange; - unsigned intdevflags; - - struct gpio_desc*rst_gpio; -}; - typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, struct isp1760_qtd *qtd); @@ -70,32 +41,79 @@ static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) return *(struct isp1760_hcd **)hcd-hcd_priv; } -/* Section 2.2 Host Controller Capability Registers */ -#define HC_LENGTH(p) (((p)00)0x00ff) /* bits 7:0 */ -#define HC_VERSION(p) (((p)16)0x) /* bits 31:16 */ -#define HCS_INDICATOR(p) ((p)(1 16)) /* true: has port indicators */ -#define HCS_PPC(p) ((p)(1 4)) /* true: port power control */ -#define HCS_N_PORTS(p) (((p)0)0xf) /* bits 3:0, ports on HC */ -#define HCC_ISOC_CACHE(p) ((p)(1 7)) /* true: can cache isoc frame */ -#define HCC_ISOC_THRES(p) (((p)4)0x7) /* bits 6:4, uframes cached */ - -/* Section 2.3 Host Controller Operational Registers */ -#define CMD_LRESET (17) /* partial reset (no ports, etc) */ -#define CMD_RESET (11) /* reset HC not bus */ -#define CMD_RUN(10) /* start/stop HC */ -#define STS_PCD(12) /* port change detect */ -#define FLAG_CF(10) /* true: we'll support high speed */ - -#define PORT_OWNER (113) /* true: companion hc owns this port */ -#define PORT_POWER (112) /* true: has power (see PPC) */ -#define PORT_USB11(x) (((x) (3 10)) == (1 10)) /* USB 1.1 device */ -#define PORT_RESET (18) /* reset port */ -#define PORT_SUSPEND (17) /* suspend port */ -#define PORT_RESUME(16) /* resume it */ -#define PORT_PE(12) /* port enable */ -#define PORT_CSC (11) /* connect status change */ -#define PORT_CONNECT (10) /* device connected */ -#define PORT_RWC_BITS (PORT_CSC) +/* urb state*/ +#define DELETE_URB (0x0008) +#define NO_TRANSFER_ACTIVE (0x) + +/* Philips Proprietary Transfer Descriptor (PTD) */ +typedef __u32 __bitwise __dw; +struct ptd { + __dw dw0; + __dw dw1; + __dw dw2; + __dw dw3; + __dw dw4; + __dw dw5; + __dw dw6; + __dw dw7; +}; +#define PTD_OFFSET 0x0400 +#define ISO_PTD_OFFSET 0x0400 +#define INT_PTD_OFFSET 0x0800 +#define ATL_PTD_OFFSET 0x0c00 +#define PAYLOAD_OFFSET 0x1000 + + +/* ATL */ +/* DW0 */ +#define DW0_VALID_BIT 1 +#define FROM_DW0_VALID(x) ((x) 0x01) +#define TO_DW0_LENGTH(x) (((u32) x) 3) +#define TO_DW0_MAXPACKET(x)(((u32) x) 18) +#define TO_DW0_MULTI(x)(((u32) x) 29) +#define
[PATCH v3 18/20] usb: isp1760: Add device controller support
The ISP1761 is a dual-mode host and device controller backward compatible on the host side with the ISP1760. Add support for the device controller. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Changes since v2: - Update .udc_stop API Changes since v1: - Reject SET_ADDRESS in states other than default and addressed - Unregister the HCD if initialization fails due to the UDC - Remove unnecessary sleep during initialization - Use the usb_gadget_udc_reset API - Add VBUS disconnection timer - Clean up comments - Clean up ep0_status usage usb: isp1760-udc: Reset stall flag when enabling the endpoint usb: isp1760-udc: Move lock from __isp1760_udc_set_stall to the callers usb: isp1760-udc: Move uninitialized endpoint check to isp1760_udc_set_halt usb: isp1760-udc: Refuse to halt IN endpoints with queued transfers usb: isp1760-udc: Reset EP0 state to SETUP when halting the endpoint usb: isp1760-udc: Differentiate protocol and functional stall usb: isp1760-udc: Release the UDC lock before completing request usb: isp1760-udc: Move to the status stage after completing the request usb: isp1760-udc: Stop the UDC when unregistering the gadget usb: isp1760-udc: Properly delegate non-standard control requests to gadget usb: isp1760-udc: Handle gadget device registration errors usb: isp1760-udc: Reject invalid SET_CONFIGURATION requests usb: isp1760-udc: Update device state in SET_CONFIGURATION usb: isp1760-udc: Fix oops at gadget registration when UDC probe failed usb: isp1760-udc: Print scratch register value when scratch test fails usb: isp1760-udc: Call the right operation in USB resume handler usb: isp1760-udc: Update to the latest UDC API usb: isp1760-udc: Fix locking in isp1760_udc_request_complete() usb: isp1760-udc: Remove fifo_status operation usb: isp1760-udc: Implement the flush_fifo operation usb: isp1760-udc: Improve request dequeue operation debug message usb: isp1760-udc: Implement wedge support --- drivers/usb/gadget/udc/Kconfig |7 + drivers/usb/host/Makefile |1 + drivers/usb/host/isp1760-core.c | 50 +- drivers/usb/host/isp1760-core.h |4 + drivers/usb/host/isp1760-regs.h | 110 +++ drivers/usb/host/isp1760-udc.c | 1495 +++ drivers/usb/host/isp1760-udc.h | 106 +++ 7 files changed, 1768 insertions(+), 5 deletions(-) create mode 100644 drivers/usb/host/isp1760-udc.c create mode 100644 drivers/usb/host/isp1760-udc.h diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index b8e213e..c9152e2 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -109,6 +109,13 @@ config USB_GR_UDC Select this to support Aeroflex Gaisler GRUSBDC cores from the GRLIB VHDL IP core library. +config USB_ISP1761_UDC + boolean NXP ISP1761 USB Device Controller + depends on USB_ISP1760_HCD + help + The NXP ISP1761 is a dual-role high-speed USB host and device + controller. + config USB_OMAP tristate OMAP USB Device Controller depends on ARCH_OMAP1 diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 4dea9b1..67d3f18 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -6,6 +6,7 @@ CFLAGS_xhci-trace.o := -I$(src) isp1760-y := isp1760-core.o isp1760-hcd.o isp1760-if.o +isp1760-$(CONFIG_USB_ISP1761_UDC) += isp1760-udc.o fhci-y := fhci-hcd.o fhci-hub.o fhci-q.o fhci-y += fhci-mem.o fhci-tds.o fhci-sched.o diff --git a/drivers/usb/host/isp1760-core.c b/drivers/usb/host/isp1760-core.c index 1cba3e0..727e90a 100644 --- a/drivers/usb/host/isp1760-core.c +++ b/drivers/usb/host/isp1760-core.c @@ -24,9 +24,11 @@ #include isp1760-core.h #include isp1760-hcd.h #include isp1760-regs.h +#include isp1760-udc.h static void isp1760_init_core(struct isp1760_device *isp) { + u32 otgctrl; u32 hwmode; /* Low-level chip reset */ @@ -60,6 +62,17 @@ static void isp1760_init_core(struct isp1760_device *isp) hwmode |= HW_INTR_EDGE_TRIG; /* +* The ISP1761 has a dedicated DC IRQ line but supports sharing the HC +* IRQ line for both the host and device controllers. Hardcode IRQ +* sharing for now and disable the DC interrupts globally to avoid +* spurious interrupts during HCD registration. +*/ + if (isp-devflags ISP1760_FLAG_ISP1761) { + isp1760_write32(isp-regs, DC_MODE, 0); + hwmode |= HW_COMN_IRQ; + } + + /* * We have to set this first in case we're in 16-bit mode. * Write it twice to ensure correct upper bits if switching * to 16-bit mode. @@ -68,18 +81,33 @@ static void isp1760_init_core(struct isp1760_device *isp) isp1760_write32(isp-regs, HC_HW_MODE_CTRL, hwmode); /* -* PORT 1 Control register of the ISP1760 is the OTG control register on -* ISP1761. Since there is no OTG or
[PATCH v3 08/20] usb: isp1760: Pass resource pointer to isp1760_register
The function takes quite a few arguments, passing the resource pointer instead of the start address and length simplifies it a bit. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/host/isp1760-hcd.c | 11 +-- drivers/usb/host/isp1760-hcd.h | 5 ++--- drivers/usb/host/isp1760-if.c | 8 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 9ba3023..e99dafa 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -2211,9 +2211,8 @@ void isp1760_deinit_kmem_cache(void) kmem_cache_destroy(urb_listitem_cachep); } -int isp1760_register(phys_addr_t res_start, resource_size_t res_len, int irq, -unsigned long irqflags, struct device *dev, -unsigned int devflags) +int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, +struct device *dev, unsigned int devflags) { struct usb_hcd *hcd; struct isp1760_hcd *priv; @@ -2239,15 +2238,15 @@ int isp1760_register(phys_addr_t res_start, resource_size_t res_len, int irq, } init_memory(priv); - hcd-regs = ioremap(res_start, res_len); + hcd-regs = ioremap(mem-start, resource_size(mem)); if (!hcd-regs) { ret = -EIO; goto err_put; } hcd-irq = irq; - hcd-rsrc_start = res_start; - hcd-rsrc_len = res_len; + hcd-rsrc_start = mem-start; + hcd-rsrc_len = resource_size(mem); ret = usb_add_hcd(hcd, irq, irqflags); if (ret) diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index cc65602..7fc510f 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -2,9 +2,8 @@ #define _ISP1760_HCD_H_ /* exports for if */ -int isp1760_register(phys_addr_t res_start, resource_size_t res_len, int irq, -unsigned long irqflags, struct device *dev, -unsigned int devflags); +int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, +struct device *dev, unsigned int devflags); void isp1760_unregister(struct device *dev); int isp1760_init_kmem_once(void); diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index ce572cc..3a9b4f6 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -133,8 +133,8 @@ static int isp1761_pci_probe(struct pci_dev *dev, writel(reg_data, iobase + PLX_INT_CSR_REG); dev-dev.dma_mask = NULL; - ret_status = isp1760_register(pci_mem_phy0, memlength, dev-irq, - IRQF_SHARED, dev-dev, devflags); + ret_status = isp1760_register(dev-resource[3], dev-irq, IRQF_SHARED, + dev-dev, devflags); if (ret_status 0) goto cleanup3; @@ -257,8 +257,8 @@ static int isp1760_plat_probe(struct platform_device *pdev) devflags |= ISP1760_FLAG_DREQ_POL_HIGH; } - ret = isp1760_register(mem_res-start, mem_size, irq_res-start, - irqflags, pdev-dev, devflags); + ret = isp1760_register(mem_res, irq_res-start, irqflags, pdev-dev, + devflags); if (ret 0) goto cleanup; -- 2.0.5 -- 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 v3 17/20] usb: isp1760: Move PORT1 configuration to core code
Configuring the mode of operation of port 1 doesn't belong to the HCD code, as it's related to the soon to come UDC support. Move the configuration to core code. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/usb/host/isp1760-core.c | 8 drivers/usb/host/isp1760-hcd.c | 9 - 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/isp1760-core.c b/drivers/usb/host/isp1760-core.c index e840a1d..1cba3e0 100644 --- a/drivers/usb/host/isp1760-core.c +++ b/drivers/usb/host/isp1760-core.c @@ -67,6 +67,14 @@ static void isp1760_init_core(struct isp1760_device *isp) isp1760_write32(isp-regs, HC_HW_MODE_CTRL, hwmode); isp1760_write32(isp-regs, HC_HW_MODE_CTRL, hwmode); + /* +* PORT 1 Control register of the ISP1760 is the OTG control register on +* ISP1761. Since there is no OTG or device controller support in this +* driver, we use port 1 as a normal USB host port on both chips. +*/ + isp1760_write32(isp-regs, HC_PORT1_CTRL, PORT1_POWER | PORT1_INIT2); + usleep_range(1, 11000); + dev_info(isp-dev, bus width: %u, oc: %s\n, isp-devflags ISP1760_FLAG_BUS_WIDTH_16 ? 16 : 32, isp-devflags ISP1760_FLAG_ANALOG_OC ? analog : digital); diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 5309d73..568446c 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -503,15 +503,6 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) reg_write32(hcd-regs, HC_INTERRUPT_ENABLE, INTERRUPT_ENABLE_MASK); - /* -* PORT 1 Control register of the ISP1760 is the OTG control -* register on ISP1761. Since there is no OTG or device controller -* support in this driver, we use port 1 as a normal USB host port on -* both chips. -*/ - reg_write32(hcd-regs, HC_PORT1_CTRL, PORT1_POWER | PORT1_INIT2); - mdelay(10); - priv-hcs_params = reg_read32(hcd-regs, HC_HCSPARAMS); return priv_init(hcd); -- 2.0.5 -- 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 v3 15/20] usb: isp1760: Set IRQF_SHARED flag in core code
The IRQF_SHARED flag needs to be set regardless of the bus type. Don't require glue code to set it manually. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/host/isp1760-core.c | 4 ++-- drivers/usb/host/isp1760-if.c | 9 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/isp1760-core.c b/drivers/usb/host/isp1760-core.c index d38efa0..35278a8 100644 --- a/drivers/usb/host/isp1760-core.c +++ b/drivers/usb/host/isp1760-core.c @@ -43,8 +43,8 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, if (IS_ERR(isp-regs)) return PTR_ERR(isp-regs); - ret = isp1760_hcd_register(isp-hcd, isp-regs, mem, irq, irqflags, - dev, devflags); + ret = isp1760_hcd_register(isp-hcd, isp-regs, mem, irq, + irqflags | IRQF_SHARED, dev, devflags); if (ret 0) return ret; diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index f2a3990..c2a94c9 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -142,8 +142,8 @@ static int isp1761_pci_probe(struct pci_dev *dev, pci_set_master(dev); dev-dev.dma_mask = NULL; - ret = isp1760_register(dev-resource[3], dev-irq, IRQF_SHARED, - dev-dev, devflags); + ret = isp1760_register(dev-resource[3], dev-irq, 0, dev-dev, + devflags); if (ret 0) goto error; @@ -190,7 +190,7 @@ static struct pci_driver isp1761_pci_driver = { static int isp1760_plat_probe(struct platform_device *pdev) { - unsigned long irqflags = IRQF_SHARED; + unsigned long irqflags; unsigned int devflags = 0; struct resource *mem_res; struct resource *irq_res; @@ -203,8 +203,7 @@ static int isp1760_plat_probe(struct platform_device *pdev) pr_warning(isp1760: IRQ resource not available\n); return -ENODEV; } - - irqflags |= irq_res-flags IRQF_TRIGGER_MASK; + irqflags = irq_res-flags IRQF_TRIGGER_MASK; if (IS_ENABLED(CONFIG_OF) pdev-dev.of_node) { struct device_node *dp = pdev-dev.of_node; -- 2.0.5 -- 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 v3 06/20] usb: isp1760: Prefix init_kmem_once and deinit_kmem_cache with isp1760_
The two functions are specific to the driver but have very generic names, subject to collisions. Rename them. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/host/isp1760-hcd.c | 4 ++-- drivers/usb/host/isp1760-hcd.h | 4 ++-- drivers/usb/host/isp1760-if.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index aa894a1..0ae1719 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -2177,7 +2177,7 @@ static const struct hc_driver isp1760_hc_driver = { .clear_tt_buffer_complete = isp1760_clear_tt_buffer_complete, }; -int __init init_kmem_once(void) +int __init isp1760_init_kmem_once(void) { urb_listitem_cachep = kmem_cache_create(isp1760_urb_listitem, sizeof(struct urb_listitem), 0, SLAB_TEMPORARY | @@ -2204,7 +2204,7 @@ int __init init_kmem_once(void) return 0; } -void deinit_kmem_cache(void) +void isp1760_deinit_kmem_cache(void) { kmem_cache_destroy(qtd_cachep); kmem_cache_destroy(qh_cachep); diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index 372d2e5..f97c9d6 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -7,8 +7,8 @@ int isp1760_register(phys_addr_t res_start, resource_size_t res_len, int irq, const char *busname, unsigned int devflags); void isp1760_unregister(struct device *dev); -int init_kmem_once(void); -void deinit_kmem_cache(void); +int isp1760_init_kmem_once(void); +void isp1760_deinit_kmem_cache(void); /* EHCI capability registers */ #define HC_CAPLENGTH 0x00 diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 03243b0..e268b20 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -301,7 +301,7 @@ static int __init isp1760_init(void) { int ret, any_ret = -ENODEV; - init_kmem_once(); + isp1760_init_kmem_once(); ret = platform_driver_register(isp1760_plat_driver); if (!ret) @@ -313,7 +313,7 @@ static int __init isp1760_init(void) #endif if (any_ret) - deinit_kmem_cache(); + isp1760_deinit_kmem_cache(); return any_ret; } module_init(isp1760_init); @@ -324,6 +324,6 @@ static void __exit isp1760_exit(void) #ifdef CONFIG_PCI pci_unregister_driver(isp1761_pci_driver); #endif - deinit_kmem_cache(); + isp1760_deinit_kmem_cache(); } module_exit(isp1760_exit); -- 2.0.5 -- 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 v3 12/20] usb: isp1760: Prefix driver data structures with isp1760_
The slotinfo and memory_chunk structures are specific to the driver and defined in a header file. Prefix them with isp1760_ to avoid namespace clashes. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- drivers/usb/host/isp1760-hcd.c | 15 --- drivers/usb/host/isp1760-hcd.h | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 55c0add..99f56c6 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -44,11 +44,11 @@ struct isp1760_hcd { u32 hcs_params; spinlock_t lock; - struct slotinfo atl_slots[32]; + struct isp1760_slotinfo atl_slots[32]; int atl_done_map; - struct slotinfo int_slots[32]; + struct isp1760_slotinfo int_slots[32]; int int_done_map; - struct memory_chunk memory_pool[BLOCKS]; + struct isp1760_memory_chunk memory_pool[BLOCKS]; struct list_headqh_list[QH_END]; /* periodic schedule support */ @@ -743,8 +743,9 @@ static void qtd_free(struct isp1760_qtd *qtd) } static void start_bus_transfer(struct usb_hcd *hcd, u32 ptd_offset, int slot, - struct slotinfo *slots, struct isp1760_qtd *qtd, - struct isp1760_qh *qh, struct ptd *ptd) + struct isp1760_slotinfo *slots, + struct isp1760_qtd *qtd, struct isp1760_qh *qh, + struct ptd *ptd) { struct isp1760_hcd *priv = hcd_to_priv(hcd); int skip_map; @@ -857,7 +858,7 @@ static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh) { struct isp1760_hcd *priv = hcd_to_priv(hcd); int ptd_offset; - struct slotinfo *slots; + struct isp1760_slotinfo *slots; int curr_slot, free_slot; int n; struct ptd ptd; @@ -1097,7 +1098,7 @@ static void handle_done_ptds(struct usb_hcd *hcd) struct isp1760_qh *qh; int slot; int state; - struct slotinfo *slots; + struct isp1760_slotinfo *slots; u32 ptd_offset; struct isp1760_qtd *qtd; int modified; diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index 7fc510f..3056bcd 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -103,7 +103,7 @@ struct ptd { #define ATL_PTD_OFFSET 0x0c00 #define PAYLOAD_OFFSET 0x1000 -struct slotinfo { +struct isp1760_slotinfo { struct isp1760_qh *qh; struct isp1760_qtd *qtd; unsigned long timestamp; @@ -125,7 +125,7 @@ struct slotinfo { #define ISP1760_FLAG_INTR_EDGE_TRIG0x0100 /* Interrupt edge triggered */ /* chip memory management */ -struct memory_chunk { +struct isp1760_memory_chunk { unsigned int start; unsigned int size; unsigned int free; -- 2.0.5 -- 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 v3 11/20] usb: isp1760: Decouple usb_hdc and isp1760_priv
Allocate the driver private data structure manually instead of using the usb_hcd private space. This will allow skipping hcd registration for the isp1761 when used in device mode only. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Felipe Balbi ba...@ti.com --- Changes since v1: - Use the devm_kzalloc managed allocator --- drivers/usb/host/isp1760-hcd.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 2e38efe..55c0add 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -40,6 +40,8 @@ enum queue_head_types { }; struct isp1760_hcd { + struct usb_hcd *hcd; + u32 hcs_params; spinlock_t lock; struct slotinfo atl_slots[32]; @@ -65,7 +67,7 @@ typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) { - return (struct isp1760_hcd *) (hcd-hcd_priv); + return *(struct isp1760_hcd **)hcd-hcd_priv; } /* Section 2.2 Host Controller Capability Registers */ @@ -2161,7 +2163,7 @@ static void isp1760_clear_tt_buffer_complete(struct usb_hcd *hcd, static const struct hc_driver isp1760_hc_driver = { .description= isp1760-hcd, .product_desc = NXP ISP1760 USB Host Controller, - .hcd_priv_size = sizeof(struct isp1760_hcd), + .hcd_priv_size = sizeof(struct isp1760_hcd *), .irq= isp1760_irq, .flags = HCD_MEMORY | HCD_USB2, .reset = isp1760_hc_setup, @@ -2214,13 +2216,17 @@ void isp1760_deinit_kmem_cache(void) int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, struct device *dev, unsigned int devflags) { - struct usb_hcd *hcd; + struct usb_hcd *hcd = NULL; struct isp1760_hcd *priv; int ret; if (usb_disabled()) return -ENODEV; + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + /* prevent usb-core allocating DMA pages */ dev-dma_mask = NULL; @@ -2228,7 +2234,9 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, if (!hcd) return -ENOMEM; - priv = hcd_to_priv(hcd); + priv-hcd = hcd; + *(struct isp1760_hcd **)hcd-hcd_priv = priv; + priv-devflags = devflags; priv-rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH); @@ -2253,7 +2261,7 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, goto error; device_wakeup_enable(hcd-self.controller); - dev_set_drvdata(dev, hcd); + dev_set_drvdata(dev, priv); return 0; @@ -2264,7 +2272,8 @@ error: void isp1760_unregister(struct device *dev) { - struct usb_hcd *hcd = dev_get_drvdata(dev); + struct isp1760_hcd *priv = dev_get_drvdata(dev); + struct usb_hcd *hcd = priv-hcd; usb_remove_hcd(hcd); usb_put_hcd(hcd); -- 2.0.5 -- 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
E-mail® Account
Our records indicate that your E-mail® Account could not be automatically updated with our F-Secure R-HTK4S new(2015) version anti-spam/anti-virus/anti-spyware. Please click this link below to update manually http://onulineuekpdat.jigsy.com/ We Are Sorry For Any Inconvenience. Regards, Technical Support Team Copyright © 2014. All Rights Reserved -- 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: net2280: tracing
On 12/29/2014 02:58 PM, Felipe Balbi wrote: Hi, On Mon, Dec 29, 2014 at 02:56:25PM -0500, Jorge Ramirez-Ortiz wrote: On 12/29/2014 11:37 AM, Felipe Balbi wrote: Hi, On Sun, Dec 28, 2014 at 07:28:33PM -0500, Jorge Ramirez-Ortiz wrote: On 12/28/2014 11:39 AM, Felipe Balbi wrote: On Sat, Dec 27, 2014 at 05:33:36PM -0500, Jorge Ramirez-Ortiz wrote: Hi Ricardo/all I finally got around to capture a trace of a SS bulk transfer using the net2280. The trace is available to anyone interested (70 MB file for the Beaglebone 5000). can you publish the trace somewhere we can download ? I use Beagle5000 myself and could help revieweing the traces. Thanks Felipe. I dont have any public ftp server at hand so I just pushed the log to my Xenomai git tree. please grab it from here (no need to clone the tree, just press the download link) http://git.xenomai.org/xenomai-jro.git/commit/?h=logs One of the reasons could be because you're using the printer gadget :-) Have you tried any of the other gadgets ? In any case, try this little hack: diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 9054598..8a09661 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -129,7 +129,7 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR); /* holds our biggest descriptor */ #define USB_DESC_BUFSIZE 256 -#define USB_BUFSIZE8192 +#define USB_BUFSIZE65536 static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, yes I thought about that as well: in fact the trace I made available already had that modification in place. (it also has the queue length increased to 20 - no more changes after those two) oh, ok. That would mean the IP can't pump more data :-s for simplicity -and to have a common test vehicle- I'll capture a trace using the g_mass_storage (last time I run that check the performance numbers were exactly the same though). I pushed a new trace using the g_mass_storage driver this time. http://git.xenomai.org/xenomai-jro.git/commit/?h=logs LUP/LDN sequences seem to occur at a higher frequency than before (every 16 transfers or earlier) the test plan as described in the commit: -- device: modprobe net2280 dd if=/dev/zero of=/tmp/disk bs=256M count=1 modprobe g_mass_storage file=/tmp/disk host: dd if=/dev/sd{x} of=/dev/null the transfer speed is pretty much the same than before (around 100MB/s) [jramirez@XENO ~]$ sudo dd if=/dev/sdb of=/dev/null 524288+0 records in 524288+0 records out 268435456 bytes (268 MB) copied, 2.59402 s, 103 MB/s This is some information from the host side: - Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Device Descriptor: bLength18 bDescriptorType 1 bcdUSB 3.00 bDeviceClass9 Hub bDeviceSubClass 0 Unused bDeviceProtocol 3 bMaxPacketSize0 9 idVendor 0x1d6b Linux Foundation idProduct 0x0003 3.0 root hub bcdDevice3.18 iManufacturer 3 Linux 3.18.0-rc7jro-1-g225426a xhci-hcd iProduct2 xHCI Host Controller iSerial 1 :00:14.0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 31 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower0mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 9 Hub bInterfaceSubClass 0 Unused bInterfaceProtocol 0 Full speed (or root) hub iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes3 Transfer TypeInterrupt Synch Type None Usage Type Data wMaxPacketSize 0x0004 1x 4 bytes bInterval 12 bMaxBurst 0 Hub Descriptor: bLength 12 bDescriptorType 42 nNbrPorts 6 wHubCharacteristic 0x000a No power switching (usb 1.0) Per-port overcurrent protection bPwrOn2PwrGood 10 * 2 milli seconds bHubContrCurrent 0 milli Ampere bHubDecLat 0.0 micro seconds wHubDelay 0 nano seconds DeviceRemovable0x00 Hub Port Status: Port 1: .02a0 5Gbps power Rx.Detect Port 2: .02a0 5Gbps power Rx.Detect Port
Re: [PATCH 2/4] usb: dwc3: gadget: Stop TRB preparation after limit is reached
The only reason why I have not been able to test these fixes on the latest is because the customized webcam gadget is not ported on the latest kernel. There have been a lot of changes in the video framework lately and that is not my area of expertise. So porting the customized webcam gadget to latest kernel and testing these fixes is not feasible for me. right, so while I can see that both patches are very minimal and likely to be correct, I have no way of guaranteeing that. The only thing I can do, is run the tests which I already run (none of which exercise the cases you found though, other I'd have found them already) to make sure your patches don't break what's already working. Okay Having said all this, the fact remains that these are bugs in the dwc3 driver from kernel v3.9 onwards. The log messages clearly depict this. no, it doesn't :-) your log snippet is so small that I cannot see how the driver got to that point :-) The only thing I can see is that you started two requests, one for 96 bytes and another one for 2 bytes, but I don't know how many TRBs we had available, nor do I see a Start Transfer command, so I can't validate Start Transfer command parameters were correct or not. These bugs are obviously present till date. Right, the code is the same :-) I ask you to give a more deeper thought on the whole situation and not undermine the importance of code review. heh - [Patch 2/4] fixes a bug that could have been found in the code review. - [Patch 1/4] fixes a bug which was very very subtle but a deeper code review can certainly boost the confidence about the change made. list_is_last won't work when SG is used because, for the last request in the request_list, the TRB for the first sg entry modifies the list's next and prev pointers while moving the URB to req_queued. I can certainly provide the dwc3 specific kernel bootup logs, full regdump and any loglevel you want me to, if that helps Yeah, if you can provide those, then that'll help me verifying. Full logs from boot to failure point with VERBOSE_DEBUG enabled (considering you're not running on anything recent). Okay. I'll provide full verbose logs, along with the register dump, when I'm back to the office next week, for the working and non-working case, but how - as attachment or as inline? -- 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 1/1] usb: chipidea: host: add .bus_suspend quirk
On Tue, 30 Dec 2014, Peter Chen wrote: On Mon, Dec 29, 2014 at 10:44:28AM -0500, Alan Stern wrote: On Mon, 29 Dec 2014, Peter Chen wrote: For chipidea, its resume sequence is not-EHCI compatible, see below description for FPR at portsc. So in order to send SoF in time for remote wakeup sequence(within 3ms), the RUN/STOP bit must be set before the resume signal is ended. Force Port Resume - RW. Default = 0b. 1= Resume detected/driven on port. 0=No resume (K-state) detected/driven on port. Host mode: Software sets this bit to one to drive resume signaling. The Controller sets this bit to '1' if a J-to-K transition is detected while the port is in the Suspend state. When this bit transitions to a '1' because a J-to-K transition is detected, the Port Change Detect bit in the USBSTS register is also set to '1'. This bit will automatically change to '0' after the resume sequence is complete. This behavior is different from EHCI where the controller driver is required to set this bit to a '0' after the resume duration is timed in the driver. Note that when the controller owns the port, the resume sequence follows the defined sequence documented in the USB Specification Revision 2.0. The resume signaling (Full-speed 'K') is driven on the port as long as this bit remains a '1'. This bit will remain a '1' until the port has switched to idle. Writing a '0' has no affect because the port controller will time the resume operation, clear the bit and the port control state switches to HS or FS idle. This field is '0' if Port Power(PP) is '0' in host mode. This bit is not-EHCI compatible. If you really want to do this, go ahead. But see below. Any other solutions for this (Let the SoF send in time within 3ms after resume signal has ended)? No, I don't have any good solutions. What this patch does isn't suitable for EHCI controllers in general, because it disobeys section 4.3 of the EHCI spec: When system software intends to suspend the entire bus, it should selectively suspend all enabled ports, then shut off the host controller by setting the Run/Stop bit in the USBCMD register to a zero. The EHCI module can then be placed into a lower device state via the PCI power management interface (See Appendix A). With this patch, the Run/Stop bit gets set back to 1. When a wake event occurs the system will resume operation and system software will eventually set the Run/Stop bit to a one and resume the suspended ports. Software must not set the Run/Stop bit to a one until it is confirmed that the clock to the host controller is stable. With this patch, the Run/Stop bit remains equal to 1 even while the clock to the host controller is turned off. The only solution I can think of is not very satisfactory. Suppose the controller doesn't send any SoF packets within 3 ms of getting a wakeup signal. Then the device will go back into suspend. Later on, when the controller starts running, the hub driver will see that the device requested a wakeup and will resume the device. + tmp = ehci_readl(ehci, ehci-regs-command); + tmp |= CMD_RUN; + ehci_writel(ehci, tmp, ehci-regs-command); At this point, the bus isn't suspended any more. It is running. The bus state is 'J' since the portsc.suspendM = 1, so the bus is suspended, correct? True, no packets are being sent out to the bus. But the circuitry in the EHCI controller is running, generating SoF packets every 125 us (even though they don't get sent anywhere). Alan Stern -- 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: Issues with commit 34b48db6 (block: remove artifical max_hw_sectors cap)
On Tue, 30 Dec 2014, Christoph Hellwig wrote: The only limits usb-storage imposes on max_sectors are those needed to work around bugs in the devices' USB bridges. (Okay, there's also something for tape drive devices, but it probably doesn't belong in usb-storage -- it should be handled by the SCSI tape driver.) If the ATA layer needs to set a limit on max_sectors, why doesn't it simply go ahead and do so? Because the ATA layer doesn't control the device, the bridge does. And it seems like it doesn't communicate the maximum transfer size properly. _Is_ there any way to communicate the maximum transfer size? I'm not aware of any SCSI command for it. It isn't part of the USB mass-storage spec. usb-storage has no clear idea what sort of device lies on the other side of the USB bridge. It might be an ATA drive, it might be a flash drive, it might not be a disk at all -- usb-storage does its best not to know or care. If you think that usb-storage needs to set a maximum transfer size for disk drives, it won't be hard to write a patch. But what about all the other possible transports? Will they each have to implement the same transfer limit? If so, shouldn't the limit be set up from a more central location, such as the sd driver? Why not have sd always set max_sectors_kb to 32767 if it isn't already smaller? Would that cause any problems? Alan Stern -- 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: net2280: tracing
Hi, On Tue, Dec 30, 2014 at 09:40:45AM -0500, Jorge Ramirez-Ortiz wrote: On 12/29/2014 02:58 PM, Felipe Balbi wrote: Hi, On Mon, Dec 29, 2014 at 02:56:25PM -0500, Jorge Ramirez-Ortiz wrote: On 12/29/2014 11:37 AM, Felipe Balbi wrote: Hi, On Sun, Dec 28, 2014 at 07:28:33PM -0500, Jorge Ramirez-Ortiz wrote: On 12/28/2014 11:39 AM, Felipe Balbi wrote: On Sat, Dec 27, 2014 at 05:33:36PM -0500, Jorge Ramirez-Ortiz wrote: Hi Ricardo/all I finally got around to capture a trace of a SS bulk transfer using the net2280. The trace is available to anyone interested (70 MB file for the Beaglebone 5000). can you publish the trace somewhere we can download ? I use Beagle5000 myself and could help revieweing the traces. Thanks Felipe. I dont have any public ftp server at hand so I just pushed the log to my Xenomai git tree. please grab it from here (no need to clone the tree, just press the download link) http://git.xenomai.org/xenomai-jro.git/commit/?h=logs One of the reasons could be because you're using the printer gadget :-) Have you tried any of the other gadgets ? In any case, try this little hack: diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 9054598..8a09661 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -129,7 +129,7 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR); /* holds our biggest descriptor */ #define USB_DESC_BUFSIZE 256 -#define USB_BUFSIZE 8192 +#define USB_BUFSIZE 65536 static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, yes I thought about that as well: in fact the trace I made available already had that modification in place. (it also has the queue length increased to 20 - no more changes after those two) oh, ok. That would mean the IP can't pump more data :-s for simplicity -and to have a common test vehicle- I'll capture a trace using the g_mass_storage (last time I run that check the performance numbers were exactly the same though). I pushed a new trace using the g_mass_storage driver this time. http://git.xenomai.org/xenomai-jro.git/commit/?h=logs LUP/LDN sequences seem to occur at a higher frequency than before (every 16 transfers or earlier) the test plan as described in the commit: -- device: modprobe net2280 dd if=/dev/zero of=/tmp/disk bs=256M count=1 modprobe g_mass_storage file=/tmp/disk host: dd if=/dev/sd{x} of=/dev/null the transfer speed is pretty much the same than before (around 100MB/s) I was going around the previous trace again and the duration of most of the 1024 bytes transfers is rather high (over 7us). I found a few which are ridiculously high (102.032us on index 3973 or somewhere around that). I wonder what is causing these extra slow packet. Is it SW or HW ? ps: the average through calculated by the sniffer with the previous trace is 112.71 MB/sec. The average packet duration with that is 9.085 us. Considering most are above 7 us and some are ridiculously slow, I guess things really do add up. Can you try to use the kernel function profiler to see if there's anything that takes a lot more time than the others ? cheers -- balbi signature.asc Description: Digital signature
Re: Issues with commit 34b48db6 (block: remove artifical max_hw_sectors cap)
On Tue, 2014-12-30 at 10:34 -0500, Alan Stern wrote: On Tue, 30 Dec 2014, Christoph Hellwig wrote: The only limits usb-storage imposes on max_sectors are those needed to work around bugs in the devices' USB bridges. (Okay, there's also something for tape drive devices, but it probably doesn't belong in usb-storage -- it should be handled by the SCSI tape driver.) If the ATA layer needs to set a limit on max_sectors, why doesn't it simply go ahead and do so? Because the ATA layer doesn't control the device, the bridge does. And it seems like it doesn't communicate the maximum transfer size properly. _Is_ there any way to communicate the maximum transfer size? I'm not aware of any SCSI command for it. It isn't part of the USB mass-storage spec. For the device, it's in the Block limits VPD page. However, what the device supports isn't necessarily what the bridge or host bus adapter will support. We need to set the limit to the lowest of what the device, the bridge and the HBA support. We know the device (provided the bridge allows VPD inquiries ... not all do) and host, so we really need to know what the bridge will support. From the error it does look like we're running into a bridge limit. usb-storage has no clear idea what sort of device lies on the other side of the USB bridge. It might be an ATA drive, it might be a flash drive, it might not be a disk at all -- usb-storage does its best not to know or care. That's fine, but is there any way in USB to query the bridge to get it's transfer characteristics? If you think that usb-storage needs to set a maximum transfer size for disk drives, it won't be hard to write a patch. But what about all the other possible transports? Will they each have to implement the same transfer limit? If so, shouldn't the limit be set up from a more central location, such as the sd driver? This isn't a transport problem, this is a bridge problem. T10 has always recognised there might be a bridge issue linking two transports, so it did initially come up with a bridge spec (BCC) but it was abandoned a decade ago in favour of transparent bridges (every switch in a FC topology is effectively a transparent bridge) or making them explicit in the standards, like SAS expanders. Why not have sd always set max_sectors_kb to 32767 if it isn't already smaller? Would that cause any problems? This wouldn't be sd ... we have lots of requirements for large transfer sizes for efficiency. It has to be the layer that knows there's a bridge, so that would make it usb. James -- 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 2/4] usb: dwc3: gadget: Stop TRB preparation after limit is reached
On Tue, Dec 30, 2014 at 08:11:13PM +0530, Amit Virdi wrote: The only reason why I have not been able to test these fixes on the latest is because the customized webcam gadget is not ported on the latest kernel. There have been a lot of changes in the video framework lately and that is not my area of expertise. So porting the customized webcam gadget to latest kernel and testing these fixes is not feasible for me. right, so while I can see that both patches are very minimal and likely to be correct, I have no way of guaranteeing that. The only thing I can do, is run the tests which I already run (none of which exercise the cases you found though, other I'd have found them already) to make sure your patches don't break what's already working. Okay Having said all this, the fact remains that these are bugs in the dwc3 driver from kernel v3.9 onwards. The log messages clearly depict this. no, it doesn't :-) your log snippet is so small that I cannot see how the driver got to that point :-) The only thing I can see is that you started two requests, one for 96 bytes and another one for 2 bytes, but I don't know how many TRBs we had available, nor do I see a Start Transfer command, so I can't validate Start Transfer command parameters were correct or not. These bugs are obviously present till date. Right, the code is the same :-) I ask you to give a more deeper thought on the whole situation and not undermine the importance of code review. heh - [Patch 2/4] fixes a bug that could have been found in the code review. - [Patch 1/4] fixes a bug which was very very subtle but a deeper code review can certainly boost the confidence about the change made. list_is_last won't work when SG is used because, for the last request in the request_list, the TRB for the first sg entry modifies the list's next and prev pointers while moving the URB to req_queued. I can certainly provide the dwc3 specific kernel bootup logs, full regdump and any loglevel you want me to, if that helps Yeah, if you can provide those, then that'll help me verifying. Full logs from boot to failure point with VERBOSE_DEBUG enabled (considering you're not running on anything recent). Okay. I'll provide full verbose logs, along with the register dump, when I'm back to the office next week, for the working and non-working case, but how - as attachment or as inline? Either way will do but I have a feeling mailing list attachment size will bite you, so maybe it's best to make a tarball of both logs and send that as attachment. Compressed text will be very small. -- balbi signature.asc Description: Digital signature
Re: Issues with commit 34b48db6 (block: remove artifical max_hw_sectors cap)
On Tue, 30 Dec 2014, James Bottomley wrote: _Is_ there any way to communicate the maximum transfer size? I'm not aware of any SCSI command for it. It isn't part of the USB mass-storage spec. For the device, it's in the Block limits VPD page. However, what the device supports isn't necessarily what the bridge or host bus adapter will support. We need to set the limit to the lowest of what the device, the bridge and the HBA support. We know the device (provided the bridge allows VPD inquiries ... not all do) and host, so we really need to know what the bridge will support. From the error it does look like we're running into a bridge limit. I see. usb-storage has no clear idea what sort of device lies on the other side of the USB bridge. It might be an ATA drive, it might be a flash drive, it might not be a disk at all -- usb-storage does its best not to know or care. That's fine, but is there any way in USB to query the bridge to get it's transfer characteristics? No, there isn't. The only query that a USB mass-storage bridge accepts is for the maximum LUN value. If you think that usb-storage needs to set a maximum transfer size for disk drives, it won't be hard to write a patch. But what about all the other possible transports? Will they each have to implement the same transfer limit? If so, shouldn't the limit be set up from a more central location, such as the sd driver? This isn't a transport problem, this is a bridge problem. T10 has always recognised there might be a bridge issue linking two transports, so it did initially come up with a bridge spec (BCC) but it was abandoned a decade ago in favour of transparent bridges (every switch in a FC topology is effectively a transparent bridge) or making them explicit in the standards, like SAS expanders. Why not have sd always set max_sectors_kb to 32767 if it isn't already smaller? Would that cause any problems? This wouldn't be sd ... we have lots of requirements for large transfer sizes for efficiency. It has to be the layer that knows there's a bridge, so that would make it usb. All right. How does this patch look? Alan Stern Index: usb-3.18/drivers/usb/storage/scsiglue.c === --- usb-3.18.orig/drivers/usb/storage/scsiglue.c +++ usb-3.18/drivers/usb/storage/scsiglue.c @@ -114,26 +114,30 @@ static int slave_alloc (struct scsi_devi static int slave_configure(struct scsi_device *sdev) { struct us_data *us = host_to_us(sdev-host); + unsigned int max_sectors; - /* Many devices have trouble transferring more than 32KB at a time, -* while others have trouble with more than 64K. At this time we -* are limiting both to 32K (64 sectores). + /* +* Many devices have trouble transferring more than 32 KB at a time, +* while others have trouble with more than 64 KB. At this time we +* are limiting both to 32 KB (64 sectores). +* Still other devices have trouble unless the transfer size is as +* small as possible (one memory page). +* +* Tape drives need much higher max_sector limits, so just +* raise it to the maximum possible (4 GB / 512) and let the +* queue segment size sort out the real limit. +* For safety, limit all other devices to 32 MB transfer size. */ - if (us-fflags (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN)) { - unsigned int max_sectors = 64; - - if (us-fflags US_FL_MAX_SECTORS_MIN) - max_sectors = PAGE_CACHE_SIZE 9; - if (queue_max_hw_sectors(sdev-request_queue) max_sectors) - blk_queue_max_hw_sectors(sdev-request_queue, - max_sectors); - } else if (sdev-type == TYPE_TAPE) { - /* Tapes need much higher max_sector limits, so just -* raise it to the maximum possible (4 GB / 512) and -* let the queue segment size sort out the real limit. -*/ - blk_queue_max_hw_sectors(sdev-request_queue, 0x7F); - } + if (us-fflags US_FL_MAX_SECTORS_MIN) + max_sectors = PAGE_CACHE_SIZE 9; + else if (us-fflags US_FL_MAX_SECTORS_64) + max_sectors = 64; + else if (sdev-type == TYPE_TAPE) + max_sectors = 0x7F; + else + max_sectors = 65535; + if (queue_max_hw_sectors(sdev-request_queue) max_sectors) + blk_queue_max_hw_sectors(sdev-request_queue, max_sectors); /* Some USB host controllers can't do DMA; they have to use PIO. * They indicate this by setting their dma_mask to NULL. For -- 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
Re: Issues with commit 34b48db6 (block: remove artifical max_hw_sectors cap)
On 14-12-30 10:34 AM, Alan Stern wrote: On Tue, 30 Dec 2014, Christoph Hellwig wrote: The only limits usb-storage imposes on max_sectors are those needed to work around bugs in the devices' USB bridges. (Okay, there's also something for tape drive devices, but it probably doesn't belong in usb-storage -- it should be handled by the SCSI tape driver.) If the ATA layer needs to set a limit on max_sectors, why doesn't it simply go ahead and do so? Because the ATA layer doesn't control the device, the bridge does. And it seems like it doesn't communicate the maximum transfer size properly. _Is_ there any way to communicate the maximum transfer size? I'm not aware of any SCSI command for it. It isn't part of the USB mass-storage spec. In SCSI, the VPD page 0xb0 (Block limits) has a Maximum transfer length field (32 bits long). Its units are logical blocks. Useful if 0 as 0 means unreported. USB to SATA bridges should comply with SAT. However SAT and SAT-2 don't even mention that VPD page. SAT-3 and SAT-4 mention that page but have unspecified next to that field. Basically useless. IMO about the best SATL is in the MPT SAS-2 and SAS-3 HBAs and here is that page for a SAS expander attached SATA disk: # sg_vpd -p bl /dev/sg3 Block limits VPD page (SBC): Write same non-zero (WSNZ): 0 Maximum compare and write length: 0 blocks Optimal transfer length granularity: 0 blocks Maximum transfer length: 0 blocks Optimal transfer length: 0 blocks Maximum prefetch length: 0 blocks Maximum unmap LBA count: 0 Maximum unmap block descriptor count: 0 Optimal unmap granularity: 0 Unmap granularity alignment valid: 0 Unmap granularity alignment: 0 Maximum write same length: 0x0 blocks Maximum atomic transfer length: 0 Atomic alignment: 0 Atomic transfer length granularity: 0 Maximum atomic transfer length with atomic boundary: 0 Maximum atomic boundary size: 0 Not sure why LSI/Avago even bothered even implementing that page ... Doug Gilbert BTW here is the output of that page from a SAS SSD: # sg_vpd -p bl /dev/sg5 Block limits VPD page (SBC): Write same non-zero (WSNZ): 0 Maximum compare and write length: 0 blocks Optimal transfer length granularity: 8 blocks Maximum transfer length: 65535 blocks Optimal transfer length: 0 blocks Maximum prefetch length: 0 blocks Maximum unmap LBA count: 393216 Maximum unmap block descriptor count: 512 Optimal unmap granularity: 8 Unmap granularity alignment valid: 0 Unmap granularity alignment: 0 Maximum write same length: 0x0 blocks Maximum atomic transfer length: 0 Atomic alignment: 0 Atomic transfer length granularity: 0 Maximum atomic transfer length with atomic boundary: 0 Maximum atomic boundary size: 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
Re: Issues with commit 34b48db6 (block: remove artifical max_hw_sectors cap)
On Tue, 2014-12-30 at 11:12 -0500, Alan Stern wrote: On Tue, 30 Dec 2014, James Bottomley wrote: _Is_ there any way to communicate the maximum transfer size? I'm not aware of any SCSI command for it. It isn't part of the USB mass-storage spec. For the device, it's in the Block limits VPD page. However, what the device supports isn't necessarily what the bridge or host bus adapter will support. We need to set the limit to the lowest of what the device, the bridge and the HBA support. We know the device (provided the bridge allows VPD inquiries ... not all do) and host, so we really need to know what the bridge will support. From the error it does look like we're running into a bridge limit. I see. usb-storage has no clear idea what sort of device lies on the other side of the USB bridge. It might be an ATA drive, it might be a flash drive, it might not be a disk at all -- usb-storage does its best not to know or care. That's fine, but is there any way in USB to query the bridge to get it's transfer characteristics? No, there isn't. The only query that a USB mass-storage bridge accepts is for the maximum LUN value. If you think that usb-storage needs to set a maximum transfer size for disk drives, it won't be hard to write a patch. But what about all the other possible transports? Will they each have to implement the same transfer limit? If so, shouldn't the limit be set up from a more central location, such as the sd driver? This isn't a transport problem, this is a bridge problem. T10 has always recognised there might be a bridge issue linking two transports, so it did initially come up with a bridge spec (BCC) but it was abandoned a decade ago in favour of transparent bridges (every switch in a FC topology is effectively a transparent bridge) or making them explicit in the standards, like SAS expanders. Why not have sd always set max_sectors_kb to 32767 if it isn't already smaller? Would that cause any problems? This wouldn't be sd ... we have lots of requirements for large transfer sizes for efficiency. It has to be the layer that knows there's a bridge, so that would make it usb. All right. How does this patch look? OK, I suppose. The transfer limits are a little on the low side, but for usb-storage (i.e. non-UAS) performance devices, they should be OK. For TYPE_TAPE, you still have no guarantee that the bridge won't screw up ... and if the argument is that tapes are always connected to sensible bridges, why aren't SATA devices? There's also a spelling mistake below. Alan Stern Index: usb-3.18/drivers/usb/storage/scsiglue.c === --- usb-3.18.orig/drivers/usb/storage/scsiglue.c +++ usb-3.18/drivers/usb/storage/scsiglue.c @@ -114,26 +114,30 @@ static int slave_alloc (struct scsi_devi static int slave_configure(struct scsi_device *sdev) { struct us_data *us = host_to_us(sdev-host); + unsigned int max_sectors; - /* Many devices have trouble transferring more than 32KB at a time, - * while others have trouble with more than 64K. At this time we - * are limiting both to 32K (64 sectores). + /* + * Many devices have trouble transferring more than 32 KB at a time, + * while others have trouble with more than 64 KB. At this time we + * are limiting both to 32 KB (64 sectores). sectors James -- 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: Issues with commit 34b48db6 (block: remove artifical max_hw_sectors cap)
On Tue, 30 Dec 2014, James Bottomley wrote: All right. How does this patch look? OK, I suppose. The transfer limits are a little on the low side, but for usb-storage (i.e. non-UAS) performance devices, they should be OK. If you're referring to the 32-KB and 64-KB limits, we know from experience that some devices really do need them. If you're referring to the 32-MB limit... Well, that's what this whole thread is about, right? That limit could be restricted to apply only when a device is not connected over a SuperSpeed USB-3 link. But knowing the low quality of commodity USB hardware, I suspect it wouldn't work well. For TYPE_TAPE, you still have no guarantee that the bridge won't screw up ... and if the argument is that tapes are always connected to sensible bridges, why aren't SATA devices? True, we have no guarantee. But tape drives do have special requirements because of the way they write blocks and gaps; this code was added by someone with a tape drive who did need the large limit. I guess there are a lot more bridges in the low-budget consumer world targeted to disk drives than to tape drives. That could explain a lot. There's also a spelling mistake below. I'll fix it in the final patch submission. Thanks. Alan Stern PS: What's the current situation of my SCSI: fix regression in scsi_send_eh_cmnd() patch: http://marc.info/?l=linux-scsim=141658469207765w=2 submitted on November 21? Since it was a bug-fix, I rather expected it to get merged before 3.18 was released. Since it didn't, I certainly hope it will get in before 3.19. -- 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: Issues with commit 34b48db6 (block: remove artifical max_hw_sectors cap)
On Tue, 2014-12-30 at 11:45 -0500, Alan Stern wrote: PS: What's the current situation of my SCSI: fix regression in scsi_send_eh_cmnd() patch: http://marc.info/?l=linux-scsim=141658469207765w=2 submitted on November 21? Since it was a bug-fix, I rather expected it to get merged before 3.18 was released. Since it didn't, I certainly hope it will get in before 3.19. Looks like it just got overlooked. Since Hannes has reviewed it, I'll add it to the fixes branch. James -- 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: Issues with commit 34b48db6 (block: remove artifical max_hw_sectors cap)
On Tue, 30 Dec 2014, Douglas Gilbert wrote: IMO about the best SATL is in the MPT SAS-2 and SAS-3 HBAs and here is that page for a SAS expander attached SATA disk: # sg_vpd -p bl /dev/sg3 OP here. FWIW, this is what I get when running that command on the SCSI generic device that corresponds to the USB-3 (non-UAS) disk[1] that had the issue: $ sudo sg_vpd -p bl /dev/sg4 Block limits VPD page (SBC): Write same no zero (WSNZ): 0 Maximum compare and write length: 0 blocks Optimal transfer length granularity: 1 blocks Maximum transfer length: 8191 blocks Optimal transfer length: 8191 blocks Maximum prefetch length: 8191 blocks Maximum unmap LBA count: 0 Maximum unmap block descriptor count: 0 Optimal unmap granularity: 0 Unmap granularity alignment valid: 0 Unmap granularity alignment: 0 Maximum write same length: 0x0 blocks $ If more info is needed, just let me know. -Kenny [1] - SCSI generic devices follow /proc/scsi/scsi order, right? -- Kenneth R. Crudup Sr. SW Engineer, Scott County Consulting, Silicon Valley -- 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
Cash Donation For You
Hello friend! my name is Neil Trotter, I'm from South London UK. In the month of March 2014 I won £108m in the Euro Million Lottery after which i had to set up a charity project in other to spread this great fortune. Willingly am donating £1m each to five unknown individuals in my ongoing charity scheme. If you have received this mail then your are one of my lucky winners. Get back to me with your name,address and phone number for more details on how you can receive your donation. See article of my winning below: http://www.bbc.com/news/uk-england-london-26627075 Sincerely, Neil Trotter Donation Scheme. -- 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