[PATCH V4 0/6] USB: OHCI: more bus glues as separate modules
These patches are for separating the SOC On-Chip ohci host controller from ohci-hcd host code into its own driver module. This work is part of enabling multi-platform kernels on ARM; it would be nice to have in 3.12. V2: In patch 5/6 and 6/6: -Set non-standard fields in hc_driver manually, rather than relying on an expanded struct ohci_driver_overrides. -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than relying on ohci_hub_control and hub_status_data being exported. In patch 1/6 to 4/6 -ohci_setup() has been removed because it is called in .reset member of the ohci_hc_driver structure. V3: In patch 5/6 and 6/6: -ohci_setup() has been removed because it is called in .reset member of the ohci_hc_driver structure. In patch 5/6: -The ohci_restart() function is not required in current scenario, only discarding connection state of integrated transceivers is sufficient, for this directly handling ohci-hc_control. In patch 2/6 : -rewritten if (config-otg || config-rwc) block statements into two separate 'if blocks' to handle below scenarios 1. config-otg set scenario. 2. if any of these (config-otg, config-rwc) are set, this scenario should be handled only after ohci_setup() In patch 1/6 and 4/6: No change. V4: In patch 1/6 and 4/6: No change. In patch 2/6 : -usb_remove_hcd() function is required a valid clock that is what omap_ohci_clock_power(0) is called after hcd shutdown. In patch 3/6 : -V3 modification revert back, only ohci-regs setting write() function has been removed because ohci-regs doesn't get set until usb_add_hcd. In patch 5/6 : - Removed extra space after tristate. - Removed extra space between function name and '(' characters. - MODULE_ALIAS line moved to last statement of ohci-at91 file. In patch 6/6 : - Removed extra space before the '='. - Moved /* forward definitions */ line before the declarations of functions. Manjunath Goudar (6): USB: OHCI: make ohci-exynos a separate driver USB: OHCI: make ohci-omap a separate driver USB: OHCI: make ohci-omap3 a separate driver USB: OHCI: make ohci-spear a separate driver USB: OHCI: make ohci-at91 a separate driver USB: OHCI: make ohci-s3c2410 a separate driver drivers/usb/host/Kconfig| 30 ++- drivers/usb/host/Makefile |6 ++ drivers/usb/host/ohci-at91.c| 153 --- drivers/usb/host/ohci-exynos.c | 167 --- drivers/usb/host/ohci-hcd.c | 108 - drivers/usb/host/ohci-omap.c| 156 +--- drivers/usb/host/ohci-omap3.c | 118 +-- drivers/usb/host/ohci-s3c2410.c | 128 +- drivers/usb/host/ohci-spear.c | 140 +--- 9 files changed, 374 insertions(+), 632 deletions(-) -- 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
[PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver
Separate the Samsung OHCI EXYNOS host controller driver from ohci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; it would be nice to have in 3.11. Signed-off-by: Manjunath Goudar manjunath.gou...@linaro.org Acked-by: Alan Stern st...@rowland.harvard.edu Acked-by: Jingoo Han jg1@samsung.com Cc: Vivek Gautam gautam.vi...@samsung.com Cc: Arnd Bergmann a...@arndb.de Cc: Kukjin Kim kgene@samsung.com Cc: Greg KH g...@kroah.com Cc: linux-usb@vger.kernel.org V2: -exynos_ohci_hcd structure assignment error fixed. -Removed multiple usb_create_hcd() from prob funtion. -platform_set_drvdata() called before exynos_ohci_phy_enable(). -ohci_setup() removed because it is called in .reset member of the ohci_hc_driver structure V3: -No major changes only exynos written in capital letters in OHCI exynos driver. --- drivers/usb/host/Kconfig |2 +- drivers/usb/host/Makefile |1 + drivers/usb/host/ohci-exynos.c | 167 +--- drivers/usb/host/ohci-hcd.c| 18 - 4 files changed, 71 insertions(+), 117 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 7bc598b..7b8f6bd 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -463,7 +463,7 @@ config USB_OHCI_SH If you use the PCI OHCI controller, this option is not necessary. config USB_OHCI_EXYNOS - boolean OHCI support for Samsung EXYNOS SoC Series + tristate OHCI support for Samsung EXYNOS SoC Series depends on ARCH_EXYNOS help Enable support for the Samsung Exynos SOC's on-chip OHCI controller. diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 480e203..26cf69a 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o obj-$(CONFIG_USB_OHCI_HCD_PCI) += ohci-pci.o obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)+= ohci-platform.o +obj-$(CONFIG_USB_OHCI_EXYNOS) += ohci-exynos.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index b0b542c..ae6068d 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -12,24 +12,39 @@ */ #include linux/clk.h +#include linux/dma-mapping.h +#include linux/io.h +#include linux/kernel.h +#include linux/module.h #include linux/of.h #include linux/platform_device.h #include linux/platform_data/usb-ohci-exynos.h #include linux/usb/phy.h #include linux/usb/samsung_usb_phy.h +#include linux/usb.h +#include linux/usb/hcd.h +#include linux/usb/otg.h + +#include ohci.h + +#define DRIVER_DESC OHCI EXYNOS driver + +static const char hcd_name[] = ohci-exynos; +static struct hc_driver __read_mostly exynos_ohci_hc_driver; + +#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)-priv) struct exynos_ohci_hcd { - struct device *dev; - struct usb_hcd *hcd; struct clk *clk; struct usb_phy *phy; struct usb_otg *otg; struct exynos4_ohci_platdata *pdata; }; -static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci) +static void exynos_ohci_phy_enable(struct platform_device *pdev) { - struct platform_device *pdev = to_platform_device(exynos_ohci-dev); + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd); if (exynos_ohci-phy) usb_phy_init(exynos_ohci-phy); @@ -37,9 +52,10 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci) exynos_ohci-pdata-phy_init(pdev, USB_PHY_TYPE_HOST); } -static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci) +static void exynos_ohci_phy_disable(struct platform_device *pdev) { - struct platform_device *pdev = to_platform_device(exynos_ohci-dev); + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd); if (exynos_ohci-phy) usb_phy_shutdown(exynos_ohci-phy); @@ -47,63 +63,11 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci) exynos_ohci-pdata-phy_exit(pdev, USB_PHY_TYPE_HOST); } -static int ohci_exynos_reset(struct usb_hcd *hcd) -{ - return ohci_init(hcd_to_ohci(hcd)); -} - -static int ohci_exynos_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - ohci_dbg(ohci, ohci_exynos_start, ohci:%p, ohci); - - ret = ohci_run(ohci); - if (ret 0) { - dev_err(hcd-self.controller, can't start %s\n, - hcd-self.bus_name); - ohci_stop(hcd); - return ret; - } - - return 0; -} - -static
[PATCH V4 5/6] USB: OHCI: make ohci-at91 a separate driver
Separate the TI OHCI Atmel host controller driver from ohci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; it would be nice to have in 3.12. Signed-off-by: Manjunath Goudar manjunath.gou...@linaro.org Acked-by: Alan Stern st...@rowland.harvard.edu Cc: Arnd Bergmann a...@arndb.de Cc: Greg KH g...@kroah.com Cc: linux-usb@vger.kernel.org V2: -Set non-standard fields in ohci_at91_hc_driver manually, rather than relying on an expanded struct ohci_driver_overrides. -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than relying on ohci_hub_control and hub_status_data being exported. -ohci_setup() has been removed because it is called in .reset member of the ohci_hc_driver structure. V3: -The ohci_restart() function is not required in current scenario, only discarding connection state of integrated transceivers is sufficient, for this directly handling ohci-hc_control. V4: - Removed extra space after tristate. - Removed extra space between function name and '(' characters. - MODULE_ALIAS line moved to last statement of ohci-at91 file. --- drivers/usb/host/Kconfig |8 +++ drivers/usb/host/Makefile|1 + drivers/usb/host/ohci-at91.c | 153 +++--- drivers/usb/host/ohci-hcd.c | 18 - 4 files changed, 77 insertions(+), 103 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index a5a34a3..693560a 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR Enables support for the on-chip OHCI controller on ST SPEAr chips. +config USB_OHCI_HCD_AT91 +tristate Support for Atmel on-chip OHCI USB controller +depends on USB_OHCI_HCD ARCH_AT91 +default y +---help--- + Enables support for the on-chip OHCI controller on + Atmel chips. + config USB_OHCI_HCD_OMAP3 tristate OHCI support for OMAP3 and later chips depends on (ARCH_OMAP3 || ARCH_OMAP4) diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index b8ea17c..a70b044 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS) += ohci-exynos.o obj-$(CONFIG_USB_OHCI_HCD_OMAP1) += ohci-omap.o obj-$(CONFIG_USB_OHCI_HCD_OMAP3) += ohci-omap3.o obj-$(CONFIG_USB_OHCI_HCD_SPEAR) += ohci-spear.o +obj-$(CONFIG_USB_OHCI_HCD_AT91)+= ohci-at91.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 9677f68..08e28eb 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -13,27 +13,41 @@ */ #include linux/clk.h -#include linux/platform_device.h +#include linux/dma-mapping.h #include linux/of_platform.h #include linux/of_gpio.h +#include linux/platform_device.h #include linux/platform_data/atmel.h +#include linux/io.h +#include linux/kernel.h +#include linux/module.h +#include linux/usb.h +#include linux/usb/hcd.h #include mach/hardware.h #include asm/gpio.h #include mach/cpu.h -#ifndef CONFIG_ARCH_AT91 -#error CONFIG_ARCH_AT91 must be defined. -#endif + +#include ohci.h #define valid_port(index) ((index) = 0 (index) AT91_MAX_USBH_PORTS) #define at91_for_each_port(index) \ for ((index) = 0; (index) AT91_MAX_USBH_PORTS; (index)++) /* interface and function clocks; sometimes also an AHB clock */ + +#define DRIVER_DESC OHCI Atmel driver + +static const char hcd_name[] = ohci-atmel; + +static struct hc_driver __read_mostly ohci_at91_hc_driver; static struct clk *iclk, *fclk, *hclk; static int clocked; +static int (*orig_ohci_hub_control)(struct usb_hcd *hcd, u16 typeReq, + u16 wValue, u16 wIndex, char *buf, u16 wLength); +static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf); extern int usb_disabled(void); @@ -111,6 +125,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); static int usb_hcd_at91_probe(const struct hc_driver *driver, struct platform_device *pdev) { + struct at91_usbh_data *board; + struct ohci_hcd *ohci; int retval; struct usb_hcd *hcd = NULL; @@ -163,8 +179,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, goto err5; } + board = hcd-self.controller-platform_data; + ohci = hcd_to_ohci(hcd); + ohci-num_ports = board-ports; at91_start_hc(pdev); - ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, pdev-resource[1].start, IRQF_SHARED); if (retval == 0) @@ -221,36 +239,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd, } /*-*/ -
[PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
Separate the Samsung OHCI S3C host controller driver from ohci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; it would be nice to have in 3.12. Signed-off-by: Manjunath Goudar manjunath.gou...@linaro.org Acked-by: Alan Stern st...@rowland.harvard.edu Cc: Arnd Bergmann a...@arndb.de Cc: Greg KH g...@kroah.com Cc: linux-usb@vger.kernel.org V2: -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather than relying on an expanded struct ohci_driver_overrides. -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than relying on ohci_hub_control and hub_status_data being exported. V3: -Kconfig wrong parentheses discription fixed. -ohci_setup() has been removed because it is called in .reset member of the ohci_hc_driver structure. V4: - Removed extra space before the '='. - Moved /* forward definitions */ line before the declarations of functions. --- drivers/usb/host/Kconfig|8 +++ drivers/usb/host/Makefile |1 + drivers/usb/host/ohci-hcd.c | 18 -- drivers/usb/host/ohci-s3c2410.c | 128 +-- 4 files changed, 66 insertions(+), 89 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 693560a..795d14d 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR Enables support for the on-chip OHCI controller on ST SPEAr chips. +config USB_OHCI_HCD_S3C +tristate Support for S3C on-chip OHCI USB controller +depends on USB_OHCI_HCD (ARCH_S3C24XX || ARCH_S3C64XX) +default y +---help--- + Enables support for the on-chip OHCI controller on + S3C chips. + config USB_OHCI_HCD_AT91 tristate Support for Atmel on-chip OHCI USB controller depends on USB_OHCI_HCD ARCH_AT91 diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index a70b044..9dffe81 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1) += ohci-omap.o obj-$(CONFIG_USB_OHCI_HCD_OMAP3) += ohci-omap3.o obj-$(CONFIG_USB_OHCI_HCD_SPEAR) += ohci-spear.o obj-$(CONFIG_USB_OHCI_HCD_AT91)+= ohci-at91.o +obj-$(CONFIG_USB_OHCI_HCD_S3C) += ohci-s3c2410.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index b48c892..b69a49e 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1177,11 +1177,6 @@ MODULE_LICENSE (GPL); #define SA_DRIVER ohci_hcd_sa_driver #endif -#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX) -#include ohci-s3c2410.c -#define S3C2410_PLATFORM_DRIVERohci_hcd_s3c2410_driver -#endif - #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #include ohci-pxa27x.c #define PLATFORM_DRIVERohci_hcd_pxa27x_driver @@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void) goto error_tmio; #endif -#ifdef S3C2410_PLATFORM_DRIVER - retval = platform_driver_register(S3C2410_PLATFORM_DRIVER); - if (retval 0) - goto error_s3c2410; -#endif - #ifdef EP93XX_PLATFORM_DRIVER retval = platform_driver_register(EP93XX_PLATFORM_DRIVER); if (retval 0) @@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void) platform_driver_unregister(EP93XX_PLATFORM_DRIVER); error_ep93xx: #endif -#ifdef S3C2410_PLATFORM_DRIVER - platform_driver_unregister(S3C2410_PLATFORM_DRIVER); - error_s3c2410: -#endif #ifdef TMIO_OHCI_DRIVER platform_driver_unregister(TMIO_OHCI_DRIVER); error_tmio: @@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void) #ifdef EP93XX_PLATFORM_DRIVER platform_driver_unregister(EP93XX_PLATFORM_DRIVER); #endif -#ifdef S3C2410_PLATFORM_DRIVER - platform_driver_unregister(S3C2410_PLATFORM_DRIVER); -#endif #ifdef TMIO_OHCI_DRIVER platform_driver_unregister(TMIO_OHCI_DRIVER); #endif diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index e125770..48b5948 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -19,19 +19,36 @@ * This file is licenced under the GPL. */ -#include linux/platform_device.h #include linux/clk.h +#include linux/io.h +#include linux/kernel.h +#include linux/module.h +#include linux/platform_device.h #include linux/platform_data/usb-ohci-s3c2410.h +#include linux/usb.h +#include linux/usb/hcd.h + +#include ohci.h + #define valid_port(idx) ((idx) == 1 || (idx) == 2) /* clock device associated with the hcd */ + +#define DRIVER_DESC OHCI S3C driver + +static const char hcd_name[] = ohci-s3c; + static struct clk *clk; static struct clk *usb_clk; /*
[PATCH V4 4/6] USB: OHCI: make ohci-spear a separate driver
Separate the ST OHCI SPEAr host controller driver from ohci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; it would be nice to have in 3.11. Signed-off-by: Manjunath Goudar manjunath.gou...@linaro.org Acked-by: Alan Stern st...@rowland.harvard.edu Cc: Viresh Kumar viresh.li...@gmail.com Cc: Arnd Bergmann a...@arndb.de Cc: Greg KH g...@kroah.com Cc: linux-usb@vger.kernel.org V2: -ohci_setup() removed because it is called in .reset member of the ohci_hc_driver structure. -debugging stuff isn't needed any more that's what removed. V3: No change. --- drivers/usb/host/Kconfig |8 +++ drivers/usb/host/Makefile |1 + drivers/usb/host/ohci-hcd.c | 18 -- drivers/usb/host/ohci-spear.c | 140 + 4 files changed, 65 insertions(+), 102 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3eab432..a5a34a3 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -382,6 +382,14 @@ config USB_OHCI_HCD_OMAP1 ---help--- Enables support for the OHCI controller on OMAP1/2 chips. +config USB_OHCI_HCD_SPEAR +tristate Support for ST SPEAr on-chip OHCI USB controller +depends on USB_OHCI_HCD PLAT_SPEAR +default y +---help--- + Enables support for the on-chip OHCI controller on + ST SPEAr chips. + config USB_OHCI_HCD_OMAP3 tristate OHCI support for OMAP3 and later chips depends on (ARCH_OMAP3 || ARCH_OMAP4) diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 954466d..b8ea17c 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM) += ohci-platform.o obj-$(CONFIG_USB_OHCI_EXYNOS) += ohci-exynos.o obj-$(CONFIG_USB_OHCI_HCD_OMAP1) += ohci-omap.o obj-$(CONFIG_USB_OHCI_HCD_OMAP3) += ohci-omap3.o +obj-$(CONFIG_USB_OHCI_HCD_SPEAR) += ohci-spear.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index cad51d2..34ec156 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1212,11 +1212,6 @@ MODULE_LICENSE (GPL); #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver #endif -#ifdef CONFIG_PLAT_SPEAR -#include ohci-spear.c -#define SPEAR_PLATFORM_DRIVER spear_ohci_hcd_driver -#endif - #ifdef CONFIG_PPC_PS3 #include ohci-ps3.c #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver @@ -1333,19 +1328,9 @@ static int __init ohci_hcd_mod_init(void) goto error_davinci; #endif -#ifdef SPEAR_PLATFORM_DRIVER - retval = platform_driver_register(SPEAR_PLATFORM_DRIVER); - if (retval 0) - goto error_spear; -#endif - return retval; /* Error path */ -#ifdef SPEAR_PLATFORM_DRIVER - platform_driver_unregister(SPEAR_PLATFORM_DRIVER); - error_spear: -#endif #ifdef DAVINCI_PLATFORM_DRIVER platform_driver_unregister(DAVINCI_PLATFORM_DRIVER); error_davinci: @@ -1403,9 +1388,6 @@ module_init(ohci_hcd_mod_init); static void __exit ohci_hcd_mod_exit(void) { -#ifdef SPEAR_PLATFORM_DRIVER - platform_driver_unregister(SPEAR_PLATFORM_DRIVER); -#endif #ifdef DAVINCI_PLATFORM_DRIVER platform_driver_unregister(DAVINCI_PLATFORM_DRIVER); #endif diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index cc9dd9e..31ff3fc 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -11,92 +11,37 @@ * warranty of any kind, whether express or implied. */ -#include linux/signal.h -#include linux/platform_device.h #include linux/clk.h +#include linux/dma-mapping.h +#include linux/io.h +#include linux/kernel.h +#include linux/module.h #include linux/of.h +#include linux/platform_device.h +#include linux/signal.h +#include linux/usb.h +#include linux/usb/hcd.h + +#include ohci.h +#define DRIVER_DESC OHCI SPEAr driver + +static const char hcd_name[] = SPEAr-ohci; struct spear_ohci { - struct ohci_hcd ohci; struct clk *clk; }; -#define to_spear_ohci(hcd) (struct spear_ohci *)hcd_to_ohci(hcd) - -static void spear_start_ohci(struct spear_ohci *ohci) -{ - clk_prepare_enable(ohci-clk); -} - -static void spear_stop_ohci(struct spear_ohci *ohci) -{ - clk_disable_unprepare(ohci-clk); -} - -static int ohci_spear_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - ret = ohci_init(ohci); - if (ret 0) - return ret; - ohci-regs = hcd-regs; - - ret = ohci_run(ohci); - if (ret 0) { - dev_err(hcd-self.controller, can't start\n); - ohci_stop(hcd); - return ret; - } - - create_debug_files(ohci); - -#ifdef DEBUG - ohci_dump(ohci, 1);
[PATCH V4 2/6] USB: OHCI: make ohci-omap a separate driver
Separate the TI OHCI OMAP1/2 host controller driver from ohci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; it would be nice to have in 3.11. Signed-off-by: Manjunath Goudar manjunath.gou...@linaro.org Acked-by: Alan Stern st...@rowland.harvard.edu Cc: Felipe Balbi ba...@ti.com Cc: Arnd Bergmann a...@arndb.de Cc: Greg KH g...@kroah.com Cc: linux-usb@vger.kernel.org V2: -omap_ohci_clock_power(0) called in usb_hcd_omap_remove(). -Removed ohci_setup() call from usb_hcd_omap_probe(). -host_enabled and host_initialized variables aren't used for anything thats what removed. V3: -rewritten if (config-otg || config-rwc) block statements into two separate 'if blocks' to handle below scenarios 1. config-otg set scenario. 2. if any of these (config-otg, config-rwc) are set, this scenario should be handled only after ohci_setup() V4: -usb_remove_hcd() function is required a valid clock that is what omap_ohci_clock_power(0) is called after hcd shutdown. --- drivers/usb/host/Kconfig |2 +- drivers/usb/host/Makefile|1 + drivers/usb/host/ohci-hcd.c | 18 - drivers/usb/host/ohci-omap.c | 156 ++ 4 files changed, 55 insertions(+), 122 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 7b8f6bd..99b7e7e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -376,7 +376,7 @@ config USB_OHCI_HCD if USB_OHCI_HCD config USB_OHCI_HCD_OMAP1 - bool OHCI support for OMAP1/2 chips + tristate OHCI support for OMAP1/2 chips depends on ARCH_OMAP1 default y ---help--- diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 26cf69a..c7076ec 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -47,6 +47,7 @@ obj-$(CONFIG_USB_OHCI_HCD)+= ohci-hcd.o obj-$(CONFIG_USB_OHCI_HCD_PCI) += ohci-pci.o obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)+= ohci-platform.o obj-$(CONFIG_USB_OHCI_EXYNOS) += ohci-exynos.o +obj-$(CONFIG_USB_OHCI_HCD_OMAP1) += ohci-omap.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 2980bb6..1abc1e7 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1182,11 +1182,6 @@ MODULE_LICENSE (GPL); #define S3C2410_PLATFORM_DRIVERohci_hcd_s3c2410_driver #endif -#ifdef CONFIG_USB_OHCI_HCD_OMAP1 -#include ohci-omap.c -#define OMAP1_PLATFORM_DRIVER ohci_hcd_omap_driver -#endif - #ifdef CONFIG_USB_OHCI_HCD_OMAP3 #include ohci-omap3.c #define OMAP3_PLATFORM_DRIVER ohci_hcd_omap3_driver @@ -1289,12 +1284,6 @@ static int __init ohci_hcd_mod_init(void) goto error_platform; #endif -#ifdef OMAP1_PLATFORM_DRIVER - retval = platform_driver_register(OMAP1_PLATFORM_DRIVER); - if (retval 0) - goto error_omap1_platform; -#endif - #ifdef OMAP3_PLATFORM_DRIVER retval = platform_driver_register(OMAP3_PLATFORM_DRIVER); if (retval 0) @@ -1408,10 +1397,6 @@ static int __init ohci_hcd_mod_init(void) platform_driver_unregister(OMAP3_PLATFORM_DRIVER); error_omap3_platform: #endif -#ifdef OMAP1_PLATFORM_DRIVER - platform_driver_unregister(OMAP1_PLATFORM_DRIVER); - error_omap1_platform: -#endif #ifdef PLATFORM_DRIVER platform_driver_unregister(PLATFORM_DRIVER); error_platform: @@ -1466,9 +1451,6 @@ static void __exit ohci_hcd_mod_exit(void) #ifdef OMAP3_PLATFORM_DRIVER platform_driver_unregister(OMAP3_PLATFORM_DRIVER); #endif -#ifdef OMAP1_PLATFORM_DRIVER - platform_driver_unregister(OMAP1_PLATFORM_DRIVER); -#endif #ifdef PLATFORM_DRIVER platform_driver_unregister(PLATFORM_DRIVER); #endif diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 8747fa6..8149ef0 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -14,12 +14,21 @@ * This file is licenced under the GPL. */ -#include linux/signal.h -#include linux/jiffies.h -#include linux/platform_device.h #include linux/clk.h +#include linux/dma-mapping.h #include linux/err.h #include linux/gpio.h +#include linux/io.h +#include linux/jiffies.h +#include linux/kernel.h +#include linux/module.h +#include linux/usb/otg.h +#include linux/platform_device.h +#include linux/signal.h +#include linux/usb.h +#include linux/usb/hcd.h + +#include ohci.h #include asm/io.h #include asm/mach-types.h @@ -42,10 +51,7 @@ #define OMAP1510_LB_MMU_RAM_H 0xfffec234 #define OMAP1510_LB_MMU_RAM_L 0xfffec238 - -#ifndef CONFIG_ARCH_OMAP -#error This file is OMAP bus glue. CONFIG_OMAP must be defined. -#endif +#define DRIVER_DESC OHCI OMAP driver #ifdef CONFIG_TPS65010 #include linux/i2c/tps65010.h @@ -68,8 +74,9 @@ extern int ocpi_enable(void); static struct clk *usb_host_ck; static
[PATCH V4 3/6] USB: OHCI: make ohci-omap3 a separate driver
Separate the TI OHCI OMAP3 host controller driver from ohci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; it would be nice to have in 3.11. Signed-off-by: Manjunath Goudar manjunath.gou...@linaro.org Acked-by: Alan Stern st...@rowland.harvard.edu Cc: Anand Gadiyar gadi...@ti.com Cc: Felipe Balbi ba...@ti.com Cc: Arnd Bergmann a...@arndb.de Cc: Greg KH g...@kroah.com Cc: linux-usb@vger.kernel.org V2: -ohci_setup() removed because it is called in .reset member of the ohci_hc_driver structure. -The improper multi-line commenting style written in proper way. ('*' characters aligned in vertically). V3: -RemoteWakeupConnected setting has been removed. V4: -V3 modification revert back, only ohci-regs setting write() function has been removed because ohci-regs doesn't get set until usb_add_hcd. --- drivers/usb/host/Kconfig |2 +- drivers/usb/host/Makefile |1 + drivers/usb/host/ohci-hcd.c | 18 --- drivers/usb/host/ohci-omap3.c | 118 + 4 files changed, 40 insertions(+), 99 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 99b7e7e..3eab432 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -383,7 +383,7 @@ config USB_OHCI_HCD_OMAP1 Enables support for the OHCI controller on OMAP1/2 chips. config USB_OHCI_HCD_OMAP3 - bool OHCI support for OMAP3 and later chips + tristate OHCI support for OMAP3 and later chips depends on (ARCH_OMAP3 || ARCH_OMAP4) default y ---help--- diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index c7076ec..954466d 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PCI)+= ohci-pci.o obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)+= ohci-platform.o obj-$(CONFIG_USB_OHCI_EXYNOS) += ohci-exynos.o obj-$(CONFIG_USB_OHCI_HCD_OMAP1) += ohci-omap.o +obj-$(CONFIG_USB_OHCI_HCD_OMAP3) += ohci-omap3.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 1abc1e7..cad51d2 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1182,11 +1182,6 @@ MODULE_LICENSE (GPL); #define S3C2410_PLATFORM_DRIVERohci_hcd_s3c2410_driver #endif -#ifdef CONFIG_USB_OHCI_HCD_OMAP3 -#include ohci-omap3.c -#define OMAP3_PLATFORM_DRIVER ohci_hcd_omap3_driver -#endif - #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #include ohci-pxa27x.c #define PLATFORM_DRIVERohci_hcd_pxa27x_driver @@ -1284,12 +1279,6 @@ static int __init ohci_hcd_mod_init(void) goto error_platform; #endif -#ifdef OMAP3_PLATFORM_DRIVER - retval = platform_driver_register(OMAP3_PLATFORM_DRIVER); - if (retval 0) - goto error_omap3_platform; -#endif - #ifdef OF_PLATFORM_DRIVER retval = platform_driver_register(OF_PLATFORM_DRIVER); if (retval 0) @@ -1393,10 +1382,6 @@ static int __init ohci_hcd_mod_init(void) platform_driver_unregister(OF_PLATFORM_DRIVER); error_of_platform: #endif -#ifdef OMAP3_PLATFORM_DRIVER - platform_driver_unregister(OMAP3_PLATFORM_DRIVER); - error_omap3_platform: -#endif #ifdef PLATFORM_DRIVER platform_driver_unregister(PLATFORM_DRIVER); error_platform: @@ -1448,9 +1433,6 @@ static void __exit ohci_hcd_mod_exit(void) #ifdef OF_PLATFORM_DRIVER platform_driver_unregister(OF_PLATFORM_DRIVER); #endif -#ifdef OMAP3_PLATFORM_DRIVER - platform_driver_unregister(OMAP3_PLATFORM_DRIVER); -#endif #ifdef PLATFORM_DRIVER platform_driver_unregister(PLATFORM_DRIVER); #endif diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index 8f71357..e14f4d9 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c @@ -29,90 +29,22 @@ * - add kernel-doc */ +#include linux/dma-mapping.h +#include linux/kernel.h +#include linux/module.h +#include linux/of.h +#include linux/usb/otg.h #include linux/platform_device.h #include linux/pm_runtime.h -#include linux/of.h -#include linux/dma-mapping.h - -/*-*/ - -static int ohci_omap3_init(struct usb_hcd *hcd) -{ - dev_dbg(hcd-self.controller, starting OHCI controller\n); - - return ohci_init(hcd_to_ohci(hcd)); -} - -/*-*/ - -static int ohci_omap3_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - /* -* RemoteWakeupConnected has to be set explicitly before -* calling ohci_run. The reset value of RWC is 0. -*/ - ohci-hc_control = OHCI_CTRL_RWC; - writel(OHCI_CTRL_RWC,
Re: [PATCH 01/15] drivers: phy: add generic PHY framework
Hi, On Wed, Jul 31, 2013 at 11:14:32AM +0530, Kishon Vijay Abraham I wrote: IMHO we need a lookup method for PHYs, just like for clocks, regulators, PWMs or even i2c busses because there are complex cases when passing just a name using platform data will not work. I would second what Stephen said [1] and define a structure doing things in a DT-like way. Example; [platform code] static const struct phy_lookup my_phy_lookup[] = { PHY_LOOKUP(s3c-hsotg.0, otg, samsung-usbphy.1, phy.2), The only problem here is that if *PLATFORM_DEVID_AUTO* is used while creating the device, the ids in the device name would change and PHY_LOOKUP wont be useful. I don't think this is a problem. All the existing lookup methods already use ID to identify devices (see regulators, clkdev, PWMs, i2c, ...). You can simply add a requirement that the ID must be assigned manually, without using PLATFORM_DEVID_AUTO to use PHY lookup. And I'm saying that this idea, of using a specific name and id, is frought with fragility and will break in the future in various ways when devices get added to systems, making these strings constantly have to be kept up to date with different board configurations. People, NEVER, hardcode something like an id. The fact that this happens today with the clock code, doesn't make it right, it makes the clock code wrong. Others have already said that this is wrong there as well, as systems change and dynamic ids get used more and more. Let's not repeat the same mistakes of the past just because we refuse to learn from them... So again, the find a phy by a string functions should be removed, the device id should be automatically created by the phy core just to make things unique in sysfs, and no driver code should _ever_ be reliant on the number that is being created, and the pointer to the phy structure should be used everywhere instead. With those types of changes, I will consider merging this subsystem, but without them, sorry, I will not. I'll agree with Greg here, the very fact that we see people trying to add a requirement of *NOT* using PLATFORM_DEVID_AUTO already points to a big problem in the framework. The fact is that if we don't allow PLATFORM_DEVID_AUTO we will end up adding similar infrastructure to the driver themselves to make sure we don't end up with duplicate names in sysfs in case we have multiple instances of the same IP in the SoC (or several of the same PCIe card). I really don't want to go back to that. If we are using PLATFORM_DEVID_AUTO, then I dont see any way we can give the correct binding information to the PHY framework. I think we can drop having this non-dt support in PHY framework? I see only one platform (OMAP3) going to be needing this non-dt support and we can use the USB PHY library for it. you shouldn't drop support for non-DT platform, in any case we lived without DT (and still do) for years. Gotta find a better way ;-) -- balbi signature.asc Description: Digital signature
[PATCH] usb: dwc3: use dev_get_platdata()
Use the wrapper function for retrieving the platform_data instead of accessing dev-platform_data directly. Inspired-by: Jingoo Han jg1@samsung.com Signed-off-by: Felipe Balbi ba...@ti.com --- drivers/usb/dwc3/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index da0a4b8..aa48abd 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -350,11 +350,11 @@ static void dwc3_core_exit(struct dwc3 *dwc) static int dwc3_probe(struct platform_device *pdev) { - struct dwc3_platform_data *pdata = pdev-dev.platform_data; + struct device *dev = pdev-dev; + struct dwc3_platform_data *pdata = dev_get_platdata(dev); struct device_node *node = pdev-dev.of_node; struct resource *res; struct dwc3 *dwc; - struct device *dev = pdev-dev; int ret = -ENOMEM; -- 1.8.3.4.840.g6a90778 -- 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: FUSB200 xhci issue
Am 28.07.2013 22:41, schrieb Christian Lamparter: On Sunday, July 28, 2013 04:28:25 PM Oleksij Rempel wrote: Am 28.07.2013 14:12, schrieb Oleksij Rempel: Am 28.07.2013 13:38, schrieb Christian Lamparter: Anyway, I tried the -next branch. commit dbbb809d592dde0b3c9ecb97b3b387ff8e40e799 Author: Oleksij Rempel li...@rempel-privat.de Date: Wed Jul 24 10:26:18 2013 +0200 k2_fw_usb_api: workaround for EP4 bug. but still, the device won't show up after autosuspend. Hm... firmware probably didn't rebooted before suspend. Did interface was up, before autosuspend? If no, you need latest wireles-testing - there are patches to handle this issue. Or just make ifconfig wlan1 up before rmmod. Oh, I it was on the latest wireless-testing. (And the ath9k_htc module had the patch ath9k_htc: reboot firmwware if it was loaded). Furthermore, I did the same test with one of the ehci-only ports and it worked. Both, devices (one had a AR7015, the other a AR9271) came back after autosuspend there. Grrr... so it brings us back to xhci issue. Even EP4 workaround wont work here :( Suddenly i have no more ideas. Sarah, it's your turn now. Christian, can you please provide some more info about your xhci controller. I'll try to get me same. Well, it's a laptop (HP DV6-6003EG). I recon that getting 100% the same setup will be difficult. However, since the uPD720200 was/is very popular, it should be very easy to find one. [It's probably on all of these 10 euro usb-3.0 pcie-adapters. So as long as you got a free 1x-pcie port you should be good.] Here's the lspci summary: 19:00.0 USB controller [0c03]: NEC Corporation uPD720200 USB 3.0 Host Controller [1033:0194] (rev 04) (prog-if 30 [XHCI]) Subsystem: Hewlett-Packard Company Device [103c:1657] Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast TAbort- TAbort- MAbort- SERR- PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 19 Region 0: Memory at d340 (64-bit, non-prefetchable) [size=8K] Capabilities: access denied Kernel driver in use: xhci_hcd Thx... i purchased on random on ebay, will see what i get. I know now why carl9170 don't triggering this bug. Carl uses EP4 as Interrupt with packet size 64. ath9k-htc initially have EP4=Intr, Interval=1, but will reconfigure it to Bulk, Interval=0. It mean, before usb suspend EP4=Bulk, Interval=0 and after resume EP4=Intr, Inter=?. May be xhci can't handle some thing like this? Or may be interval stay 0, and xhci will overfill usb buffer on adapter - at least it looks so. -- Regards, Oleksij -- 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/19] usb/gadget: configfs: add a method to unregister the gadget
Add a method to unregister the gadget using its config_item. There can be functions (e.g. mass storage), which in some circumstances need the gadget stopped. Add a method of stopping the gadget. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/configfs.c |8 drivers/usb/gadget/configfs.h |6 ++ 2 files changed, 14 insertions(+), 0 deletions(-) create mode 100644 drivers/usb/gadget/configfs.h diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 80e7f75..cda3ead 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -989,6 +989,14 @@ static struct configfs_subsystem gadget_subsys = { .su_mutex = __MUTEX_INITIALIZER(gadget_subsys.su_mutex), }; +void unregister_gadget_item(struct config_item *item) +{ + struct gadget_info *gi = to_gadget_info(item); + + unregister_gadget(gi); +} +EXPORT_SYMBOL(unregister_gadget_item); + static int __init gadget_cfs_init(void) { int ret; diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h new file mode 100644 index 000..a7b564a --- /dev/null +++ b/drivers/usb/gadget/configfs.h @@ -0,0 +1,6 @@ +#ifndef USB__GADGET__CONFIGFS__H +#define USB__GADGET__CONFIGFS__H + +void unregister_gadget_item(struct config_item *item); + +#endif /* USB__GADGET__CONFIGFS__H */ -- 1.7.0.4 -- 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 00/19] Equivalent of g_mass_storage with configfs
This series aims at integrating configfs into mass storage, the way it has been done for acm, ncm, ecm, eem, ecm subset, rndis, obex and phonet. It contains everything that is required to provide the equivalent of g_mass_storage.ko with configfs. Mass storage itself is quite large, so the resulting patch series is a bit lengthy. However, it is supposed to be done in steps like this: 1) preliminary work, e.g. factoring out a header file, creating a utility u_ms.ko module, use usb_gstrings_attach 2) prepare for initializing the fsg_common structure in smaller steps instead of in one big step 3) usual stuff, similar to functions previously converted to configfs v1..v2: - simpified adding a level of indirection for fsg_lun storing - reworked lun debugging macros in order not to use struct device [both after discussion with Alan, thanks] v2..v3: - implemented changes resulting from Michal's comments [thanks, Michal] - used static inline fsg_common_remove_sysfs wherever possible - some small bugfixes A branch will be available here since 31st July: git://git.infradead.org/users/kmpark/linux-samsung usb-gadget-configfs BACKWARD COMPATIBILITY == Please note that the old g_mass_storage.ko is still available and works. USING THE NEW GADGET == Please refer to this post: http://www.spinics.net/lists/linux-usb/msg76388.html for general information from Sebastian on how to use configfs-based gadgets (*). With configfs the procedure is as follows, compared to the information mentioned above (*): instead of mkdir functions/acm.ttyS1 do mkdir functions/mass_storage.instance name e.g. mkdir functions/mass_storage.0 In functions/function.instance name there will be the following attribute files: stall - Set to permit function to halt bulk endpoints. Disabled on some USB devices known not to work correctly. You should set it to true. num_buffers - Number of pipeline buffers. Valid numbers are 2..4. Available only if CONFIG_USB_GADGET_DEBUG_FILES is set. and a default lun.0 directory corresponding to SCSI LUN #0. A new lun can be added with mkdir: $ mkdir functions/mass_storage.0/partition.5 Lun numbering does not have to be continuous, except for lun #0 which is created by default. A maximum of 8 luns can be specified and they all must be named following the name.number scheme. The numbers can be 0..8. Probably a good convention is to name the luns lun.number, although it is not mandatory. In each lun directory there are the following attribute files: file- The path to the backing file for the LUN. Required if LUN is not marked as removable. ro - Flag specifying access to the LUN shall be read-only. This is implied if CD-ROM emulation is enabled as well as when it was impossible to open filename in R/W mode. removable - Flag specifying that LUN shall be indicated as being removable. cdrom - Flag specifying that LUN shall be reported as being a CD-ROM. nofua - Flag specifying that FUA flag in SCSI WRITE(10,12) The rest of the procedure (*) remains the same. An example gadget with two luns: $ modprobe libcomposite $ mount none cfg -t configfs $ mkdir cfg/usb_gadget/g1 $ cd cfg/usb_gadget/g1 $ mkdir configs/c.1 $ mkdir functions/mass_storage.0 $ echo /root/lun0.img functions/mass_storage.0/lun.0/file $ mkdir functions/mass_storage.0/lun.1 $ echo /root/lun1.img functions/mass_storage.0/lun.1/file $ mkdir strings/0x409 $ mkdir configs/c.1/strings/0x409 $ echo 0xa4a2 idProduct $ echo 0x0525 idVendor $ echo my-serial-num strings/0x409/serialnumber $ echo my-manufacturer strings/0x409/manufacturer $ echo Mass Storage Gadget strings/0x409/product $ echo Conf 1 configs/c.1/strings/0x409/configuration $ echo 120 configs/c.1/MaxPower $ ln -s functions/mass_storage.0 configs/c.1 $ echo s3c-hsotg UDC After unbinding the gadget with echo UDC the symbolic links in the configuration directory can be removed, the strings/* subdirectories in the configuration directory can be removed, the strings/* subdirectories at the gadget level can be removed and the configs/* subdirectories can be removed. The functions/* subdirectories can be removed. After that the gadget directory can be removed. After that the respective modules can be unloaded. TESTING THE FUNCTIONS (actually there is only one) = mass_storage) device: connect the gadget, enable it host: dmesg, see the USB drives appear (if system configured to automatically mount) Andrzej Pietrasiewicz (19): usb/gadget: configfs: add a method to unregister the gadget usb/gadget: create a utility
[PATCH v3 16/19] usb/gadget: mass_storage: convert to new interface of f_mass_storage
Convert old mass_storage gadget to use the new interface of f_mass_storage so that later the compatibility layer in f_mass_storage can be removed. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/Kconfig|1 + drivers/usb/gadget/mass_storage.c | 107 +++- 2 files changed, 81 insertions(+), 27 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index c79d8be..d52fd2a 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -901,6 +901,7 @@ config USB_MASS_STORAGE depends on BLOCK select USB_LIBCOMPOSITE select USB_U_MS + select USB_F_MASS_STORAGE help The Mass Storage Gadget acts as a USB Mass Storage disk drive. As its storage repository it can use a regular file or a block diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 6b79814..39a5316 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -46,17 +46,7 @@ #define FSG_VENDOR_ID 0x0525 /* NetChip */ #define FSG_PRODUCT_ID 0xa4a5 /* Linux-USB File-backed Storage Gadget */ -/*-*/ - -/* - * kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a gcc --combine ... part1.c part2.c part3.c ... build would. - */ -#define USB_FMS_INCLUDED -#include f_mass_storage.c +#include f_mass_storage.h /*-*/ USB_GADGET_COMPOSITE_OPTIONS(); @@ -107,6 +97,9 @@ static struct usb_gadget_strings *dev_strings[] = { NULL, }; +static struct usb_function_instance *fi_msg; +static struct usb_function *f_msg; + /** Configurations **/ static struct fsg_module_parameters mod_data = { @@ -139,13 +132,7 @@ static int msg_thread_exits(struct fsg_common *common) static int __init msg_do_config(struct usb_configuration *c) { - static const struct fsg_operations ops = { - .thread_exits = msg_thread_exits, - }; - static struct fsg_common common; - - struct fsg_common *retp; - struct fsg_config config; + struct fsg_opts *opts; int ret; if (gadget_is_otg(c-cdev-gadget)) { @@ -153,15 +140,24 @@ static int __init msg_do_config(struct usb_configuration *c) c-bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - fsg_config_from_params(config, mod_data, fsg_num_buffers); - config.ops = ops; + opts = container_of(fi_msg, struct fsg_opts, func_inst); + + f_msg = usb_get_function(fi_msg); + if (IS_ERR(f_msg)) + return PTR_ERR(f_msg); - retp = fsg_common_init(common, c-cdev, config); - if (IS_ERR(retp)) - return PTR_ERR(retp); + ret = fsg_common_run_thread(opts-common); + if (ret) + goto put_func; - ret = fsg_bind_config(c-cdev, c, common); - fsg_common_put(common); + ret = usb_add_function(c, f_msg); + if (ret) + goto put_func; + + return 0; + +put_func: + usb_put_function(f_msg); return ret; } @@ -176,23 +172,79 @@ static struct usb_configuration msg_config_driver = { static int __init msg_bind(struct usb_composite_dev *cdev) { + static const struct fsg_operations ops = { + .thread_exits = msg_thread_exits, + }; + struct fsg_opts *opts; + struct fsg_config config; int status; + fi_msg = usb_get_function_instance(mass_storage); + if (IS_ERR(fi_msg)) + return PTR_ERR(fi_msg); + + fsg_config_from_params(config, mod_data, fsg_num_buffers); + opts = container_of(fi_msg, struct fsg_opts, func_inst); + + opts-no_configfs = true; + status = fsg_common_set_num_buffers(opts-common, fsg_num_buffers); + if (status) + goto fail; + + status = fsg_common_set_nluns(opts-common, config.nluns); + if (status) + goto fail_set_nluns; + + fsg_common_set_ops(opts-common, ops); + + status = fsg_common_set_cdev(opts-common, cdev, config.can_stall); + if (status) + goto fail_set_cdev; + + fsg_common_set_sysfs(opts-common, true); + status = fsg_common_create_luns(opts-common, config); + if (status) + goto fail_set_cdev; + + fsg_common_set_inquiry_string(opts-common, config.vendor_name, + config.product_name); + status = usb_string_ids_tab(cdev, strings_dev); if
[PATCH v3 15/19] usb/gadget: f_mass_storage: convert to new function interface with backward compatibility
Converting mass storage to the new function interface requires converting the USB mass storage's function code and its users. This patch converts the f_mass_storage.c to the new function interface. The file is now compiled into a separate usb_f_mass_storage.ko module. The old function interface is provided by means of a preprocessor conditional directives. After all users are converted, the old interface can be removed. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/Kconfig |3 + drivers/usb/gadget/Makefile |2 + drivers/usb/gadget/acm_ms.c |1 + drivers/usb/gadget/f_mass_storage.c | 217 +++--- drivers/usb/gadget/f_mass_storage.h |7 + drivers/usb/gadget/mass_storage.c |1 + drivers/usb/gadget/multi.c |1 + 7 files changed, 212 insertions(+), 20 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 0eaa4ed..c79d8be 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -544,6 +544,9 @@ config USB_F_RNDIS config USB_U_MS tristate +config USB_F_MASS_STORAGE + tristate + choice tristate USB Gadget Drivers default USB_ETH diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index b9c779a..dccab69 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -63,6 +63,8 @@ usb_f_rndis-y := f_rndis.o obj-$(CONFIG_USB_F_RNDIS) += usb_f_rndis.o u_ms-y := storage_common.o obj-$(CONFIG_USB_U_MS) += u_ms.o +usb_f_mass_storage-y := f_mass_storage.o +obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o # # USB gadget drivers diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 992ffb0..31aae8f 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -40,6 +40,7 @@ * the runtime footprint, and giving us at least some parts of what * a gcc --combine ... part1.c part2.c part3.c ... build would. */ +#define USB_FMS_INCLUDED #include f_mass_storage.c /*-*/ diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 7ef99f1..0a2b3ae 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -213,6 +213,7 @@ #include linux/spinlock.h #include linux/string.h #include linux/freezer.h +#include linux/module.h #include linux/usb/ch9.h #include linux/usb/gadget.h @@ -2592,11 +2593,17 @@ void fsg_common_get(struct fsg_common *common) { kref_get(common-ref); } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_get); +#endif void fsg_common_put(struct fsg_common *common) { kref_put(common-ref, fsg_common_release); } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_put); +#endif /* check if fsg_num_buffers is within a valid range */ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers) @@ -2634,6 +2641,9 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs) { common-sysfs = sysfs; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_sysfs); +#endif static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n) { @@ -2685,12 +2695,18 @@ error_release: return -ENOMEM; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_num_buffers); +#endif void fsg_common_free_buffers(struct fsg_common *common) { _fsg_common_free_buffers(common-buffhds, common-fsg_num_buffers); common-buffhds = NULL; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_free_buffers); +#endif int fsg_common_set_nluns(struct fsg_common *common, int nluns) { @@ -2716,6 +2732,9 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns) return 0; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_nluns); +#endif void fsg_common_free_luns(struct fsg_common *common) { @@ -2723,17 +2742,26 @@ void fsg_common_free_luns(struct fsg_common *common) kfree(common-luns); common-luns = NULL; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_free_luns); +#endif void fsg_common_set_ops(struct fsg_common *common, const struct fsg_operations *ops) { common-ops = ops; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_ops); +#endif void fsg_common_set_private_data(struct fsg_common *common, void *priv) { common-private_data = priv; } +#ifndef USB_FMS_INCLUDED +EXPORT_SYMBOL(fsg_common_set_private_data); +#endif int fsg_common_set_cdev(struct fsg_common *common, struct usb_composite_dev *cdev, bool can_stall) @@ -2763,6 +2791,9 @@ int fsg_common_set_cdev(struct fsg_common *common, return 0; } +#ifndef USB_FMS_INCLUDED
[PATCH v3 07/19] usb/gadget: f_mass_storage: use fsg_common_setup in fsg_common_init
fsg_common_init is a lengthy function. Now there are helper functions which cover all parts of it. Use them. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 19 +++ 1 files changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index ef4733c..2f6e3c3 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -3018,16 +3018,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, return ERR_PTR(-EINVAL); } - /* Allocate? */ - if (!common) { - common = kzalloc(sizeof *common, GFP_KERNEL); - if (!common) - return ERR_PTR(-ENOMEM); - common-free_storage_on_release = 1; - } else { - memset(common, 0, sizeof *common); - common-free_storage_on_release = 0; - } + common = fsg_common_setup(common, !!common); + if (IS_ERR(common)) + return common; common-sysfs = true; common-state = FSG_STATE_IDLE; @@ -3067,8 +3060,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, } common-luns = curlun_it; - init_rwsem(common-filesem); - for (i = 0, lcfg = cfg-luns; i nluns; ++i, ++curlun_it, ++lcfg) { struct fsg_lun *curlun; @@ -3168,8 +3159,6 @@ buffhds_first_it: common-can_stall = cfg-can_stall !(gadget_is_at91(common-gadget)); - spin_lock_init(common-lock); - kref_init(common-ref); /* Tell the thread to start working */ common-thread_task = @@ -3178,8 +3167,6 @@ buffhds_first_it: rc = PTR_ERR(common-thread_task); goto error_release; } - init_completion(common-thread_notifier); - init_waitqueue_head(common-fsg_wait); /* Information */ INFO(common, FSG_DRIVER_DESC , version: FSG_DRIVER_VERSION \n); -- 1.7.0.4 -- 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 04/19] usb/gadget: f_mass_storage: add a level of indirection for luns storage
This is needed to prepare for configfs integration. So far the luns have been allocated during gadget's initialization, based on the nluns module parameter's value; the exact number is known when the gadget is initialized and that number of luns is allocated in one go; they all will be used. When configfs is in place, the luns will be created one-by-one by the user. Once the user is satisfied with the number of luns, they activate the gadget. The number of luns must be = FSG_MAX_LUN (currently 8), but other than that it is not known up front and the user need not use contiguous numbering (apart from the default lun #0). On the other hand, the function code uses lun numbers to identify them and the number needs to be used as an index into an array. Given the above, an array needs to be allocated, but it might happen that 7 out of its 8 elements will not be used. On my machine sizeof(struct fsg_lun) == 462, so 3k of memory is allocated but not used in the worst case. By adding another level of indirection (allocating an array of pointers to struct fsg_lun and then allocating individual luns instead of an array of struct fsg_luns) at most 7 pointers are wasted, which is much less. This patch also changes some for/while loops to cope with the fact that in the luns array some entries are potentially empty. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 60 --- 1 files changed, 41 insertions(+), 19 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index c36e208..05d34a0 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -274,7 +274,7 @@ struct fsg_common { unsigned intnluns; unsigned intlun; - struct fsg_lun *luns; + struct fsg_lun **luns; struct fsg_lun *curlun; unsigned intbulk_out_maxpacket; @@ -2151,7 +2151,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) common-data_dir = DATA_DIR_NONE; common-lun = cbw-Lun; if (common-lun common-nluns) - common-curlun = common-luns[common-lun]; + common-curlun = common-luns[common-lun]; else common-curlun = NULL; common-tag = cbw-Tag; @@ -2297,7 +2297,9 @@ reset: common-running = 1; for (i = 0; i common-nluns; ++i) - common-luns[i].unit_attention_data = SS_RESET_OCCURRED; + if (common-luns[i]) + common-luns[i]-unit_attention_data = + SS_RESET_OCCURRED; return rc; } @@ -2397,7 +2399,9 @@ static void handle_exception(struct fsg_common *common) common-state = FSG_STATE_STATUS_PHASE; else { for (i = 0; i common-nluns; ++i) { - curlun = common-luns[i]; + curlun = common-luns[i]; + if (!curlun) + continue; curlun-prevent_medium_removal = 0; curlun-sense_data = SS_NO_SENSE; curlun-unit_attention_data = SS_NO_SENSE; @@ -2439,8 +2443,9 @@ static void handle_exception(struct fsg_common *common) * CONFIG_CHANGE cases. */ /* for (i = 0; i common-nluns; ++i) */ - /* common-luns[i].unit_attention_data = */ - /* SS_RESET_OCCURRED; */ + /* if (common-luns[i]) */ + /* common-luns[i]-unit_attention_data = */ + /* SS_RESET_OCCURRED; */ break; case FSG_STATE_CONFIG_CHANGE: @@ -2536,12 +2541,13 @@ static int fsg_main_thread(void *common_) if (!common-ops || !common-ops-thread_exits || common-ops-thread_exits(common) 0) { - struct fsg_lun *curlun = common-luns; + struct fsg_lun **curlun_it = common-luns; unsigned i = common-nluns; down_write(common-filesem); - for (; i--; ++curlun) { - if (!fsg_lun_is_open(curlun)) + for (; i--; ++curlun_it) { + struct fsg_lun *curlun = *curlun_it; + if (!curlun || !fsg_lun_is_open(curlun)) continue; fsg_lun_close(curlun); @@ -2602,7 +2608,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, { struct usb_gadget *gadget = cdev-gadget; struct fsg_buffhd *bh; - struct fsg_lun *curlun; + struct fsg_lun **curlun_it; struct fsg_lun_config *lcfg; int nluns, i, rc; char *pathbuf; @@ -2659,16
[PATCH v3 19/19] usb/gadget: f_mass_storage: add configfs support
From this commit on f_mass_storage is available through configfs. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- .../ABI/testing/configfs-usb-gadget-mass-storage | 31 ++ drivers/usb/gadget/Kconfig | 11 + drivers/usb/gadget/f_mass_storage.c| 368 drivers/usb/gadget/f_mass_storage.h| 17 + 4 files changed, 427 insertions(+), 0 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-mass-storage diff --git a/Documentation/ABI/testing/configfs-usb-gadget-mass-storage b/Documentation/ABI/testing/configfs-usb-gadget-mass-storage new file mode 100644 index 000..e1e918e --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-mass-storage @@ -0,0 +1,31 @@ +What: /config/usb-gadget/gadget/functions/mass_storage.name +Date: Jul 2013 +KenelVersion: 3.12 +Description: + The attributes: + + stall - Set to permit function to halt bulk endpoints. + Disabled on some USB devices known not to work + correctly. You should set it to true. + num_buffers - Number of pipeline buffers. Valid numbers + are 2..4. Available only if + CONFIG_USB_GADGET_DEBUG_FILES is set. + +What: /config/usb-gadget/gadget/functions/mass_storage.name/lun.name +Date: Jul 2013 +KenelVersion: 3.12 +Description: + The attributes: + + file- The path to the backing file for the LUN. + Required if LUN is not marked as removable. + ro - Flag specifying access to the LUN shall be + read-only. This is implied if CD-ROM emulation + is enabled as well as when it was impossible + to open filename in R/W mode. + removable - Flag specifying that LUN shall be indicated as + being removable. + cdrom - Flag specifying that LUN shall be reported as + being a CD-ROM. + nofua - Flag specifying that FUA flag + in SCSI WRITE(10,12) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index d52fd2a..0f38701 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -684,6 +684,17 @@ config USB_CONFIGFS_PHONET help The Phonet protocol implementation for USB device. +config USB_CONFIGFS_MASS_STORAGE + boolean Mass storage + depends on USB_CONFIGFS + select USB_U_MS + select USB_F_MASS_STORAGE + help + The Mass Storage Gadget acts as a USB Mass Storage disk drive. + As its storage repository it can use a regular file or a block + device (in much the same way as the loop device driver), + specified as a module parameter or sysfs option. + config USB_ZERO tristate Gadget Zero (DEVELOPMENT) select USB_LIBCOMPOSITE diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index aaa8349..f1aa6c0 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -220,6 +220,7 @@ #include linux/usb/composite.h #include gadget_chips.h +#include configfs.h /**/ @@ -,6 +3334,350 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, #else +static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item) +{ + return container_of(to_config_group(item), struct fsg_lun_opts, group); +} + +static inline struct fsg_opts *to_fsg_opts(struct config_item *item) +{ + return container_of(to_config_group(item), struct fsg_opts, + func_inst.group); +} + +CONFIGFS_ATTR_STRUCT(fsg_lun_opts); +CONFIGFS_ATTR_OPS(fsg_lun_opts); + +static void fsg_lun_attr_release(struct config_item *item) +{ + struct fsg_lun_opts *lun_opts; + + lun_opts = to_fsg_lun_opts(item); + kfree(lun_opts); +} + +static struct configfs_item_operations fsg_lun_item_ops = { + .release= fsg_lun_attr_release, + .show_attribute = fsg_lun_opts_attr_show, + .store_attribute = fsg_lun_opts_attr_store, +}; + +static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page) +{ + struct fsg_opts *fsg_opts; + + fsg_opts = to_fsg_opts(opts-group.cg_item.ci_parent); + + return fsg_show_file(opts-lun, fsg_opts-common-filesem, page); +} + +static ssize_t fsg_lun_opts_file_store(struct fsg_lun_opts *opts, + const char *page, size_t len) +{ + struct fsg_opts
[PATCH v3 03/19] usb/gadget: f_mass_storage: factor out a header file
In order to prepare for the new function interface the f_mass_storage.c needs to be compiled as a module, and so a header file will be required. This patch factors out some code to a new f_mass_storage.h. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 117 ++-- drivers/usb/gadget/f_mass_storage.h | 126 +++ 2 files changed, 133 insertions(+), 110 deletions(-) create mode 100644 drivers/usb/gadget/f_mass_storage.h diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 163d911..c36e208 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -229,6 +229,7 @@ static const char fsg_string_interface[] = Mass Storage; #include storage_common.h +#include f_mass_storage.h /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ static struct usb_string fsg_strings[] = { @@ -246,18 +247,6 @@ static struct usb_gadget_strings fsg_stringtab = { struct fsg_dev; struct fsg_common; -/* FSF callback functions */ -struct fsg_operations { - /* -* Callback function to call when thread exits. If no -* callback is set or it returns value lower then zero MSF -* will force eject all LUNs it operates on (including those -* marked as non-removable or with prevent_medium_removal flag -* set). -*/ - int (*thread_exits)(struct fsg_common *common); -}; - /* Data shared by all the FSG instances. */ struct fsg_common { struct usb_gadget *gadget; @@ -324,28 +313,6 @@ struct fsg_common { struct kref ref; }; -struct fsg_config { - unsigned nluns; - struct fsg_lun_config { - const char *filename; - char ro; - char removable; - char cdrom; - char nofua; - } luns[FSG_MAX_LUNS]; - - /* Callback functions. */ - const struct fsg_operations *ops; - /* Gadget's private data. */ - void*private_data; - - const char *vendor_name;/* 8 characters or less */ - const char *product_name; /* 16 characters or less */ - - charcan_stall; - unsigned intfsg_num_buffers; -}; - struct fsg_dev { struct usb_function function; struct usb_gadget *gadget;/* Copy of cdev-gadget */ @@ -2609,12 +2576,12 @@ static void fsg_lun_release(struct device *dev) /* Nothing needs to be done */ } -static inline void fsg_common_get(struct fsg_common *common) +void fsg_common_get(struct fsg_common *common) { kref_get(common-ref); } -static inline void fsg_common_put(struct fsg_common *common) +void fsg_common_put(struct fsg_common *common) { kref_put(common-ref, fsg_common_release); } @@ -2629,9 +2596,9 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers) return -EINVAL; } -static struct fsg_common *fsg_common_init(struct fsg_common *common, - struct usb_composite_dev *cdev, - struct fsg_config *cfg) +struct fsg_common *fsg_common_init(struct fsg_common *common, + struct usb_composite_dev *cdev, + struct fsg_config *cfg) { struct usb_gadget *gadget = cdev-gadget; struct fsg_buffhd *bh; @@ -3008,62 +2975,8 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, /* Module parameters */ -struct fsg_module_parameters { - char*file[FSG_MAX_LUNS]; - boolro[FSG_MAX_LUNS]; - boolremovable[FSG_MAX_LUNS]; - boolcdrom[FSG_MAX_LUNS]; - boolnofua[FSG_MAX_LUNS]; - - unsigned intfile_count, ro_count, removable_count, cdrom_count; - unsigned intnofua_count; - unsigned intluns; /* nluns */ - boolstall; /* can_stall */ -}; - -#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \ - module_param_array_named(prefix ## name, params.name, type, \ -prefix ## params.name ## _count, \ -S_IRUGO); \ - MODULE_PARM_DESC(prefix ## name, desc) - -#define _FSG_MODULE_PARAM(prefix, params, name, type, desc)\ - module_param_named(prefix ## name, params.name, type, \ - S_IRUGO);\ - MODULE_PARM_DESC(prefix ## name, desc) - -#define __FSG_MODULE_PARAMETERS(prefix, params) \ -
[PATCH v3 05/19] usb/gadget: f_mass_storage: use usb_gstrings_attach
Prepare for handling with configfs. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 25 - 1 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 05d34a0..04ee635 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -242,6 +242,11 @@ static struct usb_gadget_strings fsg_stringtab = { .strings= fsg_strings, }; +static struct usb_gadget_strings *fsg_strings_array[] = { + fsg_stringtab, + NULL, +}; + /*-*/ struct fsg_dev; @@ -2610,6 +2615,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, struct fsg_buffhd *bh; struct fsg_lun **curlun_it; struct fsg_lun_config *lcfg; + struct usb_string *us; int nluns, i, rc; char *pathbuf; @@ -2652,14 +2658,13 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, common-ep0req = cdev-req; common-cdev = cdev; - /* Maybe allocate device-global string IDs, and patch descriptors */ - if (fsg_strings[FSG_STRING_INTERFACE].id == 0) { - rc = usb_string_id(cdev); - if (unlikely(rc 0)) - goto error_release; - fsg_strings[FSG_STRING_INTERFACE].id = rc; - fsg_intf_desc.iInterface = rc; + us = usb_gstrings_attach(cdev, fsg_strings_array, +ARRAY_SIZE(fsg_strings)); + if (IS_ERR(us)) { + rc = PTR_ERR(us); + goto error_release; } + fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id; /* * Create the LUNs, open their backing files, and register the @@ -2953,11 +2958,6 @@ autoconf_fail: /** ADD FUNCTION **/ -static struct usb_gadget_strings *fsg_strings_array[] = { - fsg_stringtab, - NULL, -}; - static int fsg_bind_config(struct usb_composite_dev *cdev, struct usb_configuration *c, struct fsg_common *common) @@ -2970,7 +2970,6 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, return -ENOMEM; fsg-function.name= FSG_DRIVER_DESC; - fsg-function.strings = fsg_strings_array; fsg-function.bind= fsg_bind; fsg-function.unbind = fsg_unbind; fsg-function.setup = fsg_setup; -- 1.7.0.4 -- 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/19] usb/gadget: create a utility module for mass_storage
Converting to configfs requires making the f_mass_storage.c a module. But first we need to get rid of #include storage_common.c. This patch makes storage_common.c a separately compiled file, which is built as a utility module named u_ms.ko. After all mass storage users are converted to the new function interface this module can be eliminated by merging it with the mass storage function's module. USB descriptors are exported so that they can be accessed from f_mass_storage. FSG_VENDOR_ID and FSG_PRODUCT_ID are moved to their only user. Handling of CONFIG_USB_GADGET_DEBUG_FILES is moved to f_mass_storage.c. The fsg_num_buffers static is moved to FSG_MODULE_PARAMETER users, so instead of using a global variable the f_mass_storage introduces fsg_num_buffers member in fsg_common (and fsg_config). fsg_strings and fsg_stringtab are moved to f_mass_storage.c. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/Kconfig |6 + drivers/usb/gadget/Makefile |2 + drivers/usb/gadget/acm_ms.c | 17 ++- drivers/usb/gadget/f_mass_storage.c | 71 ++-- drivers/usb/gadget/mass_storage.c | 25 +++- drivers/usb/gadget/multi.c | 17 ++- drivers/usb/gadget/storage_common.c | 319 ++- drivers/usb/gadget/storage_common.h | 210 +++ 8 files changed, 382 insertions(+), 285 deletions(-) create mode 100644 drivers/usb/gadget/storage_common.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 8e93683..0eaa4ed 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -541,6 +541,9 @@ config USB_F_SUBSET config USB_F_RNDIS tristate +config USB_U_MS + tristate + choice tristate USB Gadget Drivers default USB_ETH @@ -894,6 +897,7 @@ config USB_MASS_STORAGE tristate Mass Storage Gadget depends on BLOCK select USB_LIBCOMPOSITE + select USB_U_MS help The Mass Storage Gadget acts as a USB Mass Storage disk drive. As its storage repository it can use a regular file or a block @@ -1017,6 +1021,7 @@ config USB_G_ACM_MS select USB_LIBCOMPOSITE select USB_U_SERIAL select USB_F_ACM + select USB_U_MS help This driver provides two functions in one configuration: a mass storage, and a CDC ACM (serial port) link. @@ -1033,6 +1038,7 @@ config USB_G_MULTI select USB_U_ETHER select USB_U_RNDIS select USB_F_ACM + select USB_U_MS help The Multifunction Composite Gadget provides Ethernet (RNDIS and/or CDC Ethernet), mass storage and ACM serial link diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index bad08e6..b9c779a 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -61,6 +61,8 @@ usb_f_ecm_subset-y:= f_subset.o obj-$(CONFIG_USB_F_SUBSET) += usb_f_ecm_subset.o usb_f_rndis-y := f_rndis.o obj-$(CONFIG_USB_F_RNDIS) += usb_f_rndis.o +u_ms-y := storage_common.o +obj-$(CONFIG_USB_U_MS) += u_ms.o # # USB gadget drivers diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 4b947bb..992ffb0 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -104,6 +104,20 @@ static struct usb_gadget_strings *dev_strings[] = { /** Configurations **/ static struct fsg_module_parameters fsg_mod_data = { .stall = 1 }; +#ifdef CONFIG_USB_GADGET_DEBUG_FILES + +static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; + +#else + +/* + * Number of buffers we will use. + * 2 is usually enough for good buffering pipeline + */ +#define fsg_num_buffersCONFIG_USB_GADGET_STORAGE_NUM_BUFFERS + +#endif /* CONFIG_USB_DEBUG */ + FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); static struct fsg_common fsg_common; @@ -167,7 +181,8 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) void*retp; /* set up mass storage function */ - retp = fsg_common_from_params(fsg_common, cdev, fsg_mod_data); + retp = fsg_common_from_params(fsg_common, cdev, fsg_mod_data, + fsg_num_buffers); if (IS_ERR(retp)) { status = PTR_ERR(retp); return PTR_ERR(retp); diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 56f1fd1..163d911 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -228,8 +228,18 @@ static const char fsg_string_interface[] = Mass Storage; -#include storage_common.c +#include storage_common.h +/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
[PATCH v3 14/19] usb/gadget: f_mass_storage: use fsg_common_run_thread in fsg_common_init
fsg_common_init is a lengthy function. Now there are helper functions which cover all parts of it. Use them. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 14 +++--- 1 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index fcc6409..7ef99f1 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -3032,21 +3032,13 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, fsg_common_set_inquiry_string(common, cfg-vendor_name, cfg-product_name); - /* Tell the thread to start working */ - common-thread_task = - kthread_create(fsg_main_thread, common, file-storage); - if (IS_ERR(common-thread_task)) { - rc = PTR_ERR(common-thread_task); - goto error_release; - } /* Information */ INFO(common, FSG_DRIVER_DESC , version: FSG_DRIVER_VERSION \n); - INFO(common, Number of LUNs=%d\n, common-nluns); - DBG(common, I/O thread pid: %d\n, task_pid_nr(common-thread_task)); - - wake_up_process(common-thread_task); + rc = fsg_common_run_thread(common); + if (rc) + goto error_release; return common; -- 1.7.0.4 -- 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 18/19] usb/gadget: storage_common: add methods to show/store 'cdrom' and 'removable'
This will be required by configfs integration. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/storage_common.c | 42 +++ drivers/usb/gadget/storage_common.h |5 2 files changed, 47 insertions(+), 0 deletions(-) diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index ab83d11..d59b555 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -359,6 +359,17 @@ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, } EXPORT_SYMBOL(fsg_show_file); +ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf) +{ + return sprintf(buf, %u\n, curlun-cdrom); +} +EXPORT_SYMBOL(fsg_show_cdrom); + +ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf) +{ + return sprintf(buf, %u\n, curlun-removable); +} +EXPORT_SYMBOL(fsg_show_removable); ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, const char *buf, size_t count) @@ -439,4 +450,35 @@ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, } EXPORT_SYMBOL(fsg_store_file); +ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count) +{ + unsignedcdrom; + int ret; + + ret = kstrtouint(buf, 2, cdrom); + if (ret) + return ret; + + curlun-cdrom = cdrom; + + return count; +} +EXPORT_SYMBOL(fsg_store_cdrom); + +ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, + size_t count) +{ + unsignedremovable; + int ret; + + ret = kstrtouint(buf, 2, removable); + if (ret) + return ret; + + curlun-removable = removable; + + return count; +} +EXPORT_SYMBOL(fsg_store_removable); + MODULE_LICENSE(GPL); diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h index aa8bf94..ca7b479 100644 --- a/drivers/usb/gadget/storage_common.h +++ b/drivers/usb/gadget/storage_common.h @@ -214,10 +214,15 @@ ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf); ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf); ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, char *buf); +ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf); +ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf); ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, const char *buf, size_t count); ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count); ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, const char *buf, size_t count); +ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count); +ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, + size_t count); #endif /* USB_STORAGE_COMMON_H */ -- 1.7.0.4 -- 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/19] usb/gadget: f_mass_storage: use fsg_common_create_luns in fsg_common_init
fsg_common_init is a lengthy function. Now there are helper functions which cover all parts of it. Use them. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 101 ++- 1 files changed, 4 insertions(+), 97 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 9dde453..41a94a1 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2999,12 +2999,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, struct usb_composite_dev *cdev, struct fsg_config *cfg) { - struct usb_gadget *gadget = cdev-gadget; - struct fsg_lun **curlun_it; - struct fsg_lun_config *lcfg; - int nluns, i, rc; - char *pathbuf; - + int i, rc; common = fsg_common_setup(common, !!common); if (IS_ERR(common)) @@ -3029,72 +3024,10 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, rc = fsg_common_set_nluns(common, cfg-nluns); if (rc) goto error_release; - curlun_it = common-luns; - nluns = cfg-nluns; - for (i = 0, lcfg = cfg-luns; i nluns; ++i, ++curlun_it, ++lcfg) { - struct fsg_lun *curlun; - - curlun = kzalloc(sizeof(*curlun), GFP_KERNEL); - if (!curlun) { - rc = -ENOMEM; - common-nluns = i; - goto error_release; - } - *curlun_it = curlun; - - curlun-name = kzalloc(MAX_LUN_NAME_LEN, GFP_KERNEL); - if (!curlun-name) { - rc = -ENOMEM; - common-nluns = i; - goto error_release; - } - curlun-cdrom = !!lcfg-cdrom; - curlun-ro = lcfg-cdrom || lcfg-ro; - curlun-initially_ro = curlun-ro; - curlun-removable = lcfg-removable; - curlun-dev.release = fsg_lun_release; - curlun-dev.parent = gadget-dev; - /* curlun-dev.driver = fsg_driver.driver; XXX */ - dev_set_drvdata(curlun-dev, common-filesem); - dev_set_name(curlun-dev, lun%d, i); - strlcpy(curlun-name, dev_name(curlun-dev), MAX_LUN_NAME_LEN); - - rc = device_register(curlun-dev); - if (rc) { - INFO(common, failed to register LUN%d: %d\n, i, rc); - common-nluns = i; - put_device(curlun-dev); - kfree(curlun); - goto error_release; - } - - rc = device_create_file(curlun-dev, - curlun-cdrom - ? dev_attr_ro_cdrom - : dev_attr_ro); - if (rc) - goto error_luns; - rc = device_create_file(curlun-dev, - curlun-removable - ? dev_attr_file - : dev_attr_file_nonremovable); - if (rc) - goto error_luns; - rc = device_create_file(curlun-dev, dev_attr_nofua); - if (rc) - goto error_luns; - - if (lcfg-filename) { - rc = fsg_lun_open(curlun, lcfg-filename); - if (rc) - goto error_luns; - } else if (!curlun-removable) { - ERROR(common, no file given for LUN%d\n, i); - rc = -EINVAL; - goto error_luns; - } - } + rc = fsg_common_create_luns(common, cfg); + if (rc) + goto error_release; /* Prepare inquiryString */ i = get_default_bcdDevice(); @@ -3106,7 +3039,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, : File-Stor Gadget), i); - /* Tell the thread to start working */ common-thread_task = kthread_create(fsg_main_thread, common, file-storage); @@ -3119,37 +3051,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, INFO(common, FSG_DRIVER_DESC , version: FSG_DRIVER_VERSION \n); INFO(common, Number of LUNs=%d\n, common-nluns); - pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); - for (i = 0, nluns = common-nluns, curlun_it = common-luns; -i nluns; -++curlun_it, ++i) { - struct fsg_lun *curlun = *curlun_it; - char *p = (no medium); - if (fsg_lun_is_open(curlun)) { -
[PATCH v3 17/19] usb/gadget: storage_common: make attribute operations more generic
Show/store methods for sysfs attributes contain code which can be used also by configfs. Make them abstract the source the lun and rw_semaphore are taken from. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 67 --- drivers/usb/gadget/storage_common.c | 36 -- drivers/usb/gadget/storage_common.h | 21 ++- 3 files changed, 81 insertions(+), 43 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 0a2b3ae..aaa8349 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2570,14 +2570,71 @@ static int fsg_main_thread(void *common_) /*** DEVICE ATTRIBUTES ***/ -static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro); -static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua); -static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file); +static ssize_t sysfs_fsg_show_ro(struct device *dev, +struct device_attribute *attr, +char *buf) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + + return fsg_show_ro(curlun, buf); +} + +static ssize_t sysfs_fsg_show_nofua(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + + return fsg_show_nofua(curlun, buf); +} + +static ssize_t sysfs_fsg_show_file(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + struct rw_semaphore *filesem = dev_get_drvdata(dev); + + return fsg_show_file(curlun, filesem, buf); +} + +static ssize_t sysfs_fsg_store_ro(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + struct rw_semaphore *filesem = dev_get_drvdata(dev); + + return fsg_store_ro(curlun, filesem, buf, count); +} + +static ssize_t sysfs_fsg_store_nofua(struct device *dev, +struct device_attribute *attr, +const char *buf, size_t count) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + + return fsg_store_nofua(curlun, buf, count); +} + +static ssize_t sysfs_fsg_store_file(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fsg_lun *curlun = fsg_lun_from_dev(dev); + struct rw_semaphore *filesem = dev_get_drvdata(dev); + + return fsg_store_file(curlun, filesem, buf, count); +} + +static DEVICE_ATTR(ro, 0644, sysfs_fsg_show_ro, sysfs_fsg_store_ro); +static DEVICE_ATTR(nofua, 0644, sysfs_fsg_show_nofua, sysfs_fsg_store_nofua); +static DEVICE_ATTR(file, 0644, sysfs_fsg_show_file, sysfs_fsg_store_file); static struct device_attribute dev_attr_ro_cdrom = - __ATTR(ro, 0444, fsg_show_ro, NULL); + __ATTR(ro, 0444, sysfs_fsg_show_ro, NULL); static struct device_attribute dev_attr_file_nonremovable = - __ATTR(file, 0444, fsg_show_file, NULL); + __ATTR(file, 0444, sysfs_fsg_show_file, NULL); /** FSG COMMON **/ diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 942324c..ab83d11 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -31,11 +31,6 @@ #include storage_common.h -static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev) -{ - return container_of(dev, struct fsg_lun, dev); -} - /* There is only one interface. */ struct usb_interface_descriptor fsg_intf_desc = { @@ -324,31 +319,23 @@ EXPORT_SYMBOL(store_cdrom_address); /*-*/ -ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr, - char *buf) +ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf) { - struct fsg_lun *curlun = fsg_lun_from_dev(dev); - return sprintf(buf, %d\n, fsg_lun_is_open(curlun) ? curlun-ro : curlun-initially_ro); } EXPORT_SYMBOL(fsg_show_ro); -ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr, - char *buf) +ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf) { - struct fsg_lun *curlun = fsg_lun_from_dev(dev); -
[PATCH v3 11/19] usb/gadget: f_mass_storage: use fsg_common_set_cdev in fsg_common_init
fsg_common_init is a lengthy function. Now there are helper functions which cover all parts of it. Use them. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 23 ++- 1 files changed, 2 insertions(+), 21 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 8aa6c86..9dde453 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -3002,7 +3002,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, struct usb_gadget *gadget = cdev-gadget; struct fsg_lun **curlun_it; struct fsg_lun_config *lcfg; - struct usb_string *us; int nluns, i, rc; char *pathbuf; @@ -3023,19 +3022,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, fsg_common_set_ops(common, cfg-ops); fsg_common_set_private_data(common, cfg-private_data); - common-gadget = gadget; - common-ep0 = gadget-ep0; - common-ep0req = cdev-req; - common-cdev = cdev; - - us = usb_gstrings_attach(cdev, fsg_strings_array, -ARRAY_SIZE(fsg_strings)); - if (IS_ERR(us)) { - rc = PTR_ERR(us); + rc = fsg_common_set_cdev(common, cdev, cfg-can_stall); + if (rc) goto error_release; - } - fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id; - rc = fsg_common_set_nluns(common, cfg-nluns); if (rc) @@ -3117,14 +3106,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, : File-Stor Gadget), i); - /* -* Some peripheral controllers are known not to be able to -* halt bulk endpoints correctly. If one of them is present, -* disable stalls. -*/ - common-can_stall = cfg-can_stall - !(gadget_is_at91(common-gadget)); - /* Tell the thread to start working */ common-thread_task = -- 1.7.0.4 -- 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/19] usb/gadget: f_mass_storage: use fsg_common_set_ops/_private_data in fsg_common_init
fsg_common_init is a lengthy function. Now there are helper functions which cover all parts of it. Use them. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 691fb51..8aa6c86 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -3019,8 +3019,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, kfree(common); return ERR_PTR(rc); } - common-ops = cfg-ops; - common-private_data = cfg-private_data; + + fsg_common_set_ops(common, cfg-ops); + fsg_common_set_private_data(common, cfg-private_data); common-gadget = gadget; common-ep0 = gadget-ep0; -- 1.7.0.4 -- 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 08/19] usb/gadget: f_mass_storage: use fsg_common_set_num_buffers in fsg_common_init
fsg_common_init is a lengthy function. Now there are helper functions which cover all parts of it. Use them. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 29 +++-- 1 files changed, 3 insertions(+), 26 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 2f6e3c3..2a71540 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -3000,17 +3000,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, struct fsg_config *cfg) { struct usb_gadget *gadget = cdev-gadget; - struct fsg_buffhd *bh; struct fsg_lun **curlun_it; struct fsg_lun_config *lcfg; struct usb_string *us; int nluns, i, rc; char *pathbuf; - rc = fsg_num_buffers_validate(cfg-fsg_num_buffers); - if (rc != 0) - return ERR_PTR(rc); - /* Find out how many LUNs there should be */ nluns = cfg-nluns; if (nluns 1 || nluns FSG_MAX_LUNS) { @@ -3024,15 +3019,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, common-sysfs = true; common-state = FSG_STATE_IDLE; - common-fsg_num_buffers = cfg-fsg_num_buffers; - common-buffhds = kcalloc(common-fsg_num_buffers, - sizeof *(common-buffhds), GFP_KERNEL); - if (!common-buffhds) { + rc = fsg_common_set_num_buffers(common, cfg-fsg_num_buffers); + if (rc) { if (common-free_storage_on_release) kfree(common); - return ERR_PTR(-ENOMEM); + return ERR_PTR(rc); } - common-ops = cfg-ops; common-private_data = cfg-private_data; @@ -3125,21 +3117,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, } common-nluns = nluns; - /* Data buffers cyclic list */ - bh = common-buffhds; - i = common-fsg_num_buffers; - goto buffhds_first_it; - do { - bh-next = bh + 1; - ++bh; -buffhds_first_it: - bh-buf = kmalloc(FSG_BUFLEN, GFP_KERNEL); - if (unlikely(!bh-buf)) { - rc = -ENOMEM; - goto error_release; - } - } while (--i); - bh-next = common-buffhds; /* Prepare inquiryString */ i = get_default_bcdDevice(); -- 1.7.0.4 -- 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 13/19] usb/gadget: f_mass_storage: use fsg_common_set_inquiry_string in fsg_common_init
fsg_common_init is a lengthy function. Now there are helper functions which cover all parts of it. Use them. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 13 +++-- 1 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 41a94a1..fcc6409 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2999,7 +2999,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, struct usb_composite_dev *cdev, struct fsg_config *cfg) { - int i, rc; + int rc; common = fsg_common_setup(common, !!common); if (IS_ERR(common)) @@ -3029,16 +3029,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, if (rc) goto error_release; - /* Prepare inquiryString */ - i = get_default_bcdDevice(); - snprintf(common-inquiry_string, sizeof common-inquiry_string, -%-8s%-16s%04x, cfg-vendor_name ?: Linux, -/* Assume product name dependent on the first LUN */ -cfg-product_name ?: ((*common-luns)-cdrom -? File-CD Gadget -: File-Stor Gadget), -i); + fsg_common_set_inquiry_string(common, cfg-vendor_name, + cfg-product_name); /* Tell the thread to start working */ common-thread_task = kthread_create(fsg_main_thread, common, file-storage); -- 1.7.0.4 -- 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/19] usb/gadget: f_mass_storage: split fsg_common initialization into a number of functions
When configfs is in place, the things related to intialization of struct fsg_common will be split over a number of places. This patch adds several functions which together cover the former intialization routine fsg_common_init. When configfs is in place, the luns will not be represented in sysfs, so there will be no struct device associated with a lun. To prepare for this some debug macros need to be adjusted. Two new fields are added to struct fsg_lun: name and name_pfx. The name is for storing a string which is presented to the user instead of the dev_name. The name_pfx, if non-NULL, is prepended to the name at printing time. The name_pfx is for a future lun.0, which will be a default group in mass_storage.name. By design at USB function configfs group's creation time its name is not known (but instead set a bit later in drivers/usb/gadget/configfs.c:function_make) and it is this name that serves the purpose of the said name prefix. So instead of copying a yet-unknown string a pointer to it is stored in struct fsg_lun. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 424 +-- drivers/usb/gadget/f_mass_storage.h | 33 +++ drivers/usb/gadget/storage_common.h | 20 ++- 3 files changed, 454 insertions(+), 23 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 04ee635..ef4733c 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -299,6 +299,7 @@ struct fsg_common { unsigned intshort_packet_received:1; unsigned intbad_lun_okay:1; unsigned intrunning:1; + unsigned intsysfs:1; int thread_wakeup_needed; struct completion thread_notifier; @@ -2607,6 +2608,393 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers) return -EINVAL; } +static struct fsg_common *fsg_common_setup(struct fsg_common *common, bool zero) +{ + if (!common) { + common = kzalloc(sizeof(*common), GFP_KERNEL); + if (!common) + return ERR_PTR(-ENOMEM); + common-free_storage_on_release = 1; + } else { + if (zero) + memset(common, 0, sizeof(*common)); + common-free_storage_on_release = 0; + } + init_rwsem(common-filesem); + spin_lock_init(common-lock); + kref_init(common-ref); + init_completion(common-thread_notifier); + init_waitqueue_head(common-fsg_wait); + common-state = FSG_STATE_TERMINATED; + + return common; +} + +void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs) +{ + common-sysfs = sysfs; +} + +static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n) +{ + if (buffhds) { + struct fsg_buffhd *bh = buffhds; + while (n--) { + kfree(bh-buf); + ++bh; + } + kfree(buffhds); + } +} + +int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n) +{ + struct fsg_buffhd *bh, *new_buffhds; + int i, rc; + + rc = fsg_num_buffers_validate(n); + if (rc != 0) + return rc; + + new_buffhds = kcalloc(n, sizeof *(new_buffhds), GFP_KERNEL); + if (!new_buffhds) + return -ENOMEM; + + /* Data buffers cyclic list */ + bh = new_buffhds; + i = n; + goto buffhds_first_it; + do { + bh-next = bh + 1; + ++bh; +buffhds_first_it: + bh-buf = kmalloc(FSG_BUFLEN, GFP_KERNEL); + if (unlikely(!bh-buf)) + goto error_release; + } while (--i); + bh-next = new_buffhds; + + _fsg_common_free_buffers(common-buffhds, common-fsg_num_buffers); + common-fsg_num_buffers = n; + common-buffhds = new_buffhds; + + return 0; + +error_release: + _fsg_common_free_buffers(new_buffhds, n - i); + + return -ENOMEM; +} + +void fsg_common_free_buffers(struct fsg_common *common) +{ + _fsg_common_free_buffers(common-buffhds, common-fsg_num_buffers); + common-buffhds = NULL; +} + +int fsg_common_set_nluns(struct fsg_common *common, int nluns) +{ + struct fsg_lun **curlun; + + /* Find out how many LUNs there should be */ + if (nluns 1 || nluns FSG_MAX_LUNS) { + pr_err(invalid number of LUNs: %u\n, nluns); + return -EINVAL; + } + + curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL); + if (unlikely(!curlun)) + return -ENOMEM; + + if (common-luns) + fsg_common_free_luns(common); + + common-luns = curlun; + common-nluns = nluns; + +
[PATCH v3 09/19] usb/gadget: f_mass_storage: use fsg_common_set_nluns in fsg_common_init
fsg_common_init is a lengthy function. Now there are helper functions which cover all parts of it. Use them. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 22 +- 1 files changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 2a71540..691fb51 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -3006,12 +3006,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, int nluns, i, rc; char *pathbuf; - /* Find out how many LUNs there should be */ - nluns = cfg-nluns; - if (nluns 1 || nluns FSG_MAX_LUNS) { - dev_err(gadget-dev, invalid number of LUNs: %u\n, nluns); - return ERR_PTR(-EINVAL); - } common = fsg_common_setup(common, !!common); if (IS_ERR(common)) @@ -3041,17 +3035,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, } fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id; - /* -* Create the LUNs, open their backing files, and register the -* LUN devices in sysfs. -*/ - curlun_it = kcalloc(nluns, sizeof(*curlun_it), GFP_KERNEL); - if (unlikely(!curlun_it)) { - rc = -ENOMEM; - goto error_release; - } - common-luns = curlun_it; + rc = fsg_common_set_nluns(common, cfg-nluns); + if (rc) + goto error_release; + curlun_it = common-luns; + nluns = cfg-nluns; for (i = 0, lcfg = cfg-luns; i nluns; ++i, ++curlun_it, ++lcfg) { struct fsg_lun *curlun; @@ -3115,7 +3104,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common, goto error_luns; } } - common-nluns = nluns; /* Prepare inquiryString */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/1] Equivalent of g_acm_ms.ko with configfs
Here I present the conversion of everything that is required to provide the equivalent of g_acm_ms.ko with configfs. In fact this series consists of just one patch; everything required to provide the equivalent of g_acm_ms.ko with configfs has been done in the series related to the g_mass_storage.ko. The current series just moves the g_acm_ms to the new function interface of f_mass_storage. v1..v2: - removed the cause of Felipe returning -ENOLOG - moved fsg_common_set_sysfs invocation after the lun number is set, so that the latter operation does not try freeing nonexistent sysfs entries A branch will be available here from 31st July: git://git.infradead.org/users/kmpark/linux-samsung usb-gadget-configfs BACKWARD COMPATIBILITY == Please note that the old g_acm_ms.ko is still available and works. USING THE NEW GADGET == Please refer to this post: http://www.spinics.net/lists/linux-usb/msg76388.html for general information from Sebastian on how to use configfs-based gadgets (*). The g_acm_ms.ko provides 2 functions: - acm (described in (*)) - mass storage (described in a series preceding the current one, I will reply to this post to send a link when spinics or gmane has indexed the series in question) The procedure of setting up such a gadget with configfs is given below with an example: $ modprobe libcomposite $ mount none cfg -t configfs $ mkdir cfg/usb_gadget/g1 $ cd cfg/usb_gadget/g1 $ echo 0x0106 idProduct $ echo 0x04e8 idVendor $ mkdir strings/0x409 $ echo my-serial-number strings/0x409/serialnumber $ echo my-manufacturer strings/0x409/manufacturer $ echo ACM/MS Gadget strings/0x409/product $ mkdir configs/c.1 $ echo 120 configs/c.1/MaxPower $ mkdir configs/c.1/strings/0x409 $ echo Conf 1 configs/c.1/strings/0x409/configuration $ mkdir functions/mass_storage.0 $ echo /root/lun0.img functions/mass_storage.0/lun.0/file $ mkdir functions/mass_storage.0/lun.1 $ echo /root/lun1.img functions/mass_storage.0/lun.1/file $ mkdir functions/acm.usb0 $ ln -s functions/mass_storage.0 configs/c.1 $ ln -s functions/acm.usb0 configs/c.1 $ echo s3c-hsotg UDC After unbinding the gadget with echo UDC the symbolic links in the configuration directory can be removed, the strings/* subdirectories in the configuration directory can be removed, the strings/* subdirectories at the gadget level can be removed and the configs/* subdirectories can be removed. The functions/* subdirectories can be removed. After that the gadget directory can be removed. After that the respective modules can be unloaded. TESTING THE FUNCTIONS acm) On the host: cat /dev/ttyACM0 On the device: cat /dev/ttyGS0 and then the other way round: cat /dev/ttyGS0 cat /dev/ttyACM0 mass storage) device: connect the gadget, enable it host: dmesg, see the USB drives appear (if system configured to automatically mount) Andrzej Pietrasiewicz (1): usb/gadget: acm_ms: convert to new interface of f_mass_storage drivers/usb/gadget/Kconfig |1 + drivers/usb/gadget/acm_ms.c | 113 --- 2 files changed, 75 insertions(+), 39 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/1] usb/gadget: acm_ms: convert to new interface of f_mass_storage
Convert the legacy acm_ms gadget to use the new function interface of f_mass_storage, so that later the compatibility layer in f_mass_storage can be removed. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/Kconfig |1 + drivers/usb/gadget/acm_ms.c | 113 --- 2 files changed, 75 insertions(+), 39 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 0f38701..27a51e1 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -1037,6 +1037,7 @@ config USB_G_ACM_MS select USB_U_SERIAL select USB_F_ACM select USB_U_MS + select USB_F_MASS_STORAGE help This driver provides two functions in one configuration: a mass storage, and a CDC ACM (serial port) link. diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 31aae8f..b405bc4 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -31,17 +31,7 @@ #define ACM_MS_VENDOR_NUM 0x1d6b /* Linux Foundation */ #define ACM_MS_PRODUCT_NUM 0x0106 /* Composite Gadget: ACM + MS*/ -/*-*/ - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a gcc --combine ... part1.c part2.c part3.c ... build would. - */ -#define USB_FMS_INCLUDED -#include f_mass_storage.c +#include f_mass_storage.h /*-*/ USB_GADGET_COMPOSITE_OPTIONS(); @@ -121,16 +111,19 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); -static struct fsg_common fsg_common; - /*-*/ static struct usb_function *f_acm; static struct usb_function_instance *f_acm_inst; + +static struct usb_function_instance *fi_msg; +static struct usb_function *f_msg; + /* * We _always_ have both ACM and mass storage functions. */ static int __init acm_ms_do_config(struct usb_configuration *c) { + struct fsg_opts *opts; int status; if (gadget_is_otg(c-cdev-gadget)) { @@ -138,31 +131,37 @@ static int __init acm_ms_do_config(struct usb_configuration *c) c-bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - f_acm_inst = usb_get_function_instance(acm); - if (IS_ERR(f_acm_inst)) - return PTR_ERR(f_acm_inst); + opts = container_of(fi_msg, struct fsg_opts, func_inst); f_acm = usb_get_function(f_acm_inst); - if (IS_ERR(f_acm)) { - status = PTR_ERR(f_acm); - goto err_func; + if (IS_ERR(f_acm)) + return PTR_ERR(f_acm); + + f_msg = usb_get_function(fi_msg); + if (IS_ERR(f_msg)) { + status = PTR_ERR(f_msg); + goto put_acm; } status = usb_add_function(c, f_acm); if (status 0) - goto err_conf; + goto put_msg; - status = fsg_bind_config(c-cdev, c, fsg_common); - if (status 0) - goto err_fsg; + status = fsg_common_run_thread(opts-common); + if (status) + goto remove_acm; + + status = usb_add_function(c, f_msg); + if (status) + goto remove_acm; return 0; -err_fsg: +remove_acm: usb_remove_function(c, f_acm); -err_conf: +put_msg: + usb_put_function(f_msg); +put_acm: usb_put_function(f_acm); -err_func: - usb_put_function_instance(f_acm_inst); return status; } @@ -178,46 +177,82 @@ static struct usb_configuration acm_ms_config_driver = { static int __init acm_ms_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev-gadget; + struct fsg_opts *opts; + struct fsg_config config; int status; - void*retp; - /* set up mass storage function */ - retp = fsg_common_from_params(fsg_common, cdev, fsg_mod_data, - fsg_num_buffers); - if (IS_ERR(retp)) { - status = PTR_ERR(retp); - return PTR_ERR(retp); + f_acm_inst = usb_get_function_instance(acm); + if (IS_ERR(f_acm_inst)) + return PTR_ERR(f_acm_inst); + + fi_msg = usb_get_function_instance(mass_storage); + if (IS_ERR(fi_msg)) { + status = PTR_ERR(fi_msg); + goto fail_get_msg; } + /* set up mass storage function */ +
[PATCH v2 2/5] usb/gadget: multi: convert to new interface of f_rndis
Convert the legacy multi gadget to the new interface of f_rndis, so that later the compatibility layer in f_rndis can be removed. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/Kconfig |3 +- drivers/usb/gadget/multi.c | 73 ++-- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 98284d5..f6f896e 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -1052,7 +1052,6 @@ config USB_G_MULTI select USB_LIBCOMPOSITE select USB_U_SERIAL select USB_U_ETHER - select USB_U_RNDIS select USB_F_ACM select USB_U_MS help @@ -1073,6 +1072,8 @@ config USB_G_MULTI config USB_G_MULTI_RNDIS bool RNDIS + CDC Serial + Storage configuration depends on USB_G_MULTI + select USB_U_RNDIS + select USB_F_RNDIS default y help This option enables a configuration with RNDIS, CDC Serial and diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 0d1d132..be62bea 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -47,8 +47,7 @@ MODULE_LICENSE(GPL); #include u_ecm.h #ifdef USB_ETH_RNDIS -# define USB_FRNDIS_INCLUDED -# include f_rndis.c +# include u_rndis.h # include rndis.h #endif #include u_ether.h @@ -152,14 +151,13 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); static struct fsg_common fsg_common; static struct usb_function_instance *fi_acm; -static struct eth_dev *the_dev; /** RNDIS **/ #ifdef USB_ETH_RNDIS -static u8 host_mac[ETH_ALEN]; - +static struct usb_function_instance *fi_rndis; static struct usb_function *f_acm_rndis; +static struct usb_function *f_rndis; static __init int rndis_do_config(struct usb_configuration *c) { @@ -170,13 +168,19 @@ static __init int rndis_do_config(struct usb_configuration *c) c-bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - ret = rndis_bind_config(c, host_mac, the_dev); + f_rndis = usb_get_function(fi_rndis); + if (IS_ERR(f_rndis)) + return PTR_ERR(f_rndis); + + ret = usb_add_function(c, f_rndis); if (ret 0) - return ret; + goto err_func_rndis; f_acm_rndis = usb_get_function(fi_acm); - if (IS_ERR(f_acm_rndis)) - return PTR_ERR(f_acm_rndis); + if (IS_ERR(f_acm_rndis)) { + ret = PTR_ERR(f_acm_rndis); + goto err_func_acm; + } ret = usb_add_function(c, f_acm_rndis); if (ret) @@ -191,6 +195,10 @@ err_fsg: usb_remove_function(c, f_acm_rndis); err_conf: usb_put_function(f_acm_rndis); +err_func_acm: + usb_remove_function(c, f_rndis); +err_func_rndis: + usb_put_function(f_rndis); return ret; } @@ -300,11 +308,14 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) #ifdef CONFIG_USB_G_MULTI_CDC struct f_ecm_opts *ecm_opts; #endif +#ifdef USB_ETH_RNDIS + struct f_rndis_opts *rndis_opts; +#endif int status; if (!can_support_ecm(cdev-gadget)) { dev_err(gadget-dev, controller '%s' not usable\n, - gadget-name); + gadget-name); return -EINVAL; } @@ -320,26 +331,38 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) pr_info(using host ethernet address: %s, host_addr); if (!gether_set_dev_addr(ecm_opts-net, dev_addr)) pr_info(using self ethernet address: %s, dev_addr); +#endif - the_dev = netdev_priv(ecm_opts-net); +#ifdef USB_ETH_RNDIS + fi_rndis = usb_get_function_instance(rndis); + if (IS_ERR(fi_rndis)) { + status = PTR_ERR(fi_rndis); + goto fail; + } -#elif defined USB_ETH_RNDIS + rndis_opts = container_of(fi_rndis, struct f_rndis_opts, func_inst); - /* set up network link layer */ - the_dev = gether_setup(cdev-gadget, dev_addr, host_addr, host_mac, - qmult); - if (IS_ERR(the_dev)) - return PTR_ERR(the_dev); + gether_set_qmult(rndis_opts-net, qmult); + if (!gether_set_host_addr(rndis_opts-net, host_addr)) + pr_info(using host ethernet address: %s, host_addr); + if (!gether_set_dev_addr(rndis_opts-net, dev_addr)) + pr_info(using self ethernet address: %s, dev_addr); #endif #if (defined CONFIG_USB_G_MULTI_CDC defined USB_ETH_RNDIS) + /* +* If both ecm and rndis are selected then: +* 1) rndis borrows the net interface from ecm +* 2) since the interface is shared it must not be bound +* twice - in ecm's _and_ rndis' binds, so do it here. +*/
[PATCH v2 4/5] usb/gadget: f_mass_storage: remove compatibility layer
There are no more old interface users left. Remove it. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/f_mass_storage.c | 154 +-- drivers/usb/gadget/f_mass_storage.h | 21 - 2 files changed, 1 insertions(+), 174 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index f1aa6c0..3e9a03b 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2651,17 +2651,13 @@ void fsg_common_get(struct fsg_common *common) { kref_get(common-ref); } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_get); -#endif void fsg_common_put(struct fsg_common *common) { kref_put(common-ref, fsg_common_release); } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_put); -#endif /* check if fsg_num_buffers is within a valid range */ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers) @@ -2699,9 +2695,7 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs) { common-sysfs = sysfs; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_set_sysfs); -#endif static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n) { @@ -2753,18 +2747,14 @@ error_release: return -ENOMEM; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_set_num_buffers); -#endif void fsg_common_free_buffers(struct fsg_common *common) { _fsg_common_free_buffers(common-buffhds, common-fsg_num_buffers); common-buffhds = NULL; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_free_buffers); -#endif int fsg_common_set_nluns(struct fsg_common *common, int nluns) { @@ -2790,9 +2780,7 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns) return 0; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_set_nluns); -#endif void fsg_common_free_luns(struct fsg_common *common) { @@ -2800,26 +2788,20 @@ void fsg_common_free_luns(struct fsg_common *common) kfree(common-luns); common-luns = NULL; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_free_luns); -#endif void fsg_common_set_ops(struct fsg_common *common, const struct fsg_operations *ops) { common-ops = ops; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_set_ops); -#endif void fsg_common_set_private_data(struct fsg_common *common, void *priv) { common-private_data = priv; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_set_private_data); -#endif int fsg_common_set_cdev(struct fsg_common *common, struct usb_composite_dev *cdev, bool can_stall) @@ -2849,9 +2831,7 @@ int fsg_common_set_cdev(struct fsg_common *common, return 0; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_set_cdev); -#endif static inline int fsg_common_add_sysfs(struct fsg_common *common, struct fsg_lun *lun) @@ -2916,9 +2896,7 @@ void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs) kfree(lun-name); kfree(lun); } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_remove_lun); -#endif void _fsg_common_remove_luns(struct fsg_common *common, int n) { @@ -2935,9 +2913,7 @@ void fsg_common_remove_luns(struct fsg_common *common) { _fsg_common_remove_luns(common, common-nluns); } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_remove_luns); -#endif #define MAX_LUN_NAME_LEN 80 @@ -3034,9 +3010,7 @@ error_name: kfree(lun); return rc; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_create_lun); -#endif int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg) { @@ -3058,9 +3032,7 @@ fail: _fsg_common_remove_luns(common, i); return rc; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_create_luns); -#endif void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn, const char *pn) @@ -3077,9 +3049,7 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn, : File-Stor Gadget), i); } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_set_inquiry_string); -#endif int fsg_common_run_thread(struct fsg_common *common) { @@ -3098,66 +3068,7 @@ int fsg_common_run_thread(struct fsg_common *common) return 0; } -#ifndef USB_FMS_INCLUDED EXPORT_SYMBOL(fsg_common_run_thread); -#endif - -struct fsg_common *fsg_common_init(struct fsg_common *common, - struct usb_composite_dev *cdev, - struct fsg_config *cfg) -{ - int rc; - - common = fsg_common_setup(common, !!common); - if (IS_ERR(common)) - return common; - common-sysfs = true; - common-state = FSG_STATE_IDLE; - - rc =
[PATCH v2 1/5] usb/gadget: multi: convert to new interface of f_ecm
Convert the legacy multi gadget to the new interface of f_ecm, so that later the compatibility layer in f_ecm can be removed. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/Kconfig |1 + drivers/usb/gadget/multi.c | 68 ++- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 27a51e1..98284d5 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -1086,6 +1086,7 @@ config USB_G_MULTI_CDC bool CDC Ethernet + CDC Serial + Storage configuration depends on USB_G_MULTI default n + select USB_F_ECM help This option enables a configuration with CDC Ethernet (ECM), CDC Serial and Mass Storage functions available in the Multifunction diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index c232f76..0d1d132 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -15,6 +15,7 @@ #include linux/kernel.h #include linux/module.h +#include linux/netdevice.h #include u_serial.h #if defined USB_ETH_RNDIS @@ -44,8 +45,7 @@ MODULE_LICENSE(GPL); #define USB_FMS_INCLUDED #include f_mass_storage.c -#define USBF_ECM_INCLUDED -#include f_ecm.c +#include u_ecm.h #ifdef USB_ETH_RNDIS # define USB_FRNDIS_INCLUDED # include f_rndis.c @@ -151,14 +151,14 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); static struct fsg_common fsg_common; -static u8 host_mac[ETH_ALEN]; - static struct usb_function_instance *fi_acm; static struct eth_dev *the_dev; /** RNDIS **/ #ifdef USB_ETH_RNDIS +static u8 host_mac[ETH_ALEN]; + static struct usb_function *f_acm_rndis; static __init int rndis_do_config(struct usb_configuration *c) @@ -220,7 +220,9 @@ static int rndis_config_register(struct usb_composite_dev *cdev) /** CDC ECM **/ #ifdef CONFIG_USB_G_MULTI_CDC +static struct usb_function_instance *fi_ecm; static struct usb_function *f_acm_multi; +static struct usb_function *f_ecm; static __init int cdc_do_config(struct usb_configuration *c) { @@ -231,14 +233,20 @@ static __init int cdc_do_config(struct usb_configuration *c) c-bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - ret = ecm_bind_config(c, host_mac, the_dev); + f_ecm = usb_get_function(fi_ecm); + if (IS_ERR(f_ecm)) + return PTR_ERR(f_ecm); + + ret = usb_add_function(c, f_ecm); if (ret 0) - return ret; + goto err_func_ecm; /* implicit port_num is zero */ f_acm_multi = usb_get_function(fi_acm); - if (IS_ERR(f_acm_multi)) - return PTR_ERR(f_acm_multi); + if (IS_ERR(f_acm_multi)) { + ret = PTR_ERR(f_acm_multi); + goto err_func_acm; + } ret = usb_add_function(c, f_acm_multi); if (ret) @@ -253,6 +261,10 @@ err_fsg: usb_remove_function(c, f_acm_multi); err_conf: usb_put_function(f_acm_multi); +err_func_acm: + usb_remove_function(c, f_ecm); +err_func_ecm: + usb_put_function(f_ecm); return ret; } @@ -285,6 +297,9 @@ static int cdc_config_register(struct usb_composite_dev *cdev) static int __ref multi_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev-gadget; +#ifdef CONFIG_USB_G_MULTI_CDC + struct f_ecm_opts *ecm_opts; +#endif int status; if (!can_support_ecm(cdev-gadget)) { @@ -293,11 +308,39 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) return -EINVAL; } +#ifdef CONFIG_USB_G_MULTI_CDC + fi_ecm = usb_get_function_instance(ecm); + if (IS_ERR(fi_ecm)) + return PTR_ERR(fi_ecm); + + ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst); + + gether_set_qmult(ecm_opts-net, qmult); + if (!gether_set_host_addr(ecm_opts-net, host_addr)) + pr_info(using host ethernet address: %s, host_addr); + if (!gether_set_dev_addr(ecm_opts-net, dev_addr)) + pr_info(using self ethernet address: %s, dev_addr); + + the_dev = netdev_priv(ecm_opts-net); + +#elif defined USB_ETH_RNDIS + /* set up network link layer */ the_dev = gether_setup(cdev-gadget, dev_addr, host_addr, host_mac, qmult); if (IS_ERR(the_dev)) return PTR_ERR(the_dev); +#endif + +#if (defined CONFIG_USB_G_MULTI_CDC defined USB_ETH_RNDIS) + gether_set_gadget(ecm_opts-net, cdev-gadget); + status = gether_register_netdev(ecm_opts-net); + if (status) + goto fail0; + ecm_opts-bound = true; + + gether_get_host_addr_u8(ecm_opts-net, host_mac); +#endif /* set up serial link layer */ fi_acm =
[PATCH v2 3/5] usb/gadget: multi: convert to new interface of f_mass_storage
Convert the legacy multi gadget to the new interface of f_mass_storage, so that later the compatibility layer in f_mass_storage can be removed. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/Kconfig |1 + drivers/usb/gadget/multi.c | 112 2 files changed, 83 insertions(+), 30 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index f6f896e..743425b 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -1054,6 +1054,7 @@ config USB_G_MULTI select USB_U_ETHER select USB_F_ACM select USB_U_MS + select USB_F_MASS_STORAGE help The Multifunction Composite Gadget provides Ethernet (RNDIS and/or CDC Ethernet), mass storage and ACM serial link diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index be62bea..7f84efa 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -33,17 +33,7 @@ MODULE_AUTHOR(Michal Nazarewicz); MODULE_LICENSE(GPL); -/* All the files... */ - -/* - * kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a gcc --combine ... part1.c part2.c part3.c ... build would. - */ -#define USB_FMS_INCLUDED -#include f_mass_storage.c +#include f_mass_storage.h #include u_ecm.h #ifdef USB_ETH_RNDIS @@ -148,9 +138,8 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); -static struct fsg_common fsg_common; - static struct usb_function_instance *fi_acm; +static struct usb_function_instance *fi_msg; /** RNDIS **/ @@ -158,9 +147,11 @@ static struct usb_function_instance *fi_acm; static struct usb_function_instance *fi_rndis; static struct usb_function *f_acm_rndis; static struct usb_function *f_rndis; +static struct usb_function *f_msg_rndis; static __init int rndis_do_config(struct usb_configuration *c) { + struct fsg_opts *fsg_opts; int ret; if (gadget_is_otg(c-cdev-gadget)) { @@ -186,11 +177,24 @@ static __init int rndis_do_config(struct usb_configuration *c) if (ret) goto err_conf; - ret = fsg_bind_config(c-cdev, c, fsg_common); - if (ret 0) + f_msg_rndis = usb_get_function(fi_msg); + if (IS_ERR(f_msg_rndis)) { + ret = PTR_ERR(f_msg_rndis); goto err_fsg; + } + + fsg_opts = container_of(fi_msg, struct fsg_opts, func_inst); + ret = fsg_common_run_thread(fsg_opts-common); + if (ret) + goto err_run; + + ret = usb_add_function(c, f_msg_rndis); + if (ret) + goto err_run; return 0; +err_run: + usb_put_function(f_msg_rndis); err_fsg: usb_remove_function(c, f_acm_rndis); err_conf: @@ -231,9 +235,11 @@ static int rndis_config_register(struct usb_composite_dev *cdev) static struct usb_function_instance *fi_ecm; static struct usb_function *f_acm_multi; static struct usb_function *f_ecm; +static struct usb_function *f_msg_multi; static __init int cdc_do_config(struct usb_configuration *c) { + struct fsg_opts *fsg_opts; int ret; if (gadget_is_otg(c-cdev-gadget)) { @@ -260,11 +266,24 @@ static __init int cdc_do_config(struct usb_configuration *c) if (ret) goto err_conf; - ret = fsg_bind_config(c-cdev, c, fsg_common); - if (ret 0) + f_msg_multi = usb_get_function(fi_msg); + if (IS_ERR(f_msg_multi)) { + ret = PTR_ERR(f_msg_multi); goto err_fsg; + } + + fsg_opts = container_of(fi_msg, struct fsg_opts, func_inst); + ret = fsg_common_run_thread(fsg_opts-common); + if (ret) + goto err_run; + + ret = usb_add_function(c, f_msg_multi); + if (ret) + goto err_run; return 0; +err_run: + usb_put_function(f_msg_multi); err_fsg: usb_remove_function(c, f_acm_multi); err_conf: @@ -311,6 +330,8 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) #ifdef USB_ETH_RNDIS struct f_rndis_opts *rndis_opts; #endif + struct fsg_opts *fsg_opts; + struct fsg_config config; int status; if (!can_support_ecm(cdev-gadget)) { @@ -373,41 +394,65 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) } /* set up mass storage function */ - { - void *retp; - retp = fsg_common_from_params(fsg_common, cdev, fsg_mod_data, -
[PATCH v2 0/5] Equivalent of g_multi.ko with configfs
Here I present the conversion of everything that is required to provide the equivalent of g_multi.ko with configfs. v1..v2: - removed the cause of Felipe returning -ENOLOG - moved fsg_common_set_sysfs invocation after the lun number is set, so that the latter operation does not try freeing nonexistent sysfs entries - adapted to earlier changes in multi.c (*_do_config) A branch will be available here since 31st July: git://git.infradead.org/users/kmpark/linux-samsung usb-gadget-configfs BACKWARD COMPATIBILITY == Please note that the old g_multi.ko is still available and works. USING THE NEW GADGET == Please refer to this post: http://www.spinics.net/lists/linux-usb/msg76388.html for general information from Sebastian on how to use configfs-based gadgets (*). The g_multi.ko provides 4 functions: - acm (described in (*)) - ecm (http://www.spinics.net/lists/linux-usb/msg86561.html) - rndis (http://www.spinics.net/lists/linux-usb/msg86561.html) - mass storage (described in a series preceding the current one, I will reply to this post to send a link when spinics or gmane has indexed the series in question) and using all of them with configfs has already been described. The procedure of setting up a new multi gadget with configfs is given below with an example: $ modprobe libcomposite $ mount none cfg -t configfs $ mkdir cfg/usb_gadget/g1 $ cd cfg/usb_gadget/g1 $ echo 0x0106 idProduct $ echo 0x04e8 idVendor $ mkdir strings/0x409 $ echo my-serial-num strings/0x409/serialnumber $ echo my-manufacturer strings/0x409/manufacturer $ echo Multi Gadget strings/0x409/product $ mkdir configs/c.1 $ echo 120 configs/c.1/MaxPower $ mkdir configs/c.1/strings/0x409 $ echo Conf 1 configs/c.1/strings/0x409/configuration $ mkdir configs/c.2 $ echo 120 configs/c.2/MaxPower $ mkdir configs/c.2/strings/0x409 $ echo Conf 2 configs/c.2/strings/0x409/configuration $ mkdir functions/mass_storage.0 $ echo /root/lun0.img functions/mass_storage.0/lun.0/file $ mkdir functions/mass_storage.0/lun.1 $ echo /root/lun1.img functions/mass_storage.0/lun.1/file $ mkdir functions/acm.0 $ mkdir functions/ecm.0 $ mkdir functions/rndis.0 $ ln -s functions/rndis.0 configs/c.1 $ ln -s functions/acm.0 configs/c.1 $ ln -s functions/mass_storage.0 configs/c.1 $ ln -s functions/ecm.0 configs/c.2 $ ln -s functions/acm.0 configs/c.2 $ ln -s functions/mass_storage.0 configs/c.2 After unbinding the gadget with echo UDC the symbolic links in the configuration directory can be removed, the strings/* subdirectories in the configuration directory can be removed, the strings/* subdirectories at the gadget level can be removed and the configs/* subdirectories can be removed. The functions/* subdirectories can be removed. After that the gadget directory can be removed. After that the respective modules can be unloaded. TESTING THE FUNCTIONS acm) On the host: cat /dev/ttyACM0 On the device: cat /dev/ttyGS0 and then the other way round: cat /dev/ttyGS0 cat /dev/ttyACM0 mass storage) device: connect the gadget, enable it host: dmesg, see the USB drives appear (if system configured to automatically mount) ecm, rndis) On the device: ping host's IP On the host: ping device's IP Andrzej Pietrasiewicz (5): usb/gadget: multi: convert to new interface of f_ecm usb/gadget: multi: convert to new interface of f_rndis usb/gadget: multi: convert to new interface of f_mass_storage usb/gadget: f_mass_storage: remove compatibility layer usb/gadget: mass_storage: merge usb_f_mass_storage module with u_ms module drivers/usb/gadget/Kconfig | 12 +-- drivers/usb/gadget/Makefile |4 +- drivers/usb/gadget/f_mass_storage.c | 154 +-- drivers/usb/gadget/f_mass_storage.h | 21 --- drivers/usb/gadget/multi.c | 237 +++ 5 files changed, 190 insertions(+), 238 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/5] usb/gadget: mass_storage: merge usb_f_mass_storage module with u_ms module
u_ms.ko is needed only together with usb_f_mass_storage.ko. Merge them. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/usb/gadget/Kconfig |7 --- drivers/usb/gadget/Makefile |4 +--- 2 files changed, 1 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 743425b..9932f25 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -541,9 +541,6 @@ config USB_F_SUBSET config USB_F_RNDIS tristate -config USB_U_MS - tristate - config USB_F_MASS_STORAGE tristate @@ -687,7 +684,6 @@ config USB_CONFIGFS_PHONET config USB_CONFIGFS_MASS_STORAGE boolean Mass storage depends on USB_CONFIGFS - select USB_U_MS select USB_F_MASS_STORAGE help The Mass Storage Gadget acts as a USB Mass Storage disk drive. @@ -911,7 +907,6 @@ config USB_MASS_STORAGE tristate Mass Storage Gadget depends on BLOCK select USB_LIBCOMPOSITE - select USB_U_MS select USB_F_MASS_STORAGE help The Mass Storage Gadget acts as a USB Mass Storage disk drive. @@ -1036,7 +1031,6 @@ config USB_G_ACM_MS select USB_LIBCOMPOSITE select USB_U_SERIAL select USB_F_ACM - select USB_U_MS select USB_F_MASS_STORAGE help This driver provides two functions in one configuration: @@ -1053,7 +1047,6 @@ config USB_G_MULTI select USB_U_SERIAL select USB_U_ETHER select USB_F_ACM - select USB_U_MS select USB_F_MASS_STORAGE help The Multifunction Composite Gadget provides Ethernet (RNDIS diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index dccab69..e70e9f1 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -61,9 +61,7 @@ usb_f_ecm_subset-y:= f_subset.o obj-$(CONFIG_USB_F_SUBSET) += usb_f_ecm_subset.o usb_f_rndis-y := f_rndis.o obj-$(CONFIG_USB_F_RNDIS) += usb_f_rndis.o -u_ms-y := storage_common.o -obj-$(CONFIG_USB_U_MS) += u_ms.o -usb_f_mass_storage-y := f_mass_storage.o +usb_f_mass_storage-y := f_mass_storage.o storage_common.o obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o # -- 1.7.0.4 -- 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/2] usb: chipidea: move vbus regulator operation to core
Hi Peter, On Wed, Jul 31, 2013 at 09:39:50AM +0800, Peter Chen wrote: On Tue, Jul 30, 2013 at 02:41:23PM +0200, Michael Grzeschik wrote: From: Michael Grzeschik m...@pengutronix.de This patch moves the regulator code from ci_hdrc_imx gluecode to the core layer. It also checks the errorpathes in case the platformglue didn't prepare an regulator for this driver. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/usb/chipidea/ci_hdrc_imx.c | 26 ++ drivers/usb/chipidea/core.c| 16 include/linux/usb/chipidea.h | 1 + 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 06bc775..d2937e1 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -19,7 +19,6 @@ #include linux/dma-mapping.h #include linux/usb/chipidea.h #include linux/clk.h -#include linux/regulator/consumer.h #include ci.h #include ci_hdrc_imx.h @@ -31,7 +30,6 @@ struct ci_hdrc_imx_data { struct usb_phy *phy; struct platform_device *ci_pdev; struct clk *clk; - struct regulator *reg_vbus; }; static const struct usbmisc_ops *usbmisc_ops; @@ -134,20 +132,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) goto err_clk; } - /* we only support host now, so enable vbus here */ - data-reg_vbus = devm_regulator_get(pdev-dev, vbus); - if (!IS_ERR(data-reg_vbus)) { - ret = regulator_enable(data-reg_vbus); - if (ret) { - dev_err(pdev-dev, - Failed to enable vbus regulator, err=%d\n, - ret); - goto err_clk; - } - } else { - data-reg_vbus = NULL; - } - pdata.phy = data-phy; if (!pdev-dev.dma_mask) @@ -160,7 +144,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) if (ret) { dev_err(pdev-dev, usbmisc init failed, ret=%d\n, ret); - goto err; + goto err_clk; } } @@ -172,7 +156,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) dev_err(pdev-dev, Can't register ci_hdrc platform device, err=%d\n, ret); - goto err; + goto err_clk; } if (usbmisc_ops usbmisc_ops-post) { @@ -193,9 +177,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) disable_device: ci_hdrc_remove_device(data-ci_pdev); -err: - if (data-reg_vbus) - regulator_disable(data-reg_vbus); err_clk: clk_disable_unprepare(data-clk); return ret; @@ -208,9 +189,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) pm_runtime_disable(pdev-dev); ci_hdrc_remove_device(data-ci_pdev); - if (data-reg_vbus) - regulator_disable(data-reg_vbus); - if (data-phy) { usb_phy_shutdown(data-phy); module_put(data-phy-dev-driver-owner); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index a5df24c..178b61d 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -57,6 +57,7 @@ #include linux/interrupt.h #include linux/io.h #include linux/kernel.h +#include linux/regulator/consumer.h #include linux/slab.h #include linux/pm_runtime.h #include linux/usb/ch9.h @@ -363,6 +364,21 @@ struct platform_device *ci_hdrc_add_device(struct device *dev, goto put_id; } + /* Get the vbus regulator */ + platdata-reg_vbus = devm_regulator_get(dev, vbus); + if (PTR_ERR(platdata-reg_vbus) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err; + } else if (PTR_ERR(platdata-reg_vbus) == -ENODEV) { + platdata-reg_vbus = NULL; /* no vbus regualator is needed */ + } else if (IS_ERR(platdata-reg_vbus)) { + dev_err(pdev-dev, + Getting regulator error: %ld\n, + PTR_ERR(platdata-reg_vbus)); + ret = PTR_ERR(platdata-reg_vbus); + goto err; + } + pdev-dev.parent = dev; Michael, thanks to do this for me. One small suggestion is: it is better add one function like: ci_get_platdata, and move the vbus stuff to that function. This function is used to get common thing from glue layer. And it is better at the beginning of ci_hdrc_add_device, since the other code at ci_hdrc_add_device are all related to core device. I can help to do refine this patch (with some typo which Felipe mentioned) if you consider it is necessary. I know you may be busy with other things. Feel free
Re: [PATCH 1/2] usb: chipidea: move vbus regulator operation to core
On Wed, Jul 31, 2013 at 09:23:56AM +0200, Michael Grzeschik wrote: Hi Peter, On Wed, Jul 31, 2013 at 09:39:50AM +0800, Peter Chen wrote: On Tue, Jul 30, 2013 at 02:41:23PM +0200, Michael Grzeschik wrote: From: Michael Grzeschik m...@pengutronix.de This patch moves the regulator code from ci_hdrc_imx gluecode to the core layer. It also checks the errorpathes in case the platformglue didn't prepare an regulator for this driver. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/usb/chipidea/ci_hdrc_imx.c | 26 ++ drivers/usb/chipidea/core.c| 16 include/linux/usb/chipidea.h | 1 + 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 06bc775..d2937e1 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -19,7 +19,6 @@ #include linux/dma-mapping.h #include linux/usb/chipidea.h #include linux/clk.h -#include linux/regulator/consumer.h #include ci.h #include ci_hdrc_imx.h @@ -31,7 +30,6 @@ struct ci_hdrc_imx_data { struct usb_phy *phy; struct platform_device *ci_pdev; struct clk *clk; - struct regulator *reg_vbus; }; static const struct usbmisc_ops *usbmisc_ops; @@ -134,20 +132,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) goto err_clk; } - /* we only support host now, so enable vbus here */ - data-reg_vbus = devm_regulator_get(pdev-dev, vbus); - if (!IS_ERR(data-reg_vbus)) { - ret = regulator_enable(data-reg_vbus); - if (ret) { - dev_err(pdev-dev, - Failed to enable vbus regulator, err=%d\n, - ret); - goto err_clk; - } - } else { - data-reg_vbus = NULL; - } - pdata.phy = data-phy; if (!pdev-dev.dma_mask) @@ -160,7 +144,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) if (ret) { dev_err(pdev-dev, usbmisc init failed, ret=%d\n, ret); - goto err; + goto err_clk; } } @@ -172,7 +156,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) dev_err(pdev-dev, Can't register ci_hdrc platform device, err=%d\n, ret); - goto err; + goto err_clk; } if (usbmisc_ops usbmisc_ops-post) { @@ -193,9 +177,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) disable_device: ci_hdrc_remove_device(data-ci_pdev); -err: - if (data-reg_vbus) - regulator_disable(data-reg_vbus); err_clk: clk_disable_unprepare(data-clk); return ret; @@ -208,9 +189,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) pm_runtime_disable(pdev-dev); ci_hdrc_remove_device(data-ci_pdev); - if (data-reg_vbus) - regulator_disable(data-reg_vbus); - if (data-phy) { usb_phy_shutdown(data-phy); module_put(data-phy-dev-driver-owner); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index a5df24c..178b61d 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -57,6 +57,7 @@ #include linux/interrupt.h #include linux/io.h #include linux/kernel.h +#include linux/regulator/consumer.h #include linux/slab.h #include linux/pm_runtime.h #include linux/usb/ch9.h @@ -363,6 +364,21 @@ struct platform_device *ci_hdrc_add_device(struct device *dev, goto put_id; } + /* Get the vbus regulator */ + platdata-reg_vbus = devm_regulator_get(dev, vbus); + if (PTR_ERR(platdata-reg_vbus) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err; + } else if (PTR_ERR(platdata-reg_vbus) == -ENODEV) { + platdata-reg_vbus = NULL; /* no vbus regualator is needed */ + } else if (IS_ERR(platdata-reg_vbus)) { + dev_err(pdev-dev, + Getting regulator error: %ld\n, + PTR_ERR(platdata-reg_vbus)); + ret = PTR_ERR(platdata-reg_vbus); + goto err; + } + pdev-dev.parent = dev; Michael, thanks to do this for me. One small suggestion is: it is better add one function like: ci_get_platdata, and move the vbus stuff to that function. This function is used to get common thing from glue layer. And it is better at the beginning of ci_hdrc_add_device, since the other code at ci_hdrc_add_device are all related to core device. I can help to do refine this patch (with some typo which Felipe mentioned)
Re: [PATCH 2/2] chipidea: Use devm_request_irq()
On Tue, Jul 30, 2013 at 10:04:29PM -0300, Fabio Estevam wrote: From: Fabio Estevam fabio.este...@freescale.com By using devm_request_irq() we don't need to call free_irq(), which simplifies the code a bit. Signed-off-by: Fabio Estevam fabio.este...@freescale.com --- drivers/usb/chipidea/core.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 5cc1b02..d185c41 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -502,8 +502,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, ci); - ret = request_irq(ci-irq, ci_irq, IRQF_SHARED, ci-platdata-name, - ci); + ret = devm_request_irq(dev, ci-irq, ci_irq, IRQF_SHARED, +ci-platdata-name, ci); Mark Brown (now on Cc:) replied to one of my patches using devm_request_irq: I'm always deeply suspicous of devm_request_irq() since you need to be *very* sure that the interrupt can't fire during cleanup and cause the handlers to try to use data structures that are already being freed. and: devm_request_threaded_irq() is just generally a bit of a warning sign since it needs careful checking to tell if it's safe. I don't know the details and didn't find any problems with it that a plain request_irq doesn't have. But I wonder about the details and if others are aware of the possible problems. Mark, maybe you can describe in more detail the downsides you see? Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | http://www.pengutronix.de/ | -- 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/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 09:33:06AM +0200, Uwe Kleine-König wrote: On Tue, Jul 30, 2013 at 10:04:29PM -0300, Fabio Estevam wrote: From: Fabio Estevam fabio.este...@freescale.com By using devm_request_irq() we don't need to call free_irq(), which simplifies the code a bit. Signed-off-by: Fabio Estevam fabio.este...@freescale.com --- drivers/usb/chipidea/core.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 5cc1b02..d185c41 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -502,8 +502,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, ci); - ret = request_irq(ci-irq, ci_irq, IRQF_SHARED, ci-platdata-name, - ci); + ret = devm_request_irq(dev, ci-irq, ci_irq, IRQF_SHARED, + ci-platdata-name, ci); Mark Brown (now on Cc:) replied to one of my patches using devm_request_irq: I'm always deeply suspicous of devm_request_irq() since you need to be *very* sure that the interrupt can't fire during cleanup and cause the handlers to try to use data structures that are already being freed. and: devm_request_threaded_irq() is just generally a bit of a warning sign since it needs careful checking to tell if it's safe. The probably problem I find is the free_irq will be called after driver's removal is called, then the problem Mark described will occur. See __device_release_driver(struct device *dev) at drivers/base/dd.c. -- Best Regards, Peter Chen -- 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/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 04:20:55PM +0800, Peter Chen wrote: On Wed, Jul 31, 2013 at 09:33:06AM +0200, Uwe Kleine-König wrote: On Tue, Jul 30, 2013 at 10:04:29PM -0300, Fabio Estevam wrote: From: Fabio Estevam fabio.este...@freescale.com By using devm_request_irq() we don't need to call free_irq(), which simplifies the code a bit. Signed-off-by: Fabio Estevam fabio.este...@freescale.com --- drivers/usb/chipidea/core.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 5cc1b02..d185c41 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -502,8 +502,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, ci); - ret = request_irq(ci-irq, ci_irq, IRQF_SHARED, ci-platdata-name, - ci); + ret = devm_request_irq(dev, ci-irq, ci_irq, IRQF_SHARED, +ci-platdata-name, ci); Mark Brown (now on Cc:) replied to one of my patches using devm_request_irq: I'm always deeply suspicous of devm_request_irq() since you need to be *very* sure that the interrupt can't fire during cleanup and cause the handlers to try to use data structures that are already being freed. and: devm_request_threaded_irq() is just generally a bit of a warning sign since it needs careful checking to tell if it's safe. The probably problem I find is the free_irq will be called after driver's removal is called, then the problem Mark described will occur. See __device_release_driver(struct device *dev) at drivers/base/dd.c. So you mean the remove callback (dev-bus-remove or drv-remove) is called before devres_release_all, right? OK, so the possible problem is that remove is called while the irq is still active. That means you have to assert that all resources the irq handler is using (e.g. ioremap, clk_prepare_enable) are only freed *after* the irq is done. For ioremap that means it must be done using devm_ioremap_resource. For a clock it's not that easy because the irq handler has to assert that a used clk is kept prepared which can only be done using clk_prepare which in turn is not allowed in an irq handler. Hmm. So the only possible fixes are - devm* can be told to also care about clk_disable_unprepare - after disabling irqs in the remove callback wait for all active irqs to be done. (i.e. call synchronize_irq(irq)) - don't use devm_request_irq Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | http://www.pengutronix.de/ | -- 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/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 10:46:45AM +0200, Uwe Kleine-König wrote: OK, so the possible problem is that remove is called while the irq is still active. That means you have to assert that all resources the irq handler is using (e.g. ioremap, clk_prepare_enable) are only freed *after* the irq is done. For ioremap that means it must be done using devm_ioremap_resource. For a clock it's not that easy because the irq handler has to assert that a used clk is kept prepared which can only be done using clk_prepare which in turn is not allowed in an irq handler. Hmm. So the only possible fixes are - devm* can be told to also care about clk_disable_unprepare - after disabling irqs in the remove callback wait for all active irqs to be done. (i.e. call synchronize_irq(irq)) - don't use devm_request_irq I'm not sure that devm_ guarantees any ordering in the cleanups it does so I'd not like to rely on the first option either, if there were some guarantee of that it'd help. The nice thing about explicitly freeing the IRQ is that you can tell that all this stuff is safe by inspection. signature.asc Description: Digital signature
[PATCH v4 3/5] net/usb/r815x: change the return value for bind functions
Replace 0 with the result from usbnet_cdc_bind(). Signed-off-by: Hayes Wang hayesw...@realtek.com --- drivers/net/usb/r815x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c index 1a80e76..2df2f4f 100644 --- a/drivers/net/usb/r815x.c +++ b/drivers/net/usb/r815x.c @@ -172,7 +172,7 @@ static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) dev-mii.phy_id = R815x_PHY_ID; dev-mii.supports_gmii = 1; - return 0; + return status; } static int r8152_bind(struct usbnet *dev, struct usb_interface *intf) @@ -191,7 +191,7 @@ static int r8152_bind(struct usbnet *dev, struct usb_interface *intf) dev-mii.phy_id = R815x_PHY_ID; dev-mii.supports_gmii = 0; - return 0; + return status; } static const struct driver_info r8152_info = { -- 1.8.3.1 -- 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 v4 2/5] net/usb/r815x: avoid to call mdio functions for runtime-suspended device
Don't replace the usb_control_msg() with usbnet_{read,write}_cmd() which couldn't be called inside suspend/resume callback. Keep the basic functions unlimited. Instead, using usb_autopm_get_interface() and usb_autopm_put_interface() in r815x_mdio_{read,write}(). Signed-off-by: Hayes Wang hayesw...@realtek.com --- drivers/net/usb/r815x.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c index e9b99ba..1a80e76 100644 --- a/drivers/net/usb/r815x.c +++ b/drivers/net/usb/r815x.c @@ -126,11 +126,18 @@ out1: static int r815x_mdio_read(struct net_device *netdev, int phy_id, int reg) { struct usbnet *dev = netdev_priv(netdev); + int ret; if (phy_id != R815x_PHY_ID) return -EINVAL; - return ocp_reg_read(dev, BASE_MII + reg * 2); + if (usb_autopm_get_interface(dev-intf) 0) + return -ENODEV; + + ret = ocp_reg_read(dev, BASE_MII + reg * 2); + + usb_autopm_put_interface(dev-intf); + return ret; } static @@ -141,7 +148,12 @@ void r815x_mdio_write(struct net_device *netdev, int phy_id, int reg, int val) if (phy_id != R815x_PHY_ID) return; + if (usb_autopm_get_interface(dev-intf) 0) + return; + ocp_reg_write(dev, BASE_MII + reg * 2, val); + + usb_autopm_put_interface(dev-intf); } static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) -- 1.8.3.1 -- 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 v4 1/5] net/usb/r815x: replace USB buffer from stack to DMA-able
Some USB buffers use stack which may not be DMA-able. Use the buffers from kmalloc to replace those one. Signed-off-by: Hayes Wang hayesw...@realtek.com --- drivers/net/usb/r815x.c | 44 +++- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c index 8523922..e9b99ba 100644 --- a/drivers/net/usb/r815x.c +++ b/drivers/net/usb/r815x.c @@ -24,34 +24,43 @@ static int pla_read_word(struct usb_device *udev, u16 index) { - int data, ret; + int ret; u8 shift = index 2; - __le32 ocp_data; + __le32 *tmp; + + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; index = ~3; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, ocp_data, sizeof(ocp_data), - 500); + index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); if (ret 0) - return ret; + goto out2; - data = __le32_to_cpu(ocp_data); - data = (shift * 8); - data = 0x; + ret = __le32_to_cpu(*tmp); + ret = (shift * 8); + ret = 0x; - return data; +out2: + kfree(tmp); + return ret; } static int pla_write_word(struct usb_device *udev, u16 index, u32 data) { - __le32 ocp_data; + __le32 *tmp; u32 mask = 0x; u16 byen = BYTE_EN_WORD; u8 shift = index 2; int ret; + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + data = mask; if (shift) { @@ -63,19 +72,20 @@ static int pla_write_word(struct usb_device *udev, u16 index, u32 data) ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, ocp_data, sizeof(ocp_data), - 500); + index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); if (ret 0) - return ret; + goto out3; - data |= __le32_to_cpu(ocp_data) ~mask; - ocp_data = __cpu_to_le32(data); + data |= __le32_to_cpu(*tmp) ~mask; + *tmp = __cpu_to_le32(data); ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE, - index, MCU_TYPE_PLA | byen, ocp_data, - sizeof(ocp_data), 500); + index, MCU_TYPE_PLA | byen, tmp, sizeof(*tmp), + 500); +out3: + kfree(tmp); return ret; } -- 1.8.3.1 -- 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/2] usb: chipidea: move vbus regulator operation to core
On Wed, Jul 31, 2013 at 03:32:14PM +0800, Peter Chen wrote: On Wed, Jul 31, 2013 at 09:23:56AM +0200, Michael Grzeschik wrote: Hi Peter, On Wed, Jul 31, 2013 at 09:39:50AM +0800, Peter Chen wrote: On Tue, Jul 30, 2013 at 02:41:23PM +0200, Michael Grzeschik wrote: From: Michael Grzeschik m...@pengutronix.de This patch moves the regulator code from ci_hdrc_imx gluecode to the core layer. It also checks the errorpathes in case the platformglue didn't prepare an regulator for this driver. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/usb/chipidea/ci_hdrc_imx.c | 26 ++ drivers/usb/chipidea/core.c| 16 include/linux/usb/chipidea.h | 1 + 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 06bc775..d2937e1 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -19,7 +19,6 @@ #include linux/dma-mapping.h #include linux/usb/chipidea.h #include linux/clk.h -#include linux/regulator/consumer.h #include ci.h #include ci_hdrc_imx.h @@ -31,7 +30,6 @@ struct ci_hdrc_imx_data { struct usb_phy *phy; struct platform_device *ci_pdev; struct clk *clk; - struct regulator *reg_vbus; }; static const struct usbmisc_ops *usbmisc_ops; @@ -134,20 +132,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) goto err_clk; } - /* we only support host now, so enable vbus here */ - data-reg_vbus = devm_regulator_get(pdev-dev, vbus); - if (!IS_ERR(data-reg_vbus)) { - ret = regulator_enable(data-reg_vbus); - if (ret) { - dev_err(pdev-dev, - Failed to enable vbus regulator, err=%d\n, - ret); - goto err_clk; - } - } else { - data-reg_vbus = NULL; - } - pdata.phy = data-phy; if (!pdev-dev.dma_mask) @@ -160,7 +144,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) if (ret) { dev_err(pdev-dev, usbmisc init failed, ret=%d\n, ret); - goto err; + goto err_clk; } } @@ -172,7 +156,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) dev_err(pdev-dev, Can't register ci_hdrc platform device, err=%d\n, ret); - goto err; + goto err_clk; } if (usbmisc_ops usbmisc_ops-post) { @@ -193,9 +177,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) disable_device: ci_hdrc_remove_device(data-ci_pdev); -err: - if (data-reg_vbus) - regulator_disable(data-reg_vbus); err_clk: clk_disable_unprepare(data-clk); return ret; @@ -208,9 +189,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) pm_runtime_disable(pdev-dev); ci_hdrc_remove_device(data-ci_pdev); - if (data-reg_vbus) - regulator_disable(data-reg_vbus); - if (data-phy) { usb_phy_shutdown(data-phy); module_put(data-phy-dev-driver-owner); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index a5df24c..178b61d 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -57,6 +57,7 @@ #include linux/interrupt.h #include linux/io.h #include linux/kernel.h +#include linux/regulator/consumer.h #include linux/slab.h #include linux/pm_runtime.h #include linux/usb/ch9.h @@ -363,6 +364,21 @@ struct platform_device *ci_hdrc_add_device(struct device *dev, goto put_id; } + /* Get the vbus regulator */ + platdata-reg_vbus = devm_regulator_get(dev, vbus); + if (PTR_ERR(platdata-reg_vbus) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err; + } else if (PTR_ERR(platdata-reg_vbus) == -ENODEV) { + platdata-reg_vbus = NULL; /* no vbus regualator is needed */ + } else if (IS_ERR(platdata-reg_vbus)) { + dev_err(pdev-dev, + Getting regulator error: %ld\n, +
Re: [PATCH 2/2] chipidea: Use devm_request_irq()
[Expanded Cc: a bit] Hello, On Wed, Jul 31, 2013 at 10:05:12AM +0100, Mark Brown wrote: On Wed, Jul 31, 2013 at 10:46:45AM +0200, Uwe Kleine-König wrote: We're discussing about devm_request_irq and wonder what happens at remove time when the irq is still active. OK, so the possible problem is that remove is called while the irq is still active. That means you have to assert that all resources the irq handler is using (e.g. ioremap, clk_prepare_enable) are only freed *after* the irq is done. For ioremap that means it must be done using devm_ioremap_resource. For a clock it's not that easy because the irq handler has to assert that a used clk is kept prepared which can only be done using clk_prepare which in turn is not allowed in an irq handler. Hmm. So the only possible fixes are - devm* can be told to also care about clk_disable_unprepare - after disabling irqs in the remove callback wait for all active irqs to be done. (i.e. call synchronize_irq(irq)) - don't use devm_request_irq I'm not sure that devm_ guarantees any ordering in the cleanups it does so I'd not like to rely on the first option either, if there were some guarantee of that it'd help. The nice thing about explicitly freeing the IRQ is that you can tell that all this stuff is safe by inspection. devm_* at least uses list_for_each_entry_reverse (drivers/base/devres.c:release_nodes()). Without this guarantee devm_ would not make much sense IMHO. To also manage clks, we'd need something like: devm_clk_prepare(dev, some_clk); that makes devm_clk_release also call clk_unprepare the right number of times. Maybe also the same for devm_clk_enable? Does this make sense? Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | http://www.pengutronix.de/ | -- 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/2] chipidea: Use devm_request_irq()
Hello, On Wed, Jul 31, 2013 at 11:44:34AM +0200, Uwe Kleine-König wrote: OK, so the possible problem is that remove is called while the irq is still active. That means you have to assert that all resources the irq If your driver destruction path is running while your irq handler is still running, it's a crappy / broken driver. You need a deactivation step whether you're using devm or not. IRQs can be shared and the device should be in a quiesced state before the driver detaches itself. Note that you can queue deactivation routine using devm. For an example, please take a look at drivers/ata/libata-core.c::ata_host_start(). handler is using (e.g. ioremap, clk_prepare_enable) are only freed *after* the irq is done. For ioremap that means it must be done using devm_ioremap_resource. For a clock it's not that easy because the irq handler has to assert that a used clk is kept prepared which can only be done using clk_prepare which in turn is not allowed in an irq handler. Hmm. So the only possible fixes are - devm* can be told to also care about clk_disable_unprepare - after disabling irqs in the remove callback wait for all active irqs to be done. (i.e. call synchronize_irq(irq)) - don't use devm_request_irq Again, the right thing to do is having a proper deactivation step. This is nothing devm can do automatically. There's no way for it to find out that the device is actually quiesced. Let's say it waits for the current instance of irq handler to finish. How would it know that it won't start again between the flushing of the current instance and irq deregistration. Add an explicit deactivation step using devres_alloc(). I'm not sure that devm_ guarantees any ordering in the cleanups it does so I'd not like to rely on the first option either, if there were some guarantee of that it'd help. The nice thing about explicitly freeing the IRQ is that you can tell that all this stuff is safe by inspection. devm_* at least uses list_for_each_entry_reverse (drivers/base/devres.c:release_nodes()). Without this guarantee devm_ would not make much sense IMHO. devm guarantees that the destruction callbacks are called in the reverse order of registration. Thanks. -- tejun -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2] USB: EHCI: make ehci-w90X900 a separate driver
Separate the W90X900(W90P910) on-chip host controller driver from ehci-hcd host code so that it can be built as a separate driver module. This work is part of enabling multi-platform kernels on ARM; however, note that other changes are still needed before W90X900(W90P910) can be booted with a multi-platform kernel and an ehci driver that only works on one of them. With the infrastructure added by Alan Stern in patch 3e0232039 USB: EHCI: prepare to make ehci-hcd a library module, we can avoid this problem by turning a bus glue into a separate module, as we do here for the w90X900 bus glue. Signed-off-by: Manjunath Goudar manjunath.gou...@linaro.org Acked-by: Arnd Bergmann a...@arndb.de Acked-by: Wan ZongShun mcuos@gmail.com Acked-by: Alan Stern st...@rowland.harvard.edu Cc: Greg KH g...@kroah.com Cc: linux-usb@vger.kernel.org Cc: linux-ker...@vger.kernel.org V2: -Arranged #include's in alphabetical order. -Replaced w90p910 by w90x900 because it is supports all series of w90x900. --- drivers/usb/host/Kconfig|2 +- drivers/usb/host/Makefile |1 + drivers/usb/host/ehci-hcd.c |5 --- drivers/usb/host/ehci-w90x900.c | 85 --- 4 files changed, 37 insertions(+), 56 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index ba52912..7bc598b 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -244,7 +244,7 @@ config USB_EHCI_MV SoCs, see USB_EHCI_HCD_ORION for those. config USB_W90X900_EHCI - bool W90X900(W90P910) EHCI support + tristate W90X900(W90P910) EHCI support depends on ARCH_W90X900 ---help--- Enables support for the W90X900 USB controller diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 7664db8..28adb3f 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_MV) += ehci-mv.o +obj-$(CONFIG_USB_W90X900_EHCI) += ehci-w90x900.o obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 5717dcd..4a5644e 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1249,11 +1249,6 @@ MODULE_LICENSE (GPL); #define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver #endif -#ifdef CONFIG_USB_W90X900_EHCI -#include ehci-w90x900.c -#definePLATFORM_DRIVER ehci_hcd_w90x900_driver -#endif - #ifdef CONFIG_USB_OCTEON_EHCI #include ehci-octeon.c #define PLATFORM_DRIVERehci_octeon_driver diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index 59e0e24..4d6631d 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -11,13 +11,28 @@ * */ +#include linux/dma-mapping.h +#include linux/io.h +#include linux/kernel.h +#include linux/module.h +#include linux/of.h #include linux/platform_device.h +#include linux/usb.h +#include linux/usb/hcd.h + +#include ehci.h /* enable phy0 and phy1 for w90p910 */ #defineENPHY (0x018) #define PHY0_CTR (0xA4) #define PHY1_CTR (0xA8) +#define DRIVER_DESC EHCI w90x900 driver + +static const char hcd_name[] = ehci-w90x900 ; + +static struct hc_driver __read_mostly ehci_w90x900_hc_driver; + static int usb_w90x900_probe(const struct hc_driver *driver, struct platform_device *pdev) { @@ -99,54 +114,6 @@ void usb_w90x900_remove(struct usb_hcd *hcd, struct platform_device *pdev) usb_put_hcd(hcd); } -static const struct hc_driver ehci_w90x900_hc_driver = { - .description = hcd_name, - .product_desc = Nuvoton w90x900 EHCI Host Controller, - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* -* generic hardware linkage -*/ - .irq = ehci_irq, - .flags = HCD_USB2|HCD_MEMORY, - - /* -* basic lifecycle operations -*/ - .reset = ehci_setup, - .start = ehci_run, - - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* -* managing i/o requests and associated device resources -*/ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - /* -* scheduling support -*/ - .get_frame_number = ehci_get_frame, - - /* -* root hub support -*/ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, -#endif - .relinquish_port= ehci_relinquish_port, - .port_handed_over
Re: [PATCH] musb: don't reset endpoint data toggle on blackfin
Hi Balbi, On Thu, Jul 18, 2013 at 07:04:14PM -0400, Scott Jiang wrote: Reset endpoint data toggle would lead to failure for musb RTL version 1.9 on blackfin. is this specific to musb 1.9 or to blackfin ? I'm not sure about this. It failed in musb 1.9 on bf527. But this bug didn't affect musb RTL 2.0 on bf609. Do you have Mentor's errata list or just Analog Device's errata ? I reviewed the Analog Device's errata but it didn't mention this. I'd keep this as a local patch because I can't test it on other platform. Thanks. Scott -- 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 v2 26/42] USB: ohci-at91: add usb_clk for transition to common clk framework
Hello Alan, I don't know if you remember but a few days back I sent a series which included this patch (ARM: at91: prepare transition to common clk framework). It was decided to move this patch out of the prepare series to avoid backward compatility handling. Things have changed a little bit. I was asked to split the ARM: at91: move to common clk framework series into several smaller series (one for each SoC). This means at91 will have some SoCs supporting using common clk framework (and thus will define the usb_clk) and other SoCs using the old at91 clk implementation (which does not define usb_clk). I was also requested to drop common clk framework support for non dt boards, which means, as long as at91 keep non dt boards the at91 old clk implem will remain active. For all these reasons I will have to reintroduce the backward compatibility hack. Should I get this patch (and patch 27) out of the this series and back to the prepare series ? Best Regards, Boris On 17/07/2013 17:47, Boris BREZILLON wrote: The AT91 PMC (Power Management Controller) provides an USB clock used by USB Full Speed host (ohci) and USB Full Speed device (udc). The usb drivers (ohci and udc) must configure this clock to 48Mhz. This configuration was formely done in mach-at91/clock.c, but this implementation will be removed when moving to common clk framework. This patch add support for usb clock retrieval and configuration. Signed-off-by: Boris BREZILLON b.brezil...@overkiz.com --- drivers/usb/host/ohci-at91.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 9677f68..ca1cdd6 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -31,8 +31,8 @@ #define at91_for_each_port(index) \ for ((index) = 0; (index) AT91_MAX_USBH_PORTS; (index)++) -/* interface and function clocks; sometimes also an AHB clock */ -static struct clk *iclk, *fclk, *hclk; +/* interface, function and usb clocks; sometimes also an AHB clock */ +static struct clk *iclk, *fclk, *uclk, *hclk; static int clocked; extern int usb_disabled(void); @@ -41,6 +41,8 @@ extern int usb_disabled(void); static void at91_start_clock(void) { + clk_set_rate(uclk, 4800); + clk_prepare_enable(uclk); clk_prepare_enable(hclk); clk_prepare_enable(iclk); clk_prepare_enable(fclk); @@ -52,6 +54,7 @@ static void at91_stop_clock(void) clk_disable_unprepare(fclk); clk_disable_unprepare(iclk); clk_disable_unprepare(hclk); + clk_disable_unprepare(uclk); clocked = 0; } @@ -162,6 +165,12 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, retval = PTR_ERR(hclk); goto err5; } + uclk = clk_get(pdev-dev, usb_clk); + if (IS_ERR(uclk)) { + dev_err(pdev-dev, failed to get usb_clk\n); + retval = PTR_ERR(uclk); + goto err6; + } at91_start_hc(pdev); ohci_hcd_init(hcd_to_ohci(hcd)); @@ -173,6 +182,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, /* Error handling */ at91_stop_hc(pdev); + clk_put(uclk); + err6: clk_put(hclk); err5: clk_put(fclk); @@ -212,6 +223,7 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd, release_mem_region(hcd-rsrc_start, hcd-rsrc_len); usb_put_hcd(hcd); + clk_put(uclk); clk_put(hclk); clk_put(fclk); clk_put(iclk); -- 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/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 05:54:11AM -0400, Tejun Heo wrote: Hello, On Wed, Jul 31, 2013 at 11:44:34AM +0200, Uwe Kleine-König wrote: OK, so the possible problem is that remove is called while the irq is still active. That means you have to assert that all resources the irq If your driver destruction path is running while your irq handler is still running, it's a crappy / broken driver. You need a deactivation Well, you cannot avoid assuming that the irq is still active when your driver's remove callback is called. But I agree about crappyness at the end of the destruction path. The problem is that crap is as easy as: probe(..) { clk = devm_get_clk(...); clk_prepare_enable(clk); writel(1, base + IRQENABLE); devm_request_irq(...); } remove(..) { writel(0, base + IRQENABLE); clk_disable_unprepare(clk); } and I think there are more and more drivers doing that. step whether you're using devm or not. IRQs can be shared and the device should be in a quiesced state before the driver detaches itself. Note that you can queue deactivation routine using devm. For an example, please take a look at drivers/ata/libata-core.c::ata_host_start(). handler is using (e.g. ioremap, clk_prepare_enable) are only freed *after* the irq is done. For ioremap that means it must be done using devm_ioremap_resource. For a clock it's not that easy because the irq handler has to assert that a used clk is kept prepared which can only be done using clk_prepare which in turn is not allowed in an irq handler. Hmm. So the only possible fixes are - devm* can be told to also care about clk_disable_unprepare - after disabling irqs in the remove callback wait for all active irqs to be done. (i.e. call synchronize_irq(irq)) - don't use devm_request_irq Again, the right thing to do is having a proper deactivation step. This is nothing devm can do automatically. There's no way for it to find out that the device is actually quiesced. Let's say it waits for the current instance of irq handler to finish. How would it know that it won't start again between the flushing of the current instance and irq deregistration. Add an explicit deactivation step using devres_alloc(). I'm not sure that devm_ guarantees any ordering in the cleanups it does so I'd not like to rely on the first option either, if there were some guarantee of that it'd help. The nice thing about explicitly freeing the IRQ is that you can tell that all this stuff is safe by inspection. devm_* at least uses list_for_each_entry_reverse (drivers/base/devres.c:release_nodes()). Without this guarantee devm_ would not make much sense IMHO. devm guarantees that the destruction callbacks are called in the reverse order of registration. That's fine. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | http://www.pengutronix.de/ | -- 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 v3 1/3] net/usb/r815x: replace USB buffer from stack to DMA-able
On Wed, Jul 31, 2013 at 2:49 AM, David Miller da...@davemloft.net wrote: From: Joe Perches j...@perches.com Date: Tue, 30 Jul 2013 11:41:17 -0700 On Tue, 2013-07-30 at 11:33 -0700, David Miller wrote: From: Greg KH gre...@linuxfoundation.org Date: Tue, 30 Jul 2013 07:00:59 -0700 This call is so slow, you can afford to make a call to kmalloc for the data, as it sure just did for other structures it needed :) I told him to implement things this way, to avoid calling kmalloc every single register access. Using kmalloc all the time makes the access fragile, since a badly timed call during high memory pressure can fail. I'd rather the potential failure happen at one time, probe time. In any event, Ming Lei has suggested using usbnet_{read,write}_cmd() instead, which sounds like a good solution to this problem. Those do per-call allocs too. Sigh... Ok I won't fight this any longer then :-) It might not be a big deal because most of these commands are sent during probe()/ethtool/... context, and not in tx/rx path. Another choice is to reserve a big enough buffer during probe() for read/write command, but one mutex is needed too for avoiding concurrent calling. Anyway, please call the command API to do such thing, so that we can improve it easily in future. Thanks, -- Ming Lei -- 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/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 12:28:53PM +0200, Uwe Kleine-König wrote: Well, you cannot avoid assuming that the irq is still active when your driver's remove callback is called. But I agree about crappyness at the end of the destruction path. The problem is that crap is as easy as: probe(..) { clk = devm_get_clk(...); clk_prepare_enable(clk); writel(1, base + IRQENABLE); devm_request_irq(...); } remove(..) { writel(0, base + IRQENABLE); clk_disable_unprepare(clk); } and I think there are more and more drivers doing that. Oh, so, the problem is that the driver is mixing devm and non-devm resource management and ending up messing the order of shutdown? Well, the obvious solution is using devm for clk too. devm does provide constructs to build custom destruction sequence so that such calls can be mixed but it's a bit of hassle and mostly meant for driver midlayers (libata, firewire, usb and so on) so that they can provide nicely wrapped init/exit helpers for low level drivers. In general, partial devm conversion can easily lead to subtle shutdown order problems and it's best to go all the way. Thanks. -- tejun -- 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 0/4] USB USBNET: loose DMA SG check and support usbnet DMA SG
Hi, This patchset allows drivers to pass sg buffers which size can't be divided by max packet size of endpoint if the host controllers support this kind of sg buffers. Previously we add check[1] on the situation and don't allow these sg buffers passed to USB HCD, looks the check is too strict because some applications(such as network stack) can't provide this sg buffers which size can be divided by max packet size, so this patch looses the check in case that the host controllers support it. Also patch 3/4 implements DMA SG on usbnet driver, and patch 4/4 enables it on ax88179_178a USB3 NIC, so CPU utilization can be decreased much with usbnet DMA SG when the USB3 NIC is attached to xHCI controller. [1], http://git.kernel.org/cgit/linux/kernel/git/gregkh/usb.git/commit/?h=usb-nextid=10e232c597ac757e7f8600649f7e872e86de190f drivers/net/usb/ax88179_178a.c | 30 + drivers/net/usb/usbnet.c | 48 ++-- drivers/usb/core/urb.c |3 ++- drivers/usb/host/xhci.c|4 include/linux/usb.h|3 ++- include/linux/usb/usbnet.h |4 6 files changed, 88 insertions(+), 4 deletions(-) Thanks, -- Ming Lei -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] USBNET: support DMA SG
This patch introduces support of DMA SG if the USB host controller attached by usbnet device is capable of building packet from discontinuous buffers. Firstly, one header for usb transfer is often needed for device, and this patch introduces one extra small buffer to hold the header, then we can avoid move or copy data over the whole skb. Secondaly, the patch supports passing the skb fragment buffers to usb stack directly via urb-sg. Signed-off-by: Ming Lei ming@canonical.com --- drivers/net/usb/usbnet.c | 48 ++-- include/linux/usb/usbnet.h |4 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index e4811d7..c04682b 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1232,6 +1232,45 @@ EXPORT_SYMBOL_GPL(usbnet_tx_timeout); /*-*/ +static int build_dma_sg(const struct sk_buff *skb, struct urb *urb) +{ + unsigned num_sgs, total_len = 0; + int i, s = 0; + struct skb_data *entry = (struct skb_data *)skb-cb; + int has_header = !!entry-length; + + num_sgs = skb_shinfo(skb)-nr_frags + has_header + 1; + if (num_sgs == 1) + return 0; + + urb-sg = kmalloc(num_sgs * sizeof(struct scatterlist), GFP_ATOMIC); + if (!urb-sg) + return -ENOMEM; + + urb-num_sgs = num_sgs; + sg_init_table(urb-sg, urb-num_sgs); + + if (has_header) { + sg_set_buf(urb-sg[s++], entry-header, + entry-length); + total_len += entry-length; + } + + sg_set_buf(urb-sg[s++], skb-data, skb_headlen(skb)); + total_len += skb_headlen(skb); + + for (i = 0; i skb_shinfo(skb)-nr_frags; i++) { + struct skb_frag_struct *f = skb_shinfo(skb)-frags[i]; + + total_len += skb_frag_size(f); + sg_set_page(urb-sg[i + s], f-page.p, f-size, + f-page_offset); + } + urb-transfer_buffer_length = total_len; + + return 1; +} + netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) { @@ -1258,7 +1297,6 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, goto drop; } } - length = skb-len; if (!(urb = usb_alloc_urb (0, GFP_ATOMIC))) { netif_dbg(dev, tx_err, dev-net, no urb\n); @@ -1268,10 +1306,14 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, entry = (struct skb_data *) skb-cb; entry-urb = urb; entry-dev = dev; - entry-length = length; usb_fill_bulk_urb (urb, dev-udev, dev-out, skb-data, skb-len, tx_complete, skb); + if (dev-can_dma_sg) { + if (build_dma_sg(skb, urb) 0) + goto drop; + } + entry-length = length = urb-transfer_buffer_length; /* don't assume the hardware handles USB_ZERO_PACKET * NOTE: strictly conforming cdc-ether devices should expect @@ -1391,6 +1433,8 @@ static void usbnet_bh (unsigned long param) rx_process (dev, skb); continue; case tx_done: + kfree(entry-header); + kfree(entry-urb-sg); case rx_cleanup: usb_free_urb (entry-urb); dev_kfree_skb (skb); diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 8fbc008..51aa466 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -35,6 +35,7 @@ struct usbnet { unsigned char suspend_count; unsigned char pkt_cnt, pkt_err; unsigned short rx_qlen, tx_qlen; + unsignedcan_dma_sg:1; /* i/o info: pipes etc */ unsignedin, out; @@ -217,7 +218,10 @@ enum skb_state { struct skb_data { /* skb-cb is one of these */ struct urb *urb; struct usbnet *dev; + void*header; enum skb_state state; + + /* either header length for dma sg or transfer buffer lenght */ size_t length; }; -- 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
[PATCH 2/4] USB: XHCI: mark no_sg_limit
This patch marks all xHCI controllers as no_sg_limit since xHCI supports building packet from discontinuous buffers. Cc: Sarah Sharp sarah.a.sh...@linux.intel.com Signed-off-by: Ming Lei ming@canonical.com --- drivers/usb/host/xhci.c |4 1 file changed, 4 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 2c49f00..541b155 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4841,6 +4841,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) /* Accept arbitrarily long scatter-gather lists */ hcd-self.sg_tablesize = ~0; + + /* support to build packet from discontinuous buffers */ + hcd-self.no_sg_limit = 1; + /* XHCI controllers don't stop the ep queue on short packets :| */ hcd-self.no_stop_on_short = 1; -- 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
[PATCH 4/4] USBNET: ax88179_178a: enable tso if host supports sg dma
This patch enables 'can_dma_sg' flag for ax88179_178a device if the attached host controller supports building packet from discontinuous buffers(DMA SG is possible), so both frame header and skb data buffers can be passed to usb stack via urb-sg, then skb data copy can be saved. With the patch, CPU utilization decreased much in iperf test at client mode. Signed-off-by: Ming Lei ming@canonical.com --- drivers/net/usb/ax88179_178a.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 5a468f3..c75bded 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -1031,12 +1031,20 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) dev-mii.phy_id = 0x03; dev-mii.supports_gmii = 1; + if (dev-udev-bus-no_sg_limit) + dev-can_dma_sg = 1; + dev-net-features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM; dev-net-hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM; + if (dev-can_dma_sg) { + dev-net-features |= NETIF_F_SG | NETIF_F_TSO; + dev-net-hw_features |= NETIF_F_SG | NETIF_F_TSO; + } + /* Enable checksum offload */ *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; @@ -1170,12 +1178,30 @@ ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) int mss = skb_shinfo(skb)-gso_size; int headroom; int tailroom; + struct skb_data *entry = (struct skb_data *)skb-cb; tx_hdr1 = skb-len; tx_hdr2 = mss; if (((skb-len + 8) % frame_size) == 0) tx_hdr2 |= 0x80008000; /* Enable padding */ + if (dev-can_dma_sg) { + if (!(entry-header = kmalloc(8, GFP_ATOMIC))) + goto no_sg; + + entry-length = 8; + cpu_to_le32s(tx_hdr1); + cpu_to_le32s(tx_hdr2); + memcpy(entry-header, tx_hdr1, 4); + memcpy(entry-header + 4, tx_hdr2, 4); + + return skb; + } else { +no_sg: + entry-header = NULL; + entry-length = 0; + } + headroom = skb_headroom(skb); tailroom = skb_tailroom(skb); @@ -1323,6 +1349,10 @@ static int ax88179_reset(struct usbnet *dev) dev-net-hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM; + if (dev-can_dma_sg) { + dev-net-features |= NETIF_F_SG | NETIF_F_TSO; + dev-net-hw_features |= NETIF_F_SG | NETIF_F_TSO; + } /* Enable checksum offload */ *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | -- 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: [PATCH 0/4] USB USBNET: loose DMA SG check and support usbnet DMA SG
On Wed, 2013-07-31 at 18:51 +0800, Ming Lei wrote: Hi, This patchset allows drivers to pass sg buffers which size can't be divided by max packet size of endpoint if the host controllers support this kind of sg buffers. Cool. One question though. It makes sense to use sg only if all elements are in memory capable of DMA. It seems to be possible to have HCs which can do unlimited sg but are limited to 32bit DMA. Regards Oliver -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 05:54:11AM -0400, Tejun Heo wrote: On Wed, Jul 31, 2013 at 11:44:34AM +0200, Uwe Kleine-König wrote: OK, so the possible problem is that remove is called while the irq is still active. That means you have to assert that all resources the irq If your driver destruction path is running while your irq handler is still running, it's a crappy / broken driver. You need a deactivation step whether you're using devm or not. IRQs can be shared and the device should be in a quiesced state before the driver detaches itself. Note that you can queue deactivation routine using devm. For an example, please take a look at drivers/ata/libata-core.c::ata_host_start(). I'm not sure I understand how this relates the problem. The main issue here is that for the shared IRQ case quiescing the device doesn't make any difference since one of the other users of the interrupt could cause the interrupt handler to be called regardless of what the hardware is doing. This means that we need to guarantee that anything the interrupt handler relies on has not been deallocated before the interrupt handler is unregistered. irq deregistration. Add an explicit deactivation step using devres_alloc(). devm guarantees that the destruction callbacks are called in the reverse order of registration. OK, that's helpful. It'd be good to document this if it's something the API is intending to guarantee, though - devres.txt doesn't mention this and it's not something I'd intuitively expect to be the case. signature.asc Description: Digital signature
Re: [PATCH 2/2] chipidea: Use devm_request_irq()
Hello, On Wed, Jul 31, 2013 at 12:18:53PM +0100, Mark Brown wrote: I'm not sure I understand how this relates the problem. The main issue here is that for the shared IRQ case quiescing the device doesn't make any difference since one of the other users of the interrupt could cause the interrupt handler to be called regardless of what the hardware is doing. This means that we need to guarantee that anything the interrupt handler relies on has not been deallocated before the interrupt handler is unregistered. Yeah, if all resources are allocated using devm - note that you can hook in non-devm resources using devres_alloc() - all resources which would be necessary for the interrupt handler would have been allocated before the irq was allocated, right? And thus they'll of course released after the IRQ is freed. The problem arises when devm and non-devm releases are mixed as non-devm ones would happen before all devm ones messing up the release sequencing. OK, that's helpful. It'd be good to document this if it's something the API is intending to guarantee, though - devres.txt doesn't mention Oh, it's definitely guaranteed. Nothing would work otherwise. this and it's not something I'd intuitively expect to be the case. Oops... I guess I forgot to mention that. Care to submit a patch? Thanks. -- tejun -- 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: Ejected Nook (usb mass storage) prevents suspend
On Mon, 2013-07-29 at 10:21 -0400, Alan Stern wrote: On Mon, 29 Jul 2013, Oliver Neukum wrote: On Fri, 2013-07-26 at 16:31 -0400, Alan Stern wrote: In addition to my earlier comment, the patch below should be applied. It will fix your immediate problem, although not in the best way. Alan, I think your diagnosis is correct, but not the fix. This is run even in the runtime case. We might lose data if the flush is not done. Actually no, the scsi_bus_suspend_common() routine does not run during runtime PM. It gets called only from scsi_bus_suspend(), scsi_bus_freeze(), and scsi_bus_poweroff(), which are all part of system sleep. These errors should be handled cleanly. How about this patch? Regards Oliver From 76a377d9894dc8945e9afecc7f9864e6dc3156b1 Mon Sep 17 00:00:00 2001 From: Oliver Neukum oneu...@suse.de Date: Wed, 31 Jul 2013 13:32:51 +0200 Subject: [PATCH] sd: handle errors during suspend Errors during suspend must be handled according to reasons Errors due to missing media or unplugged devices must be ignored. The error returns must be modified so that the generic layer understands them. Signed-off-by: Oliver Neukum oneu...@suse.de --- drivers/scsi/scsi_pm.c | 3 ++- drivers/scsi/sd.c | 61 +- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index 4c5aabe..af4c050 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c @@ -54,7 +54,8 @@ scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *)) /* * All the high-level SCSI drivers that implement runtime * PM treat runtime suspend, system suspend, and system - * hibernate identically. + * hibernate nearly identically. In all cases the requirements + * for runtime suspension are stricter. */ if (pm_runtime_suspended(dev)) return 0; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 86fcf2c..76273f4 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -105,7 +105,8 @@ static void sd_unlock_native_capacity(struct gendisk *disk); static int sd_probe(struct device *); static int sd_remove(struct device *); static void sd_shutdown(struct device *); -static int sd_suspend(struct device *); +static int sd_suspend_system(struct device *); +static int sd_suspend_runtime(struct device *); static int sd_resume(struct device *); static void sd_rescan(struct device *); static int sd_done(struct scsi_cmnd *); @@ -483,11 +484,11 @@ static struct class sd_disk_class = { }; static const struct dev_pm_ops sd_pm_ops = { - .suspend = sd_suspend, + .suspend = sd_suspend_system, .resume = sd_resume, - .poweroff = sd_suspend, + .poweroff = sd_suspend_system, .restore = sd_resume, - .runtime_suspend = sd_suspend, + .runtime_suspend = sd_suspend_runtime, .runtime_resume = sd_resume, }; @@ -1455,12 +1456,31 @@ static int sd_sync_cache(struct scsi_disk *sdkp) if (res) { sd_print_result(sdkp, res); - if (driver_byte(res) DRIVER_SENSE) + + if (driver_byte(res) DRIVER_SENSE) sd_print_sense_hdr(sdkp, sshdr); + /* we need to evaluate the error return */ + if ((scsi_sense_valid(sshdr) + /* 0x3a is medium not present */ + sshdr.asc == 0x3a)) +/* this is no error here */ +return 0; + + switch (host_byte(res)) { + /* ignore errors due to racing a disconnection */ + case DID_BAD_TARGET: + case DID_NO_CONNECT: + return 0; + /* signal the upper layer it might try again */ + case DID_BUS_BUSY: + case DID_IMM_RETRY: + case DID_REQUEUE: + case DID_SOFT_ERROR: + return -EBUSY; + default: + return -EIO; + } } - - if (res) - return -EIO; return 0; } @@ -3062,9 +3082,17 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) sd_print_result(sdkp, res); if (driver_byte(res) DRIVER_SENSE) sd_print_sense_hdr(sdkp, sshdr); + if ((scsi_sense_valid(sshdr) + /* 0x3a is medium not present */ + sshdr.asc == 0x3a)) + res = 0; } - return res; + /* SCSI error codes must not go to the generic layer */ + if (res) + return -EIO; + + return 0; } /* @@ -3096,7 +3124,7 @@ exit: scsi_disk_put(sdkp); } -static int sd_suspend(struct device *dev) +static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) { struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); int ret = 0; @@ -3113,7 +3141,10 @@ static int sd_suspend(struct device *dev) if (sdkp-device-manage_start_stop) { sd_printk(KERN_NOTICE, sdkp, Stopping disk\n); + /* an error is not worth aborting a system sleep */ ret = sd_start_stop_device(sdkp, 0); + if (ignore_stop_errors) + ret = 0; } done: @@ -3121,6 +3152,16 @@ done: return ret; } +static int sd_suspend_system(struct device *dev) +{ + return sd_suspend_common(dev, true); +} + +static int sd_suspend_runtime(struct device *dev) +{ +return sd_suspend_common(dev, false); +} +
Re: [PATCH] musb: don't reset endpoint data toggle on blackfin
Hi, On Wed, Jul 31, 2013 at 06:26:24PM +0800, Scott Jiang wrote: On Thu, Jul 18, 2013 at 07:04:14PM -0400, Scott Jiang wrote: Reset endpoint data toggle would lead to failure for musb RTL version 1.9 on blackfin. is this specific to musb 1.9 or to blackfin ? I'm not sure about this. It failed in musb 1.9 on bf527. But this bug didn't affect musb RTL 2.0 on bf609. Do you have Mentor's errata list or just Analog Device's errata ? I reviewed the Analog Device's errata but it didn't mention this. I'd keep this as a local patch because I can't test it on other platform. Thanks. alright. I'd like to push it upstream, but perhaps we add a quirk flag and enable it for blackfin only ? Can you do that ? Add a 'quirks' member to struct musb and struct musb_platform_data, then pass the quirks from blackfin.c to MUSB. If other people need th workaround, they just add the flag. -- balbi signature.asc Description: Digital signature
Re: [PATCH 2/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 07:32:44AM -0400, Tejun Heo wrote: Yeah, if all resources are allocated using devm - note that you can hook in non-devm resources using devres_alloc() - all resources which would be necessary for the interrupt handler would have been allocated before the irq was allocated, right? And thus they'll of course released after the IRQ is freed. The problem arises when devm and non-devm releases are mixed as non-devm ones would happen before all devm ones messing up the release sequencing. OK, that's helpful. It'd be good to document this if it's something the API is intending to guarantee, though - devres.txt doesn't mention Oh, it's definitely guaranteed. Nothing would work otherwise. Most things would work just fine - most of the uses of devm_ are just resource allocations that can safely be freed in essentially any order. It doesn't really matter if you free the driver's private structure before you free the clock that's pointing to it or whatever since neither has any real connection to the other. this and it's not something I'd intuitively expect to be the case. Oops... I guess I forgot to mention that. Care to submit a patch? I'll take a look. signature.asc Description: Digital signature
Re: [PATCH 0/4] USB USBNET: loose DMA SG check and support usbnet DMA SG
On Wed, Jul 31, 2013 at 7:12 PM, Oliver Neukum oneu...@suse.de wrote: On Wed, 2013-07-31 at 18:51 +0800, Ming Lei wrote: Hi, This patchset allows drivers to pass sg buffers which size can't be divided by max packet size of endpoint if the host controllers support this kind of sg buffers. Cool. One question though. It makes sense to use sg only if all elements are in memory capable of DMA. It seems to be possible to have HCs which can do unlimited sg but are limited to 32bit DMA. For current usbnet devices which supports TSO, one header need to add before skb-data from network stack, so basically the first two elements aren't OK for other HCs(EHCI/UHCI/...) to DMA from SG. Thanks, -- Ming Le -- 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/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 12:50:27PM +0100, Mark Brown wrote: Most things would work just fine - most of the uses of devm_ are just resource allocations that can safely be freed in essentially any order. It doesn't really matter if you free the driver's private structure before you free the clock that's pointing to it or whatever since neither has any real connection to the other. If you have DMA / IRQ / command engine deactivations in devm path which often is the case with full conversions, freeing any resources including DMA areas and host private data in the wrong order is a horrible idea. It's worse as it won't really be noticeable in most cases. Thanks. -- tejun -- 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 4/4] USBNET: ax88179_178a: enable tso if host supports sg dma
On Wed, Jul 31, 2013 at 06:51:49PM +0800, Ming Lei wrote: This patch enables 'can_dma_sg' flag for ax88179_178a device if the attached host controller supports building packet from discontinuous buffers(DMA SG is possible), so both frame header and skb data buffers can be passed to usb stack via urb-sg, then skb data copy can be saved. With the patch, CPU utilization decreased much in iperf test at client mode. What is much? --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -1031,12 +1031,20 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) dev-mii.phy_id = 0x03; dev-mii.supports_gmii = 1; + if (dev-udev-bus-no_sg_limit) + dev-can_dma_sg = 1; I don't feel comfortable with USB drivers poking about in the USB host controller structures like this. If we really do this, please provide a function call for it to make to determine this. But even then, is this really something that we want/need to do at all? If only some xhci controller support this, we will start to see more driver-specific changes just to handle one type of host controller. Why not have the USB core handle it instead and if the host controller can not do sg lists like this, fall back to a slower implementation? thanks, greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 1/5] net/usb/r815x: replace USB buffer from stack to DMA-able
On Wed, Jul 31, 2013 at 05:21:22PM +0800, Hayes Wang wrote: Some USB buffers use stack which may not be DMA-able. Use the buffers from kmalloc to replace those one. Signed-off-by: Hayes Wang hayesw...@realtek.com Acked-by: Greg Kroah-Hartman gre...@linuxfoundation.org -- 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 v4 4/5] net/usb/r8152: make sure the USB buffer is DMA-able
On Wed, Jul 31, 2013 at 05:21:25PM +0800, Hayes Wang wrote: Allocate the required memory before calling usb_control_msg. And the additional memory copy is necessary. Signed-off-by: Hayes Wang hayesw...@realtek.com Acked-by: Greg Kroah-Hartman gre...@linuxfoundation.org -- 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: External HDD does not work with 3.11-rc2
On Tue, Jul 30, 2013 at 9:28 PM, Alan Stern st...@rowland.harvard.edu wrote: On Tue, 30 Jul 2013, Sarah Sharp wrote: On Tue, Jul 30, 2013 at 12:52:40PM -0400, Alan Stern wrote: Sarah, the usbmon trace shows that after doing a successful port reset and clearing a bunch of port features, the system tells the port to go into the SS.disabled state for no apparent reason: 88014649f3c0 1804119918 S Co:4:001:0 s 23 03 0004 0002 0 88014649f3c0 1804119924 C Co:4:001:0 0 0 88020a1dd000 1804170382 S Ci:4:001:0 s a3 00 0002 0004 4 88020a1dd000 1804170389 C Ci:4:001:0 0 4 = 03021000 8801b7173300 1804221388 S Co:4:001:0 s 23 01 0014 0002 0 8801b7173300 1804221397 C Co:4:001:0 0 0 8801b7173300 1804221398 S Co:4:001:0 s 23 01 001d 0002 0 8801b7173300 1804221403 C Co:4:001:0 0 0 8801b7173300 1804221403 S Co:4:001:0 s 23 01 0019 0002 0 8801b7173300 1804221407 C Co:4:001:0 0 0 8801b7173300 1804221408 S Co:4:001:0 s 23 01 0010 0002 0 8801b7173300 1804221412 C Co:4:001:0 0 0 8801b7173300 1804221414 S Ci:4:001:0 s a3 00 0002 0004 4 8801b7173300 1804221417 C Ci:4:001:0 0 4 = 0302 88014649f3c0 1804623388 S Co:4:001:0 s 23 03 0005 0402 0 88020ceb1600 1804623409 C Ii:4:001:1 0:2048 1 = 04 88020ceb1600 1804623410 S Ii:4:001:1 -115:2048 4 88014649f3c0 1804623415 C Co:4:001:0 0 0 Do you have any idea why it is doing this? If a warm reset failed, the USB core will put the port into SS.Disabled. If enumeration fails in the right places, the port will also be disabled. As far as I can tell from the usbmon trace, the reset succeeded. dmesg with CONFIG_USB_DEBUG and CONFIG_USB_XHCI_HCD_DEBUGGING might help me understand what's going on. A log with CONFIG_USB_DEBUG and CONFIG_USB_XHCI_HCD_DEBUGGING enabled is attached to this mail. Note that the issue only occures if the drive is connected to the usb3 port of my docking station. (As described in https://bugzilla.redhat.com/show_bug.cgi?id=984189 .) usb-debug.txt.bz2 Description: BZip2 compressed data
Re: [PATCH 2/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 07:55:27AM -0400, Tejun Heo wrote: If you have DMA / IRQ / command engine deactivations in devm path which often is the case with full conversions, freeing any resources including DMA areas and host private data in the wrong order is a horrible idea. It's worse as it won't really be noticeable in most cases. It's really only interrupts that affect most devices - if there's DMA or anything going on after the remove() then as you said earlier the driver is probably doing something wrong. signature.asc Description: Digital signature
Re: [PATCH] usb: dwc3: use dev_get_platdata()
Hello. On 31-07-2013 10:22, Felipe Balbi wrote: Use the wrapper function for retrieving the platform_data instead of accessing dev-platform_data directly. Inspired-by: Jingoo Han jg1@samsung.com Signed-off-by: Felipe Balbi ba...@ti.com --- drivers/usb/dwc3/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index da0a4b8..aa48abd 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -350,11 +350,11 @@ static void dwc3_core_exit(struct dwc3 *dwc) static int dwc3_probe(struct platform_device *pdev) { - struct dwc3_platform_data *pdata = pdev-dev.platform_data; + struct device *dev = pdev-dev; + struct dwc3_platform_data *pdata = dev_get_platdata(dev); struct device_node *node = pdev-dev.of_node; Why not use your 'dev' variable also here? WBR, Sergei -- 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/2] chipidea: Use devm_request_irq()
Hello, On Wed, Jul 31, 2013 at 02:27:08PM +0100, Mark Brown wrote: It's really only interrupts that affect most devices - if there's DMA or anything going on after the remove() then as you said earlier the driver is probably doing something wrong. Hmmm... it depends on the specific driver is converted but if the deactivation sequence - shutting down of command engine - is also handled by devm as in libata and if you have non-devres resource free in the exit path, you have the same problem. Again, in general, tearing things down in the order which isn't the reverse of allocation is a bad idea. Adhering to the order isn't that hard and will result in far less craziness in the long term. Thanks. -- tejun -- 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 4/4] USBNET: ax88179_178a: enable tso if host supports sg dma
On Wed, Jul 31, 2013 at 8:47 PM, Greg Kroah-Hartman gre...@linuxfoundation.org wrote: On Wed, Jul 31, 2013 at 06:51:49PM +0800, Ming Lei wrote: This patch enables 'can_dma_sg' flag for ax88179_178a device if the attached host controller supports building packet from discontinuous buffers(DMA SG is possible), so both frame header and skb data buffers can be passed to usb stack via urb-sg, then skb data copy can be saved. With the patch, CPU utilization decreased much in iperf test at client mode. What is much? The data is platform dependent, on one dual-core ARM A15 board at my hand, ~30~40% CPU utilization is saved with the patchset when doing 'iperf -c' test on this board. --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -1031,12 +1031,20 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) dev-mii.phy_id = 0x03; dev-mii.supports_gmii = 1; + if (dev-udev-bus-no_sg_limit) + dev-can_dma_sg = 1; I don't feel comfortable with USB drivers poking about in the USB host controller structures like this. If we really do this, please provide a function call for it to make to determine this. OK, that is fine. But even then, is this really something that we want/need to do at all? If only some xhci controller support this, we will start to see more It should be all xhci controllers support this, per xHCI spec. driver-specific changes just to handle one type of host controller. Why We already have this kind of changes, such as usbfs and mass storage driver, the two drivers support both sg list and non-sg list cases(depends on HCD). not have the USB core handle it instead and if the host controller can not do sg lists like this, fall back to a slower implementation? In the usbnet case, the driver already supports non-sg well. Actually, all current drivers should support non-sg well because urb-sg wasn't introduced for very long time. We can think it as a new feature or DMA enhancement for xHCI controller. If you mean buffer debounce for dma sg support on ehci/uhci/ohci/.., maybe we need to discuss and evaluate further. Thanks, -- Ming Lei -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: dwc3: use dev_get_platdata()
On Wed, Jul 31, 2013 at 05:34:52PM +0400, Sergei Shtylyov wrote: Hello. On 31-07-2013 10:22, Felipe Balbi wrote: Use the wrapper function for retrieving the platform_data instead of accessing dev-platform_data directly. Inspired-by: Jingoo Han jg1@samsung.com Signed-off-by: Felipe Balbi ba...@ti.com --- drivers/usb/dwc3/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index da0a4b8..aa48abd 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -350,11 +350,11 @@ static void dwc3_core_exit(struct dwc3 *dwc) static int dwc3_probe(struct platform_device *pdev) { -struct dwc3_platform_data *pdata = pdev-dev.platform_data; +struct device *dev = pdev-dev; +struct dwc3_platform_data *pdata = dev_get_platdata(dev); struct device_node *node = pdev-dev.of_node; Why not use your 'dev' variable also here? where in the device node ? Uhm, because it's not part of $subject ? :-) Anyway, it's so small change that I can do it in this commit and mention about this change, here's the new version: commit 941ea3616c747545d0278fc432fb7919b6d0d8f0 Author: Felipe Balbi ba...@ti.com Date: Wed Jul 31 09:21:25 2013 +0300 usb: dwc3: use dev_get_platdata() Use the wrapper function for retrieving the platform_data instead of accessing dev-platform_data directly. While at that also make change 'node' initialization to use the dev pointer. Inspired-by: Jingoo Han jg1@samsung.com Signed-off-by: Felipe Balbi ba...@ti.com diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index da0a4b8..3ff6f0a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -350,11 +350,11 @@ static void dwc3_core_exit(struct dwc3 *dwc) static int dwc3_probe(struct platform_device *pdev) { - struct dwc3_platform_data *pdata = pdev-dev.platform_data; - struct device_node *node = pdev-dev.of_node; + struct device *dev = pdev-dev; + struct dwc3_platform_data *pdata = dev_get_platdata(dev); + struct device_node *node = dev-of_node; struct resource *res; struct dwc3 *dwc; - struct device *dev = pdev-dev; int ret = -ENOMEM; -- balbi signature.asc Description: Digital signature
Re: [PATCH 2/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 9:27 PM, Mark Brown broo...@kernel.org wrote: On Wed, Jul 31, 2013 at 07:55:27AM -0400, Tejun Heo wrote: If you have DMA / IRQ / command engine deactivations in devm path which often is the case with full conversions, freeing any resources including DMA areas and host private data in the wrong order is a horrible idea. It's worse as it won't really be noticeable in most cases. It's really only interrupts that affect most devices - if there's DMA or anything going on after the remove() then as you said earlier the driver is probably doing something wrong. I think the main point is we should allocate managed resource which is used at interrupt handler before devm_request_irq, and all resources used at interrupt handler should be managed. If we use non-managed resource at interrupt handler, but using managed interrupt handler, things still will go wrong if there is an odd (unexpected) interrupt after we finish deactivation at removal. -- BR, Peter Chen -- 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/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 09:42:15AM -0400, Tejun Heo wrote: On Wed, Jul 31, 2013 at 02:27:08PM +0100, Mark Brown wrote: It's really only interrupts that affect most devices - if there's DMA or anything going on after the remove() then as you said earlier the driver is probably doing something wrong. Hmmm... it depends on the specific driver is converted but if the deactivation sequence - shutting down of command engine - is also handled by devm as in libata and if you have non-devres resource free in the exit path, you have the same problem. Again, in general, That's the only API I've ever heard of doing that. Everything else is just using it to do deallocation. signature.asc Description: Digital signature
Re: [PATCH 4/4] USBNET: ax88179_178a: enable tso if host supports sg dma
On Wed, 2013-07-31 at 21:50 +0800, Ming Lei wrote: In the usbnet case, the driver already supports non-sg well. Actually, all current drivers should support non-sg well because urb-sg wasn't introduced for very long time. We can think it as a new feature or DMA enhancement for xHCI controller. If you mean buffer debounce for dma sg support on ehci/uhci/ohci/.., maybe we need to discuss and evaluate further. We cannot lie to the networking layer. Either we can do sg in hardware or we cannot. This is unfortunately determined by the HC not the device on the bus. How else but from the host driver would we get the information? Regards Oliver -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: Build regressions/improvements in v3.11-rc3
My patches usb: chipidea: fix the build error with randconfig fixes chipidea problem. It has already at USB fixes for 3.11-rc4. On Tue, 30 Jul 2013, Geert Uytterhoeven wrote: JFYI, when comparing v3.11-rc3 to v3.11-rc2[3], the summaries are: - build errors: +38/-14 + arch/powerpc/kvm/book3s_emulate.c: error: 'bat' may be used uninitialized in this function [-Werror=uninitialized]: = 349:2 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_ANDCOND' undeclared (first use in this function): = 161:17, 86:16 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_AVPN' undeclared (first use in this function): = 160:17, 85:16, 192:16 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_BULK_REMOVE' undeclared (first use in this function): = 246:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_CEDE' undeclared (first use in this function): = 250:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_CPPR' undeclared (first use in this function): = 257:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_ENTER' undeclared (first use in this function): = 240:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_EOI' undeclared (first use in this function): = 258:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_EXACT' undeclared (first use in this function): = 50:6 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_IPI' undeclared (first use in this function): = 259:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_IPOLL' undeclared (first use in this function): = 260:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_NOT_FOUND' undeclared (first use in this function): = 193:27, 87:27 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_PARAMETER' undeclared (first use in this function): = 138:10 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_PROTECT' undeclared (first use in this function): = 244:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_PTEG_FULL' undeclared (first use in this function): = 54:12 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_PUT_TCE' undeclared (first use in this function): = 248:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_REMOVE' undeclared (first use in this function): = 242:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_RTAS' undeclared (first use in this function): = 265:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_SUCCESS' undeclared (first use in this function): = 67:26, 96:26, 211:26, 125:12 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_TOO_HARD' undeclared (first use in this function): = 224:12 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_XIRR' undeclared (first use in this function): = 256:7 + arch/powerpc/kvm/book3s_pr_papr.c: error: 'H_XIRR_X' undeclared (first use in this function): = 261:7 + arch/powerpc/platforms/pseries/hotplug-memory.c: error: 'SECTION_SIZE_BITS' undeclared (first use in this function): = 24:31 + mm/memory_hotplug.c: error: 'PAGES_PER_SECTION' undeclared (first use in this function): = 1630:46 + mm/memory_hotplug.c: error: implicit declaration of function '__nr_to_section' [-Werror=implicit-function-declaration]: = 1635:3 + mm/memory_hotplug.c: error: implicit declaration of function 'find_memory_block_hinted' [-Werror=implicit-function-declaration]: = 1642:3 + mm/memory_hotplug.c: error: implicit declaration of function 'pfn_to_section_nr' [-Werror=implicit-function-declaration]: = 1631:3 + mm/memory_hotplug.c: error: implicit declaration of function 'present_section_nr' [-Werror=implicit-function-declaration]: = 1632:3 powerpc-randconfig + drivers/md/dm-cache-policy-mq.c: error: conflicting types for 'remove_mapping': = 962:13 sparc-allmodconfig, not a regression (was hidden due to a sparc64/sparc32 mixup on kissb), patch submitted + error: usb_add_gadget_udc [drivers/usb/chipidea/ci_hdrc.ko] undefined!: = N/A + error: usb_del_gadget_udc [drivers/usb/chipidea/ci_hdrc.ko] undefined!: = N/A + error: usb_gadget_map_request [drivers/usb/chipidea/ci_hdrc.ko] undefined!: = N/A + error: usb_gadget_unmap_request [drivers/usb/chipidea/ci_hdrc.ko] undefined!: = N/A x86_64-randconfig [1] http://kisskb.ellerman.id.au/kisskb/head/6490/ (all 120 configs) [3] http://kisskb.ellerman.id.au/kisskb/head/6461/ (all 120 configs) Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say programmer or something like that. -- Linus Torvalds -- 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 -- 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: [PATCH 2/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 02:57:51PM +0100, Mark Brown wrote: That's the only API I've ever heard of doing that. Everything else is just using it to do deallocation. I'm not sure why or what you're trying to argue here but take a look at devm_pwm_release() for example. It calls back into low level driver free routine. Are you arguing that it'd be a good idea to release pci regions before this is complete? It's just stupid to do any differently. There's nothing to argue about. -- tejun -- 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 v13 00/14] Add tested id switch and vbus connect detect support for Chipidea
Hi Alex, any comments, now it finished 3.11-rc4, I don't want this patchset missed at 3.11. Please tell me which one is OK, and which one needs to be refined, thanks. Best regards, Peter From: linux-usb-ow...@vger.kernel.org [linux-usb-ow...@vger.kernel.org] on behalf of Peter Chen [peter.c...@freescale.com] Sent: Friday, July 26, 2013 5:18 PM To: alexander.shish...@linux.intel.com Cc: linux-usb@vger.kernel.org; linux-arm-ker...@lists.infradead.org; feste...@gmail.com; ma...@denx.de; maxime.rip...@free-electrons.com; shawn@linaro.org; ker...@pengutronix.de; m...@pengutronix.de; m.grzesc...@pengutronix.de; gre...@linuxfoundation.org; Li Frank-B20596 Subject: [PATCH v13 00/14] Add tested id switch and vbus connect detect support for Chipidea This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection. This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards. My chipidea repo: https://github.com/hzpeterchen/linux-usb.git Chagnes for v13: - Add Tested-by: Marek Vasut ma...@denx.de - [Sascha's comments]: Add return value check for devm_regulator_get. [3/14] - [Marc's comments]: Change timeout usage at hw_wait_reg. [11/14] - [Alex's comments]: Using platdata flag to indicate dual role but not OTG controller. [7/14] Changes for v12: - Rebased greg's usb-next tree (3.10.0-rc7+) - Split more small patches for single function and fix. Changes for v11: - mark ci_handle_vbus_change as static as it is only used at core.c [3/9] - Move the vbus operation for platform code to host code, as vbus operation is common operation, and host is the only user for vbus. When it is host mode, we need to open vbus, when it is out of host mode, we need to close vbus. [6/9] [8/9] - Delete the delayed work at core.c as it is not needed. [7/9] Changes for v10: - Delete [8/9] at v9, ci core's drvdata must be set for further operation. [8/8] Changes for v9: - Some small comments from Alex like: variable comment for otg event additional newline. [3/9] - Import function tell show if the controller has otg capable, if the controller supports both host and device, we think it is otg capable, and can read OTGSC. [3/9] - Merge two otg patches [v8 3/8] and [v8 4/8] to one [v9 3/9]. [3/9] - Add inline to ci_hdrc_gadget_destroy if CONFIG_USB_CHIPIDEA_UDC is not defined, it can fix one build warning defined but not used [3/9] - One comment from Felipe about changing calling gadget disconnect API at chipidea's udc driver. I move calling ci-driver-disconnect from _gadget_stop_activity to which calls _gadget_stop_activity except ci13xxx_stop, as udc core will call disconnect when do rmmod gadget. [7/9] - Add ci core probe's return value to ci's platform_data, we do this for getting core's probe's result at platform layer, and quit it if the core's probe fails. [8/9] [9/9] Changes for v8: - Add ci_supports_gadget helper to know if the controller supports gadget, if the controller supports gadget, it needs to read otgsc to know the vbus value, basically, if the controller supports gadget, it will support host as well [3/8] - At ci_hdrc_probe, it needs to add free memory at error path [3/8] - Cosolidate ci-driver = NULL at ci13xxx_stop [8/8] Changes for v7: For Patch 8/8, we only need to set ci-driver to NULL when usb cable is not connected, for other changes, it will case some runtime pm unmatch and un-align with udc-core composite driver problems. Changes for v6: - Add Alex comments for init/destroy function [3/8] [4/8] - Remove memset(ci-gadget, 0, sizeof(ci-gadget)) at destory function [4/8] - Add Kishon's comment: Change the format of struct usb_otg otg at drivers/usb/chipidea/ci.h [1/8] - Add comments for CI_VBUS_STABLE_TIMEOUT [3/8] - Change the otg_set_peripheral return value check as the fully chipidea driver users don't need it. [4/8] - Fix one bug that the oops when re-plug in usb cable after rmmod gadget [8/8] Peter Chen (14): usb: chipidea: add vbus regulator control usb: chipidea: imx: remove vbus regulator operation usb: chipidea: imx: add return value check for devm_regulator_get usb: chipidea: udc: otg_set_peripheral is useless for some chipidea users usb: chipidea: otg: Add otg file used to access otgsc usb: chipidea: Add role init and destory APIs usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG usb: chipidea: disable all interrupts and clear all interrupts status usb: chipidea: move otg relate things to otg file usb: chipidea: add vbus interrupt handler usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS usb: chipidea: udc: .pullup is valid when vbus is on at CI_HDRC_PULLUP_ON_VBUS usb:
Re: [PATCH 2/2] chipidea: Use devm_request_irq()
hello, On Wed, Jul 31, 2013 at 09:55:26PM +0800, Peter Chen wrote: I think the main point is we should allocate managed resource which is used at interrupt handler before devm_request_irq, and all resources used at interrupt handler should be managed. If we use non-managed resource at interrupt handler, but using managed interrupt handler, things still will go wrong if there is an odd (unexpected) interrupt after we finish deactivation at removal. In general, applying devm partially isn't a good idea. It's very easy to get into trouble thanks to release order dependency which isn't immediately noticeable and there have been actual bugs caused by that. The strategies which seem to work are either * Convert everything over to devm by wrapping deactivation in a devres callback too. As long as your init sequence is sane (ie. irq shouldn't be request before things used by irq are ready). * Allocate all resources using devres but shut down the execution engine in the remove_one(). Again, as all releases are controlled by devres, you won't have to worry about messing up the release sequencing. Thanks. -- tejun -- 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 v2 26/42] USB: ohci-at91: add usb_clk for transition to common clk framework
On Wed, 31 Jul 2013, boris brezillon wrote: Hello Alan, I don't know if you remember but a few days back I sent a series which included this patch (ARM: at91: prepare transition to common clk framework). It was decided to move this patch out of the prepare series to avoid backward compatility handling. Things have changed a little bit. I was asked to split the ARM: at91: move to common clk framework series into several smaller series (one for each SoC). This means at91 will have some SoCs supporting using common clk framework (and thus will define the usb_clk) and other SoCs using the old at91 clk implementation (which does not define usb_clk). I was also requested to drop common clk framework support for non dt boards, which means, as long as at91 keep non dt boards the at91 old clk implem will remain active. For all these reasons I will have to reintroduce the backward compatibility hack. Should I get this patch (and patch 27) out of the this series and back to the prepare series ? I don't care too much how the two patch series are organized, although some of the other maintainers involved in this project might. So long as everything remains compatible with all the hardware variations and bisectable at each stage, I'll be happy. 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
[PATCH 3/4] usb: chipidea: don't clobber return value of ci_role_start()
Signed-off-by: Lothar Waßmann l...@karo-electronics.de --- drivers/usb/chipidea/core.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index a5df24c..38b0a7a 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -497,7 +497,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) ret = ci_role_start(ci, ci-role); if (ret) { dev_err(dev, can't start %s role\n, ci_role(ci)-name); - ret = -ENODEV; goto rm_wq; } -- 1.7.2.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 2/4] usb: chipidea: ci_hdrc_imx: remove an unsolicited module_put() call from ci_hdrc_imx_remove()
This prevents the USB PHY refcount to be decremented below zero upon unloading the ci-hdrc-imx module. Signed-off-by: Lothar Waßmann l...@karo-electronics.de --- drivers/usb/chipidea/ci_hdrc_imx.c |4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 14362c0..802eab1 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -218,10 +218,8 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) if (data-reg_vbus) regulator_disable(data-reg_vbus); - if (data-phy) { + if (data-phy) usb_phy_shutdown(data-phy); - module_put(data-phy-dev-driver-owner); - } clk_disable_unprepare(data-clk); -- 1.7.2.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 1/4] usb: chipidea: improve kconfig 2.0
This patch provides a cleaner solution to the problem described in commit 20a677fd. The goal to be achieved is to force USB_CHIPIDEA=m if either USB_EHCI_HCD=m or USB_GADGET=m. If both are 'y' USB_CHIPIDEA may be selected to be 'm' or 'y'. The old patch had the drawback, that USB_CHIPIDEA could be chosen as 'y' though USB_EHCI_HCD or USB_GADGET (or both) were 'm' leading to a situation where USB_CHIPIDEA_HOST or USB_CHIPIDEA_UDC vanished from the config options producing a compilable but dysfunctional driver. Signed-off-by: Lothar Waßmann l...@karo-electronics.de --- drivers/usb/chipidea/Kconfig |7 +++ 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index d1bd8ef..4a851e1 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig @@ -1,6 +1,6 @@ config USB_CHIPIDEA tristate ChipIdea Highspeed Dual Role Controller - depends on USB || USB_GADGET + depends on (USB_EHCI_HCD USB_GADGET) || (USB_EHCI_HCD !USB_GADGET) || (!USB_EHCI_HCD USB_GADGET) help Say Y here if your system has a dual role high speed USB controller based on ChipIdea silicon IP. Currently, only the @@ -12,15 +12,14 @@ if USB_CHIPIDEA config USB_CHIPIDEA_UDC bool ChipIdea device controller - depends on USB_GADGET=y || (USB_CHIPIDEA=m USB_GADGET=m) + depends on USB_GADGET help Say Y here to enable device controller functionality of the ChipIdea driver. config USB_CHIPIDEA_HOST bool ChipIdea host controller - depends on USB=y - depends on USB_EHCI_HCD=y || (USB_CHIPIDEA=m USB_EHCI_HCD=m) + depends on USB_EHCI_HCD select USB_EHCI_ROOT_HUB_TT help Say Y here to enable host controller functionality of the -- 1.7.2.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: USB Interrupt Transaction Scheduling
On Tue, 30 Jul 2013, Stoddard, Nate (GE Healthcare) wrote: The driver has to set up the data structures for the transfers, which includes scheduling when the SSPLIT and CSPLIT transactions will occur and figuring out how much bandwidth they will consume. The transactions themselves are handled entirely by the EHCI hardware. So you would expect a temporary CPU increase when a device is connected or reset since the scheduler will need to set up when the packets will be transferred. Once this is complete, the CPU should return to a lower amount as the EHCI hardware would be processing the various packet sending: setup tokens, ACK/NAK handshaking, and split packets? It's obvious that connecting or resetting a device forces the CPU to do extra work. That's always true, no matter what the device is used for. When the device is in use, the CPU activity will be higher than when the device isn't in use (other things being equal). That's also true for all devices. So I'm not sure what you're trying to get at, here. I ask because we are seeing much higher constant CPU usage on our target hardware (iMX535) than we are seeing on the test PC. Do you have any recommendations for a good way to confirm the target EHCI hardware is being utilized? Is there a location to instrument in one of the ehci host files (ehci-hcd.c or ehci-q.c)? I don't know anything about the iMX535, although there may be other people on this mailing list who do. The amount of work done by ehci-hcd should be more or less the same across all platforms. Of course, some platforms will perform that work more quickly than others. It's possible that the iMX535 really does take much longer to do the same amount of work, eating up a larger fraction of the total CPU time. It's easy to confirm that the EHCI hardware is being utilized: If your test program works and the data is transferred as expected, then the hardware is working. I don't see how you could have gotten more than 15 interrupt endpoints running at the same time unless the endpoints' bInterval value was larger than 1. On all 7 devices, the IN and OUT interrupt endpoints have bInterval = 1 wMaxPacketSize = 64. Do you think this is worth pursuing? It sounds like a bug, although it might not be. We will re-run the tests with more rigor to confirm the results. I will post the details. Okay. 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: [PATCH v2] usb: core: don't try to reset_device() a port that got just disconnected
On Tue, 30 Jul 2013, Julius Werner wrote: The USB hub driver's event handler contains a check to catch SuperSpeed devices that transitioned into the SS.Inactive state and tries to fix them with a reset. It decides whether to do a plain hub port reset or call the usb_reset_device() function based on whether there was a device attached to the port. However, there are device/hub combinations (found with a JetFlash Transcend mass storage stick (8564:1000) on the root hub of an Intel LynxPoint PCH) which can transition to the SS.Inactive state on disconnect (and stay there long enough for the host to notice). In this case, above-mentioned reset check will call usb_reset_device() on the stale device data structure. The kernel will send pointless LPM control messages to the no longer connected device address and can even cause several 5 second khubd stalls on some (buggy?) host controllers, before finally accepting the device's fate amongst a flurry of error messages. This patch makes the choice of reset dependent on the port status that has just been read from the hub in addition to the existence of an in-kernel data structure for the device, and only proceeds with the more extensive reset if both are valid. Signed-off-by: Julius Werner jwer...@chromium.org --- drivers/usb/core/hub.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 4a8a1d6..558313d 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4798,7 +4798,8 @@ static void hub_events(void) hub-ports[i - 1]-child; dev_dbg(hub_dev, warm reset port %d\n, i); - if (!udev) { + if (!udev || !(portstatus + USB_PORT_STAT_CONNECTION)) { status = hub_port_reset(hub, i, NULL, HUB_BH_RESET_TIME, true); @@ -4808,8 +4809,8 @@ static void hub_events(void) usb_lock_device(udev); status = usb_reset_device(udev); usb_unlock_device(udev); + connect_change = 0; } - connect_change = 0; } if (connect_change) This version looks better. Acked-by: Alan Stern st...@rowland.harvard.edu -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: core: don't try to reset_device() a port that got just disconnected
On Tue, 30 Jul 2013, Julius Werner wrote: Wait a moment. Why does each of these attempts lead to a 5-second timeout? Why don't they fail immediately? Now that you mention it, that's a very good question. I have brought this up with Sarah on more than one occasion, but we never found a good answer. The effects are quite visible when somebody unplugs a USB-3 disk drive in the middle of a data transfer. The kernel enqueues a control transfer to the now disconnected address because it's internal bookkeeping is not yet updated, but I guess that should usually fail very fast from an xHC-internal transaction timeout. I have now tried to debug the cause of this: I see the transfer being enqueued and the doorbell triggered, but never get a transfer event back from it (until the software timeout calls usb_kill_urb() which stops the endpoint). With the same setup on a PantherPoint system I get the same U1/U2 disable control messages on unplugging, but they fail within 5ms with a transaction error... so I guess this must be a LynxPoint hardware bug. An odd sort of bug. You'd think that not getting a response back would be one of the first types of error the hardware designers would check for. Regardless, calling usb_reset_device() is still wrong and will at least lead to pointless transfer attempts and error messages, so I think my patch still has merit. What will happen here if udev is NULL? Maybe you should change the test to (!udev || !(portstatus ...)). Right... I'm not sure if that can happen in practice, but I'll change it just in case. Somebody said that in theory, ports can put themselves in the Disabled state at any time, spontaneously. If this happened just after a device was attached, you would end up with udev being NULL and the connect status being set. 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: Kernel 3.10.3 reset SuperSpeed USB device number 2 using xhci_hcd
On Tue, 30 Jul 2013, Martin K. Petersen wrote: James? [PATCH] SCSI: Don't attempt to send extended INQUIRY command if skip_vpd_pages is set If a device has the skip_vpd_pages flag set we should simply fail the scsi_get_vpd_page() call. Signed-off-by: Martin K. Petersen martin.peter...@oracle.com Acked-by: Alan Stern st...@rowland.harvard.edu Tested-by: Stuart Foster smf.li...@ntlworld.com Cc: sta...@vger.kernel.org diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 3b1ea34..eaa808e 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -1031,6 +1031,9 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, { int i, result; + if (sdev-skip_vpd_pages) + goto fail; + /* Ask for all the pages supported by this device */ result = scsi_vpd_inquiry(sdev, buf, 0, buf_len); if (result) Thanks, Martin. 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: Ejected Nook (usb mass storage) prevents suspend
On Wed, 31 Jul 2013, Oliver Neukum wrote: These errors should be handled cleanly. How about this patch? From 76a377d9894dc8945e9afecc7f9864e6dc3156b1 Mon Sep 17 00:00:00 2001 From: Oliver Neukum oneu...@suse.de Date: Wed, 31 Jul 2013 13:32:51 +0200 Subject: [PATCH] sd: handle errors during suspend Errors during suspend must be handled according to reasons You forgot to complete this sentence. Errors due to missing media or unplugged devices must be ignored. The error returns must be modified so that the generic layer understands them. The patch contains a couple of trivial whitespace errors (space added to the end of a line, or spaces used instead of a tab). More importantly, if we already know that the medium is not present or has been changed since it was last used, then there's no reason to call sd_sync_cache() at all. 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: [PATCH 4/4] USBNET: ax88179_178a: enable tso if host supports sg dma
On Wed, 2013-07-31 at 16:02 +0200, Oliver Neukum wrote: On Wed, 2013-07-31 at 21:50 +0800, Ming Lei wrote: In the usbnet case, the driver already supports non-sg well. Actually, all current drivers should support non-sg well because urb-sg wasn't introduced for very long time. We can think it as a new feature or DMA enhancement for xHCI controller. If you mean buffer debounce for dma sg support on ehci/uhci/ohci/.., maybe we need to discuss and evaluate further. We cannot lie to the networking layer. Either we can do sg in hardware or we cannot. This is unfortunately determined by the HC not the device on the bus. How else but from the host driver would we get the information? Hmm, I would rather make sure SG is really supported before adding TSO support. TCP stack can build skb with fragments of any size, not multiple of 512 or 1024 bytes. commit 20f0170377264e8449b6987041f0bcc4d746d3ed usbnet: do not pretend to support SG/TSO usbnet doesn't support yet SG, so drivers should not advertise SG or TSO capabilities, as they allow TCP stack to build large TSO packets that need to be linearized and might use order-5 pages. This adds an extra copy overhead and possible allocation failures. Current code ignore skb_linearize() return code so crashes are even possible. Best is to not pretend SG/TSO is supported, and add this again when/if usbnet really supports SG for devices who could get a performance gain. -- 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/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 10:07:58AM -0400, Tejun Heo wrote: On Wed, Jul 31, 2013 at 02:57:51PM +0100, Mark Brown wrote: That's the only API I've ever heard of doing that. Everything else is just using it to do deallocation. I'm not sure why or what you're trying to argue here but take a look at devm_pwm_release() for example. It calls back into low level driver free routine. Are you arguing that it'd be a good idea to That the callback is into the driver providing the PWM, not into the driver that's using the PWM and is releasing it. release pci regions before this is complete? It's just stupid to do any differently. There's nothing to argue about. What I'm saying is that in essentially all the users I've seen devm is only being used for things like kfree() or clk_put() which aren't really connected in any way and can happen in any order. This (coupled with the lack of documentation that this is supported) is why people are nervous about anything that relies on ordering with this stuff - aside from ATA everything is just using this for straight frees. signature.asc Description: Digital signature
Re: [PATCH 4/4] USBNET: ax88179_178a: enable tso if host supports sg dma
On Wed, Jul 31, 2013 at 11:15 PM, Eric Dumazet eric.duma...@gmail.com wrote: On Wed, 2013-07-31 at 16:02 +0200, Oliver Neukum wrote: On Wed, 2013-07-31 at 21:50 +0800, Ming Lei wrote: In the usbnet case, the driver already supports non-sg well. Actually, all current drivers should support non-sg well because urb-sg wasn't introduced for very long time. We can think it as a new feature or DMA enhancement for xHCI controller. If you mean buffer debounce for dma sg support on ehci/uhci/ohci/.., maybe we need to discuss and evaluate further. We cannot lie to the networking layer. Either we can do sg in hardware or we cannot. This is unfortunately determined by the HC not the device on the bus. How else but from the host driver would we get the information? Hmm, I would rather make sure SG is really supported before adding TSO support. TCP stack can build skb with fragments of any size, not multiple of 512 or 1024 bytes. For this SG buffer, only xHCI USB host controller supports it, and other host controllers can't support it if they don't use bounce buffer, but usbnet devices may be connected to all these host controllers. This patchset only enables SG/TSO support when ax88179_178a device connects to xHCI host controller. Thanks, -- Ming Lei -- 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/2] chipidea: Use devm_request_irq()
On Wed, Jul 31, 2013 at 04:25:23PM +0100, Mark Brown wrote: What I'm saying is that in essentially all the users I've seen devm is only being used for things like kfree() or clk_put() which aren't really connected in any way and can happen in any order. This (coupled with the lack of documentation that this is supported) is why people are nervous about anything that relies on ordering with this stuff - aside from ATA everything is just using this for straight frees. Yeah, sure, thank you very much for your input. It is of course strictly ordered and the documentation needs to be updated. -- tejun -- 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 0/4] USB USBNET: loose DMA SG check and support usbnet DMA SG
On Wed, 2013-07-31 at 18:51 +0800, Ming Lei wrote: Hi, This patchset allows drivers to pass sg buffers which size can't be divided by max packet size of endpoint if the host controllers support this kind of sg buffers. Previously we add check[1] on the situation and don't allow these sg buffers passed to USB HCD, looks the check is too strict because some applications(such as network stack) can't provide this sg buffers which size can be divided by max packet size, so this patch looses the check in case that the host controllers support it. Also patch 3/4 implements DMA SG on usbnet driver, and patch 4/4 enables it on ax88179_178a USB3 NIC, so CPU utilization can be decreased much with usbnet DMA SG when the USB3 NIC is attached to xHCI controller. This looks very promising to me, thanks a lot for doing this Ming. -- 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: Audio I/O parameters
On Tue, 30 Jul 2013, Alan Stern wrote: I can try to ameliorate the situation. Although the 7-ms delay will inevitably cause an underrun, it doesn't have to cause errors the way it does now. I'll write a patch to handle this. It may take a few days. James, see what happens with this patch. It will print a warning message in the system log every time it detects an underrun, but it won't cause an URB submission failure any more. Alan Stern Index: usb-3.11/drivers/usb/host/ehci-sched.c === --- usb-3.11.orig/drivers/usb/host/ehci-sched.c +++ usb-3.11/drivers/usb/host/ehci-sched.c @@ -1391,21 +1391,20 @@ iso_stream_schedule ( /* Behind the scheduling threshold? */ if (unlikely(start next)) { + unsigned now2 = (now - base) (mod - 1); /* USB_ISO_ASAP: Round up to the first available slot */ if (urb-transfer_flags URB_ISO_ASAP) start += (next - start + period - 1) -period; /* -* Not ASAP: Use the next slot in the stream. If -* the entire URB falls before the threshold, fail. +* Not ASAP: Use the next slot in the stream, +* no matter what. */ - else if (start + span - period next) { - ehci_dbg(ehci, iso urb late %p (%u+%u %u)\n, + else if (start + span - period now2) { + ehci_warn(ehci, iso underrun %p (%u+%u %u)\n, urb, start + base, - span - period, next + base); - status = -EXDEV; - goto fail; + span - period, now2 + base); } } -- 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 usbnet: mcs7830: apply usbnet_link_change
On Wed, Jul 31, 2013 at 5:56 PM, Till Schmalmack t...@schmalmack.net wrote: Hello Ming, I am experiencing issues with the usbnet commits you did for the 3.10 kernel, in particular with 4be74c13 usbnet: mcs7830: apply usbnet_link_change I filed this bug https://bugzilla.kernel.org/show_bug.cgi?id=60662 Thanks for the report. Looks you didn't provide any debug info, could you apply the attachment patch and post the 'dmesg' info when you reproduce the bug. Thanks, -- Ming Lei usbnet-link-dgb.patch Description: Binary data