Re: [PATCH] Fixing style warnings.
On 03/03/2015 06:19 AM, cfredric wrote: Signed-off-by: cfredric chris.p.fredrick...@gmail.com You could use your full name here. --- drivers/usb/core/buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 506b969..89f2e77 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c @@ -70,7 +70,7 @@ int hcd_buffer_create(struct usb_hcd *hcd) size = pool_max[i]; if (!size) continue; - snprintf(name, sizeof name, buffer-%d, size); + snprintf(name, sizeof(name), buffer-%d, size); This looks like checkpactch warning you fixed. You could add something to the patch description that says so. hcd-pool[i] = dma_pool_create(name, hcd-self.controller, size, size, 0); if (!hcd-pool[i]) { @@ -95,6 +95,7 @@ void hcd_buffer_destroy(struct usb_hcd *hcd) for (i = 0; i HCD_BUFFER_POOLS; i++) { struct dma_pool *pool = hcd-pool[i]; + This looks unrelated. if (pool) { dma_pool_destroy(pool); hcd-pool[i] = NULL; Sebastian -- 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/1] usb: chipidea: use hrtimer for otg fsm timers
On Mon, Mar 02, 2015 at 01:25:48PM +0800, Li Jun wrote: From: Li Jun b47...@freescale.com Current otg fsm timers are using controller 1ms irq and count it, this patch is to replace it with hrtimer solution, use one hrtimer for all otg timers. Signed-off-by: Li Jun jun...@freescale.com Change for v3: - clean up the definitions for original timer solution: ci_otg_fsm_timer and ci_otg_fsm_timer_list in usb/chipidea/otg_fsm.h. Changes for v2: - change enabled_otg_timers to be enabled_otg_timer_bits. - Remove duplicated OTG 1MSIE disable in usb otg fsm init. --- drivers/usb/chipidea/ci.h | 10 +- drivers/usb/chipidea/otg_fsm.c | 364 drivers/usb/chipidea/otg_fsm.h | 13 -- 3 files changed, 190 insertions(+), 197 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index c09381d..aeec5f0 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -162,7 +162,10 @@ struct hw_bank { * @role: current role * @is_otg: if the device is otg-capable * @fsm: otg finite state machine - * @fsm_timer: pointer to timer list of otg fsm + * @otg_fsm_hrtimer: hrtimer for otg fsm timers + * @hr_timeouts: time out list for active otg fsm timers + * @enabled_otg_timer_bits: bits of enabled otg timers + * @next_otg_timer: next nearest enabled timer to be expired * @work: work for role changing * @wq: workqueue thread * @qh_pool: allocation pool for queue heads @@ -205,7 +208,10 @@ struct ci_hdrc { boolis_otg; struct usb_otg otg; struct otg_fsm fsm; - struct ci_otg_fsm_timer_list*fsm_timer; + struct hrtimer otg_fsm_hrtimer; + ktime_t hr_timeouts[NUM_OTG_FSM_TIMERS]; + unsignedenabled_otg_timer_bits; + enum otg_fsm_timer next_otg_timer; struct work_struct work; struct workqueue_struct *wq; diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index ba2cb91..083acf4 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -30,22 +30,6 @@ #include otg.h #include otg_fsm.h -static struct ci_otg_fsm_timer *otg_timer_initializer -(struct ci_hdrc *ci, void (*function)(void *, unsigned long), - unsigned long expires, unsigned long data) -{ - struct ci_otg_fsm_timer *timer; - - timer = devm_kzalloc(ci-dev, sizeof(struct ci_otg_fsm_timer), - GFP_KERNEL); - if (!timer) - return NULL; - timer-function = function; - timer-expires = expires; - timer-data = data; - return timer; -} - /* Add for otg: interact with user space app */ static ssize_t get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) @@ -204,36 +188,48 @@ static struct attribute_group inputs_attr_group = { }; /* + * Keep this list in the same order as timers indexed + * by enum otg_fsm_timer in include/linux/usb/otg-fsm.h + */ +static unsigned otg_timer_ms[] = { + TA_WAIT_VRISE, + TA_WAIT_VFALL, + TA_WAIT_BCON, + TA_AIDL_BDIS, + TB_ASE0_BRST, + TA_BIDL_ADIS, + TB_SE0_SRP, + TB_SRP_FAIL, + 0, + TB_DATA_PLS, + TB_SSEND_SRP, +}; + +/* * Add timer to active timer list */ static void ci_otg_add_timer(struct ci_hdrc *ci, enum otg_fsm_timer t) { - struct ci_otg_fsm_timer *tmp_timer; - struct ci_otg_fsm_timer *timer = ci-fsm_timer-timer_list[t]; - struct list_head *active_timers = ci-fsm_timer-active_timers; + unsigned long flags, timer_sec, timer_nsec; if (t = NUM_OTG_FSM_TIMERS) return; - /* - * Check if the timer is already in the active list, - * if so update timer count - */ - list_for_each_entry(tmp_timer, active_timers, list) - if (tmp_timer == timer) { - timer-count = timer-expires; - return; - } - - if (list_empty(active_timers)) - pm_runtime_get(ci-dev); - - timer-count = timer-expires; - list_add_tail(timer-list, active_timers); - - /* Enable 1ms irq */ - if (!(hw_read_otgsc(ci, OTGSC_1MSIE))) - hw_write_otgsc(ci, OTGSC_1MSIE, OTGSC_1MSIE); + spin_lock_irqsave(ci-lock, flags); + timer_sec = otg_timer_ms[t] / MSEC_PER_SEC; + timer_nsec = (otg_timer_ms[t] % MSEC_PER_SEC) * NSEC_PER_MSEC; + ci-hr_timeouts[t] = ktime_add(ktime_get(), + ktime_set(timer_sec, timer_nsec)); + ci-enabled_otg_timer_bits |= (1 t); + if ((ci-next_otg_timer == NUM_OTG_FSM_TIMERS) || + (ci-hr_timeouts[ci-next_otg_timer].tv64 +
Re: [PATCH 0/8] ARM OMAP2+ GPMC: fixes and bus children
Robert, On 26/02/15 16:45, Robert ABEL wrote: These are the changes I proposed in three separate patchsets #([1], [2], [3]) rebased to 3.19 as well as new changes for little bugs I noticed while preparing this patchset. 1. DEBUG was undefined in source code -- remove offending lines 2. add capability to have busses as children of the GPMC and multiple devices on a bus. See [2] for an example DTS syntax. 3. debug output was unaligned -- align it 4. output for copy-pasting to DTS had erroneous timing outputs and made it hard to copy-paste -- correct timing values, add comments as DTS comments. 5. WAITMONITORINGTIME is expressed as GPMC_CLK cycles for all accesses. GPMCFCLKDIVIDER is used as a divider, so it must always be programmed. 6. GPMCFCLKDIVIDER is calculated according to WAITMONITORINGTIME for asynchronous accesses inside the driver -- asynchronous accesses now completely decoupled from gpmc,sync-clk-ps. 7. WAITMONITORINGTIME was being programmed/shown in GPMC_FCLK cycles instead of GPMC_CLK cycles -- add clock domain information where necessary. 8. Calculated values for WAITMONITORINGTIME and CLKACTIVATIONTIME that were outside the defined range would not raise an error. DEVICESIZE, ATTACHEDDEVICEPAGELENGTH, WAITMONITORINGTIME and CLKACTIVATIONTIME would not be marked as incorrect on DTS output. -- Fix all of these. [1]: https://lkml.org/lkml/2015/2/12/495 [2]: https://lkml.org/lkml/2015/2/16/337 [3]: https://lkml.org/lkml/2015/2/24/609 I'm OK with this version. Tony, after you ACK these I will queue them for v4.1. cheers, -roger Robert ABEL (9): ARM OMAP2+ GPMC: don't undef DEBUG ARM OMAP2+ GPMC: add bus children ARM OMAP2+ GPMC: fix debug output alignment ARM OMAP2+ GPMC: change get_gpmc_timing_reg output for DTS ARM OMAP2+ GPMC: always program GPMCFCLKDIVIDER ARM OMAP2+ GPMC: calculate GPMCFCLKDIVIDER based on WAITMONITORINGTIME ARM OMAP2+ GPMC: fix WAITMONITORINGTIME divider bug ARM OMAP2+ GPMC: fix programming/showing reserved timing parameters arch/arm/mach-omap2/gpmc-nand.c| 17 +- arch/arm/mach-omap2/gpmc-onenand.c | 4 +- arch/arm/mach-omap2/usb-tusb6010.c | 4 +- drivers/memory/Makefile| 2 + drivers/memory/omap-gpmc.c | 313 + include/linux/omap-gpmc.h | 2 +- 6 files changed, 265 insertions(+), 77 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
Re: Reg : USB modeswitch details LE920 Module
Hi Arulpandiyan, 2015-03-03 13:05 GMT+01:00 Arul pandiyan arulcse2...@gmail.com: Hi Vaibhav We are using Telit LE920 module for 3G/LTE support in our module. Our configuration is as follows, Processor- imx6 -Q7 Operating system- Jelly Bean Kernel Version - 3.0.35 We have found that our module id is detected as 1201. we have updated the same in option.c and it is detecting as storage device. I came to know from internet, i should get the interface like wwan0 once i done the usb_modeswitch, but the problem is, We are not aware about the target_device list and usb_mode_switch.conf details. Could you please help us to configure this module. DefaultVendor= 0x1bc7 DefaultProduct=0x:1201 TargetVendor=0x1bc7 TargetProductList= CheckSuccess=20 MessageEndpoint= 0x01 MessageContent=55534243123456780011062001 Note : a) It does create the /dev/ttyUSB0 - /dev/ttyUSB4 devices in the virtual filesystem. b) I have added the patch 03eb466f276ceef9dcf023dc5474db02af68aad9I, Should i do anything apart from this patch to bring up Telit LE920 module There should be no need to use usb_modeswitch: attached you can find LE920 0x1201 PID default composition. USB serial ports support in option is present since official kernel version 3.18. QMI network adapter support in qmi_wwan is present since official kernel version 3.13. Please note: it is useful to contact the modem vendor for this kind of issues especially if you use old kernel versions such as 3.0.35. Also please remember to keep cc'ed the USB mailing list. Regards, Daniele -- 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/8] ARM OMAP2+ GPMC: fixes and bus children
Robert, On 26/02/15 16:45, Robert ABEL wrote: These are the changes I proposed in three separate patchsets #([1], [2], [3]) rebased to 3.19 as well as new changes for little bugs I noticed while preparing this patchset. 1. DEBUG was undefined in source code -- remove offending lines 2. add capability to have busses as children of the GPMC and multiple devices on a bus. See [2] for an example DTS syntax. 3. debug output was unaligned -- align it 4. output for copy-pasting to DTS had erroneous timing outputs and made it hard to copy-paste -- correct timing values, add comments as DTS comments. 5. WAITMONITORINGTIME is expressed as GPMC_CLK cycles for all accesses. GPMCFCLKDIVIDER is used as a divider, so it must always be programmed. 6. GPMCFCLKDIVIDER is calculated according to WAITMONITORINGTIME for asynchronous accesses inside the driver -- asynchronous accesses now completely decoupled from gpmc,sync-clk-ps. 7. WAITMONITORINGTIME was being programmed/shown in GPMC_FCLK cycles instead of GPMC_CLK cycles -- add clock domain information where necessary. 8. Calculated values for WAITMONITORINGTIME and CLKACTIVATIONTIME that were outside the defined range would not raise an error. DEVICESIZE, ATTACHEDDEVICEPAGELENGTH, WAITMONITORINGTIME and CLKACTIVATIONTIME would not be marked as incorrect on DTS output. -- Fix all of these. [1]: https://lkml.org/lkml/2015/2/12/495 [2]: https://lkml.org/lkml/2015/2/16/337 [3]: https://lkml.org/lkml/2015/2/24/609 I'm OK with this version. Tony, after you ACK these I will queue them for v4.1. cheers, -roger Robert ABEL (9): ARM OMAP2+ GPMC: don't undef DEBUG ARM OMAP2+ GPMC: add bus children ARM OMAP2+ GPMC: fix debug output alignment ARM OMAP2+ GPMC: change get_gpmc_timing_reg output for DTS ARM OMAP2+ GPMC: always program GPMCFCLKDIVIDER ARM OMAP2+ GPMC: calculate GPMCFCLKDIVIDER based on WAITMONITORINGTIME ARM OMAP2+ GPMC: fix WAITMONITORINGTIME divider bug ARM OMAP2+ GPMC: fix programming/showing reserved timing parameters arch/arm/mach-omap2/gpmc-nand.c| 17 +- arch/arm/mach-omap2/gpmc-onenand.c | 4 +- arch/arm/mach-omap2/usb-tusb6010.c | 4 +- drivers/memory/Makefile| 2 + drivers/memory/omap-gpmc.c | 313 + include/linux/omap-gpmc.h | 2 +- 6 files changed, 265 insertions(+), 77 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
Re: gadgetfs broken since 7f7f25e8
On Tue, 3 Mar 2015, Al Viro wrote: Looking at that thing again... why do they need to be dummy? After all, those methods start with get_ready_ep(), which will fail unless we have -state == STATE_EP_ENABLED. So they'd be failing just fine until that first write() anyway. Let's do the following: In addition to the changes you made, it looks like you will need the following or something similar (also untested). I'm not sure if this is race-free, but it's better than before. Alan Stern Index: usb-3.19/drivers/usb/gadget/legacy/inode.c === --- usb-3.19.orig/drivers/usb/gadget/legacy/inode.c +++ usb-3.19/drivers/usb/gadget/legacy/inode.c @@ -987,6 +987,10 @@ ep0_read (struct file *fd, char __user * enum ep0_state state; spin_lock_irq (dev-lock); + if (dev-state = STATE_DEV_OPENED) { + retval = -ENODEV; + goto done; + } /* report fd mode change before acting on it */ if (dev-setup_abort) { @@ -1185,8 +1189,6 @@ ep0_write (struct file *fd, const char _ struct dev_data *dev = fd-private_data; ssize_t retval = -ESRCH; - spin_lock_irq (dev-lock); - /* report fd mode change before acting on it */ if (dev-setup_abort) { dev-setup_abort = 0; @@ -1232,7 +1234,6 @@ ep0_write (struct file *fd, const char _ } else DBG (dev, fail %s, state %d\n, __func__, dev-state); - spin_unlock_irq (dev-lock); return retval; } @@ -1240,6 +1241,10 @@ static int ep0_fasync (int f, struct file *fd, int on) { struct dev_data *dev = fd-private_data; + + if (dev-state = STATE_DEV_OPENED) + return -ENODEV; + // caller must F_SETOWN before signal delivery happens VDEBUG (dev, %s %s\n, __func__, on ? on : off); return fasync_helper (f, fd, on, dev-fasync); @@ -1279,6 +1284,9 @@ ep0_poll (struct file *fd, poll_table *w struct dev_data *dev = fd-private_data; int mask = 0; + if (dev-state = STATE_DEV_OPENED) + return -ENODEV; + poll_wait(fd, dev-wait, wait); spin_lock_irq (dev-lock); @@ -1314,19 +1322,6 @@ static long dev_ioctl (struct file *fd, return ret; } -/* used after device configuration */ -static const struct file_operations ep0_io_operations = { - .owner =THIS_MODULE, - .llseek = no_llseek, - - .read = ep0_read, - .write =ep0_write, - .fasync = ep0_fasync, - .poll = ep0_poll, - .unlocked_ioctl = dev_ioctl, - .release = dev_release, -}; - /*--*/ /* The in-kernel gadget driver handles most ep0 issues, in particular @@ -1850,6 +1845,14 @@ dev_config (struct file *fd, const char u32 tag; char*kbuf; + spin_lock_irq(dev-lock); + if (dev-state STATE_DEV_OPENED) { + value = ep0_write(fd, buf, len, ptr); + spin_unlock_irq(dev-lock); + return value; + } + spin_unlock_irq(dev-lock); + if (len (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) return -EINVAL; @@ -1923,7 +1926,6 @@ dev_config (struct file *fd, const char * on, they can work ... except in cleanup paths that * kick in after the ep0 descriptor is closed. */ - fd-f_op = ep0_io_operations; value = len; } return value; @@ -1954,12 +1956,14 @@ dev_open (struct inode *inode, struct fi return value; } -static const struct file_operations dev_init_operations = { +static const struct file_operations ep0_operations = { .llseek = no_llseek, .open = dev_open, + .read = ep0_read, .write =dev_config, .fasync = ep0_fasync, + .poll = ep0_poll, .unlocked_ioctl = dev_ioctl, .release = dev_release, }; @@ -2075,7 +2079,7 @@ gadgetfs_fill_super (struct super_block goto Enomem; dev-sb = sb; - dev-dentry = gadgetfs_create_file(sb, CHIP, dev, dev_init_operations); + dev-dentry = gadgetfs_create_file(sb, CHIP, dev, ep0_operations); if (!dev-dentry) { put_dev(dev); goto Enomem; -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5] xhci: fix reporting of 0-sized URBs in control endpoint
On 02.03.2015 16:58, Aleksander Morgado wrote: When a control transfer has a short data stage, the xHCI controller generates two transfer events: a COMP_SHORT_TX event that specifies the untransferred amount, and a COMP_SUCCESS event. But when the data stage is not short, only the COMP_SUCCESS event occurs. Therefore, xhci-hcd must set urb-actual_length to urb-transfer_buffer_length while processing the COMP_SUCCESS event, unless urb-actual_length was set already by a previous COMP_SHORT_TX event. The driver checks this by seeing whether urb-actual_length == 0, but this alone is the wrong test, as it is entirely possible for a short transfer to have an urb-actual_length = 0. This patch changes the xhci driver to rely on a new td-urb_length_set flag, which is set to true when a COMP_SHORT_TX event is received and the URB length updated at that stage. This fixes a bug which affected the HSO plugin, which relies on URBs with urb-actual_length == 0 to halt re-submitting the RX URB in the control endpoint. Signed-off-by: Aleksander Morgado aleksan...@aleksander.es --- Hey Mathias, This v5 of the patch takes into account the possibility of needing to return -EREMOTEIO if URB_SHORT_NOT_OK was requested in the transfer flags. With this change we no longer check for having a value in urb-actual_length, instead we just use the new flag and therefore we treat in the same way all cases where we got a SHORT_TX event (including those were the transfer was 0). Also changed the length of the comment lines to avoid going off 80chars per line. Let me know what you think. Looks good, thanks I'll add it to my queue -Mathias -- 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] udc: gadget: atmel_usba_udc: depend on COMMON_CLK_AT91
Hi Alexandre, On Tue, 3 Mar 2015 08:42:47 +0100 Alexandre Belloni alexandre.bell...@free-electrons.com wrote: Since the addition of the errata handling for at91sam9rl and at91sam9g45, the atmel_usba_udc depends on the pmc driver being present. Explicitly set that dependency. Signed-off-by: Alexandre Belloni alexandre.bell...@free-electrons.com --- drivers/usb/gadget/udc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 9a3a6b00391a..b04206fdba11 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -55,7 +55,7 @@ config USB_LPC32XX config USB_ATMEL_USBA tristate Atmel USBA - depends on AVR32 || ARCH_AT91 + depends on AVR32 || ARCH_AT91 COMMON_CLK_AT91 I guess you should add parenthesis to make it clearer ? depends on AVR32 || (ARCH_AT91 COMMON_CLK_AT91) And I wonder why you need that. I though this option was selected by all at91 platforms ? Regards, Boris -- Boris Brezillon, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com -- 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
[PATCHv3 07/29] usb: gadget: printer: eliminate pdev member of struct printer_dev
The pdev member of struct printer_dev is not used outside printer_bind_config(), so it can just as well be a local variable there. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index bbcd6aa..a9c3e57 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -83,7 +83,6 @@ struct printer_dev { u8 printer_status; u8 reset_printer; struct cdev printer_cdev; - struct device *pdev; u8 printer_cdev_open; wait_queue_head_t wait; struct usb_function function; @@ -1175,6 +1174,7 @@ static int __init printer_bind_config(struct usb_configuration *c) { struct usb_gadget *gadget = c-cdev-gadget; struct printer_dev *dev; + struct device *pdev; int status = -ENOMEM; size_t len; u32 i; @@ -1199,11 +1199,11 @@ static int __init printer_bind_config(struct usb_configuration *c) return status; /* Setup the sysfs files for the printer gadget. */ - dev-pdev = device_create(usb_gadget_class, NULL, g_printer_devno, + pdev = device_create(usb_gadget_class, NULL, g_printer_devno, NULL, g_printer); - if (IS_ERR(dev-pdev)) { + if (IS_ERR(pdev)) { ERROR(dev, Failed to create device: g_printer\n); - status = PTR_ERR(dev-pdev); + status = PTR_ERR(pdev); goto fail; } -- 1.9.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
[PATCHv3 27/29] usb: gadget: f_printer: remove compatibility layer
There are no old interface users left, so it can be removed. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/function/f_printer.c | 113 1 file changed, 113 deletions(-) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 93f4d4e..7afe17d 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -57,10 +57,8 @@ static int major, minors; static struct class *usb_gadget_class; -#ifndef USBF_PRINTER_INCLUDED static DEFINE_IDA(printer_ida); static DEFINE_MUTEX(printer_ida_lock); /* protects access do printer_ida */ -#endif /*-*/ @@ -1118,53 +1116,6 @@ fail_tx_reqs: } -#ifdef USBF_PRINTER_INCLUDED -static void printer_func_unbind(struct usb_configuration *c, - struct usb_function *f) -{ - struct printer_dev *dev; - struct usb_request *req; - - dev = func_to_printer(f); - - device_destroy(usb_gadget_class, MKDEV(major, dev-minor)); - - /* Remove Character Device */ - cdev_del(dev-printer_cdev); - - /* we must already have been disconnected ... no i/o may be active */ - WARN_ON(!list_empty(dev-tx_reqs_active)); - WARN_ON(!list_empty(dev-rx_reqs_active)); - - /* Free all memory for this driver. */ - while (!list_empty(dev-tx_reqs)) { - req = container_of(dev-tx_reqs.next, struct usb_request, - list); - list_del(req-list); - printer_req_free(dev-in_ep, req); - } - - if (dev-current_rx_req != NULL) - printer_req_free(dev-out_ep, dev-current_rx_req); - - while (!list_empty(dev-rx_reqs)) { - req = container_of(dev-rx_reqs.next, - struct usb_request, list); - list_del(req-list); - printer_req_free(dev-out_ep, req); - } - - while (!list_empty(dev-rx_buffers)) { - req = container_of(dev-rx_buffers.next, - struct usb_request, list); - list_del(req-list); - printer_req_free(dev-out_ep, req); - } - usb_free_all_descriptors(f); - kfree(dev); -} -#endif - static int printer_func_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { @@ -1189,68 +1140,6 @@ static void printer_func_disable(struct usb_function *f) spin_unlock_irqrestore(dev-lock, flags); } -#ifdef USBF_PRINTER_INCLUDED -static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, -char *pnp_string, unsigned q_len, int minor) -{ - struct printer_dev *dev; - int status = -ENOMEM; - size_t len; - - if (minor = minors) - return -ENOENT; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - dev-pnp_string = pnp_string; - dev-minor = minor; - - dev-function.name = shortname; - dev-function.bind = printer_func_bind; - dev-function.setup = printer_func_setup; - dev-function.unbind = printer_func_unbind; - dev-function.set_alt = printer_func_set_alt; - dev-function.disable = printer_func_disable; - dev-function.req_match = gprinter_req_match; - INIT_LIST_HEAD(dev-tx_reqs); - INIT_LIST_HEAD(dev-rx_reqs); - INIT_LIST_HEAD(dev-rx_buffers); - - if (pnp_str) - strlcpy(dev-pnp_string[2], pnp_str, PNP_STRING_LEN - 2); - - len = strlen(pnp_string); - pnp_string[0] = (len 8) 0xFF; - pnp_string[1] = len 0xFF; - - spin_lock_init(dev-lock); - mutex_init(dev-lock_printer_io); - INIT_LIST_HEAD(dev-tx_reqs_active); - INIT_LIST_HEAD(dev-rx_reqs_active); - init_waitqueue_head(dev-rx_wait); - init_waitqueue_head(dev-tx_wait); - init_waitqueue_head(dev-tx_flush_wait); - - dev-interface = -1; - dev-printer_cdev_open = 0; - dev-printer_status = PRINTER_NOT_ERROR; - dev-current_rx_req = NULL; - dev-current_rx_bytes = 0; - dev-current_rx_buf = NULL; - dev-q_len = q_len; - - status = usb_add_function(c, dev-function); - if (status) { - kfree(dev); - return status; - } - - INFO(dev, %s, version: DRIVER_VERSION \n, driver_desc); - return 0; -} -#else static inline int gprinter_get_minor(void) { return ida_simple_get(printer_ida, 0, 0, GFP_KERNEL); @@ -1422,8 +1311,6 @@ DECLARE_USB_FUNCTION_INIT(printer, gprinter_alloc_inst, gprinter_alloc); MODULE_LICENSE(GPL); MODULE_AUTHOR(Craig Nadler); -#endif - static int gprinter_setup(int count) { int status; -- 1.9.1 -- To unsubscribe from this list: send
[PATCHv3 13/29] usb: gadget: printer: define pnp string buffer length
Avoid using magic numbers. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 84e6cdd..db5e2f0 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -276,9 +276,11 @@ static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, /* descriptors that are built on-demand */ +#define PNP_STRING_LEN 1024 + static charproduct_desc [40] = DRIVER_DESC; static charserial_num [40] = 1; -static charpnp_string [1024] = +static charpnp_string[PNP_STRING_LEN] = XXMFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;; /* static strings, in UTF-8 */ @@ -1247,7 +1249,7 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, INIT_LIST_HEAD(dev-rx_buffers); if (pnp_str) - strlcpy(pnp_string[2], pnp_str, sizeof(pnp_string) - 2); + strlcpy(pnp_string[2], pnp_str, PNP_STRING_LEN - 2); len = strlen(pnp_string); pnp_string[0] = (len 8) 0xFF; -- 1.9.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
[PATCHv3 12/29] usb: gadget: printer: move function-related unbind code to function's unbind
In order to factor out a reusable f_printer.c, the code related to the function should be placed in functions related to the function. printer_cfg_unbind() becomes empty, so it is removed. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 58 - 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 5dbb93a..84e6cdd 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1156,43 +1156,11 @@ fail_tx_reqs: static void printer_func_unbind(struct usb_configuration *c, struct usb_function *f) { - usb_free_all_descriptors(f); -} - -static int printer_func_set_alt(struct usb_function *f, - unsigned intf, unsigned alt) -{ - struct printer_dev *dev = container_of(f, struct printer_dev, function); - int ret = -ENOTSUPP; - - if (!alt) - ret = set_interface(dev, intf); - - return ret; -} - -static void printer_func_disable(struct usb_function *f) -{ - struct printer_dev *dev = container_of(f, struct printer_dev, function); - unsigned long flags; - - DBG(dev, %s\n, __func__); - - spin_lock_irqsave(dev-lock, flags); - printer_reset_interface(dev); - spin_unlock_irqrestore(dev-lock, flags); -} - -static void printer_cfg_unbind(struct usb_configuration *c) -{ struct printer_dev *dev; struct usb_request *req; dev = usb_printer_gadget; - DBG(dev, %s\n, __func__); - - /* Remove sysfs files */ device_destroy(usb_gadget_class, g_printer_devno); /* Remove Character Device */ @@ -1226,11 +1194,35 @@ static void printer_cfg_unbind(struct usb_configuration *c) list_del(req-list); printer_req_free(dev-out_ep, req); } + usb_free_all_descriptors(f); +} + +static int printer_func_set_alt(struct usb_function *f, + unsigned intf, unsigned alt) +{ + struct printer_dev *dev = container_of(f, struct printer_dev, function); + int ret = -ENOTSUPP; + + if (!alt) + ret = set_interface(dev, intf); + + return ret; +} + +static void printer_func_disable(struct usb_function *f) +{ + struct printer_dev *dev = container_of(f, struct printer_dev, function); + unsigned long flags; + + DBG(dev, %s\n, __func__); + + spin_lock_irqsave(dev-lock, flags); + printer_reset_interface(dev); + spin_unlock_irqrestore(dev-lock, flags); } static struct usb_configuration printer_cfg_driver = { .label = printer, - .unbind = printer_cfg_unbind, .bConfigurationValue= 1, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, }; -- 1.9.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
[PATCHv3 04/29] usb: gadget: printer: eliminate random pointer dereference
struct printer_dev contains 3 list heads: tx_reqs, rx_reqs and rx_buffers. There is just one instance of this structure in the driver and it is file static, and as such initialized with all zeros. If device_create() or cdev_add() fails then goto fail branch is taken, which results in printer_cfg_unbind() call. The latter checks if tx_reqs, rx_reqs and rx_buffers lists are empty. The check for emptiness is in fact a check whether the next member of struct list_head points to the head of the list. But the heads of the lists in question have not been initialized yet and, as mentioned above, contain all zeros, so list_empty() returns false and respective while loop body starts executing. Here, container_of() just subtracts the offset of a struct usb_request member from an address of this same member, which results in a value somewhere near 0 or 0xfff...ff. And the argument to list_del() dereferences such a pointer which causes a disaster. This patch moves respective INIT_LIST_HEAD() invocations to a point before goto fail branch can be taken. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 21ea317..12247d3 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1190,6 +1190,9 @@ static int __init printer_bind_config(struct usb_configuration *c) dev-function.unbind = printer_func_unbind; dev-function.set_alt = printer_func_set_alt; dev-function.disable = printer_func_disable; + INIT_LIST_HEAD(dev-tx_reqs); + INIT_LIST_HEAD(dev-rx_reqs); + INIT_LIST_HEAD(dev-rx_buffers); status = usb_add_function(c, dev-function); if (status) @@ -1233,11 +1236,8 @@ static int __init printer_bind_config(struct usb_configuration *c) spin_lock_init(dev-lock); mutex_init(dev-lock_printer_io); - INIT_LIST_HEAD(dev-tx_reqs); INIT_LIST_HEAD(dev-tx_reqs_active); - INIT_LIST_HEAD(dev-rx_reqs); INIT_LIST_HEAD(dev-rx_reqs_active); - INIT_LIST_HEAD(dev-rx_buffers); init_waitqueue_head(dev-rx_wait); init_waitqueue_head(dev-tx_wait); init_waitqueue_head(dev-tx_flush_wait); -- 1.9.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
[PATCHv3 20/29] usb: gadget: composite: add req_match method to usb_function
Non-standard requests can encode the actual interface number in a non-standard way. For example composite_setup() assumes that it is w_index 0xFF, but the printer function encodes the interface number in a context-dependet way (either w_index or w_index 8). This can lead to such requests being directed to wrong functions. This patch adds req_match() method to usb_function. Its purpose is to verify that a given request can be handled by a given function. If any function within a configuration provides the method and it returns true, then it is assumed that the right function is found. If a function uses req_match(), it should try as hard as possible to determine if the request is meant for it. If no functions in a configuration provide req_match or none of them returns true, then fall back to the usual approach. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/composite.c | 6 +- include/linux/usb/composite.h | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 9fb9231..4d25e11 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1758,6 +1758,10 @@ unknown: * take such requests too, if that's ever needed: to work * in config 0, etc. */ + list_for_each_entry(f, cdev-config-functions, list) + if (f-req_match f-req_match(f, ctrl)) + goto try_fun_setup; + f = NULL; switch (ctrl-bRequestType USB_RECIP_MASK) { case USB_RECIP_INTERFACE: if (!cdev-config || intf = MAX_CONFIG_INTERFACES) @@ -1775,7 +1779,7 @@ unknown: f = NULL; break; } - +try_fun_setup: if (f f-setup) value = f-setup(f, ctrl); else { diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 3d87def..2511469 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -148,6 +148,7 @@ struct usb_os_desc_table { * @disable: (REQUIRED) Indicates the function should be disabled. Reasons * include host resetting or reconfiguring the gadget, and disconnection. * @setup: Used for interface-specific control requests. + * @req_match: Tests if a given class request can be handled by this function. * @suspend: Notifies functions when the host stops sending USB traffic. * @resume: Notifies functions when the host restarts USB traffic. * @get_status: Returns function status as a reply to @@ -213,6 +214,8 @@ struct usb_function { void(*disable)(struct usb_function *); int (*setup)(struct usb_function *, const struct usb_ctrlrequest *); + bool(*req_match)(struct usb_function *, + const struct usb_ctrlrequest *); void(*suspend)(struct usb_function *); void(*resume)(struct usb_function *); -- 1.9.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
[PATCHv3 08/29] usb: gadget: printer: follow the naming convention for usb_add_config callback
Legacy gadgets, before converting them to the new function framework, used to use the name something_do_config() for usb_add_config()'s callback. This patch changes the name so that it is easier to follow the convention. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index a9c3e57..c865833 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1170,7 +1170,7 @@ static struct usb_configuration printer_cfg_driver = { .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, }; -static int __init printer_bind_config(struct usb_configuration *c) +static int __init printer_do_config(struct usb_configuration *c) { struct usb_gadget *gadget = c-cdev-gadget; struct printer_dev *dev; @@ -1287,7 +1287,7 @@ static int __init printer_bind(struct usb_composite_dev *cdev) device_desc.iProduct = strings[USB_GADGET_PRODUCT_IDX].id; device_desc.iSerialNumber = strings[USB_GADGET_SERIAL_IDX].id; - ret = usb_add_config(cdev, printer_cfg_driver, printer_bind_config); + ret = usb_add_config(cdev, printer_cfg_driver, printer_do_config); if (ret) return ret; usb_composite_overwrite_options(cdev, coverwrite); -- 1.9.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
[PATCHv3 01/29] usb: gadget: composite: don't try standard handling for non-standard requests
If a non-standard request is processed and its parameters just happen to match those of some standard request, the logic of composite_setup() can be fooled, so don't even try any switch cases, just go to the proper place where unknown requests are handled. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/composite.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 13adfd1..9fb9231 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1472,6 +1472,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) req-length = 0; gadget-ep0-driver_data = cdev; + /* +* Don't let non-standard requests match any of the cases below +* by accident. +*/ + if ((ctrl-bRequestType USB_TYPE_MASK) != USB_TYPE_STANDARD) + goto unknown; + switch (ctrl-bRequest) { /* we handle all standard USB descriptors */ -- 1.9.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
[PATCHv3 25/29] usb: gadget: f_printer: convert to new function interface with backward compatibility
In order to add configfs support, a usb function must be converted to use the new interface. This patch converts the function to the new interface and provides backward compatiblity layer, which can be removed after all its users are converted to use the new interface. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/Kconfig | 3 + drivers/usb/gadget/function/Makefile| 2 + drivers/usb/gadget/function/f_printer.c | 185 +++- drivers/usb/gadget/function/u_printer.h | 30 ++ drivers/usb/gadget/legacy/printer.c | 1 + 5 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/gadget/function/u_printer.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index b454d05..9d507cf 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -196,6 +196,9 @@ config USB_F_MIDI config USB_F_HID tristate +config USB_F_PRINTER + tristate + choice tristate USB Gadget Drivers default USB_ETH diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index f71b1aa..bd7def5 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -42,3 +42,5 @@ usb_f_midi-y := f_midi.o obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o usb_f_hid-y:= f_hid.o obj-$(CONFIG_USB_F_HID)+= usb_f_hid.o +usb_f_printer-y:= f_printer.o +obj-$(CONFIG_USB_F_PRINTER)+= usb_f_printer.o diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 0847972..93f4d4e 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -24,6 +24,7 @@ #include linux/mutex.h #include linux/errno.h #include linux/init.h +#include linux/idr.h #include linux/timer.h #include linux/list.h #include linux/interrupt.h @@ -46,6 +47,8 @@ #include linux/usb/gadget.h #include linux/usb/g_printer.h +#include u_printer.h + #define PNP_STRING_LEN 1024 #define PRINTER_MINORS 4 #define GET_DEVICE_ID 0 @@ -54,6 +57,10 @@ static int major, minors; static struct class *usb_gadget_class; +#ifndef USBF_PRINTER_INCLUDED +static DEFINE_IDA(printer_ida); +static DEFINE_MUTEX(printer_ida_lock); /* protects access do printer_ida */ +#endif /*-*/ @@ -999,7 +1006,7 @@ unknown: return value; } -static int __init printer_func_bind(struct usb_configuration *c, +static int printer_func_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_gadget *gadget = c-cdev-gadget; @@ -,6 +1118,7 @@ fail_tx_reqs: } +#ifdef USBF_PRINTER_INCLUDED static void printer_func_unbind(struct usb_configuration *c, struct usb_function *f) { @@ -1155,6 +1163,7 @@ static void printer_func_unbind(struct usb_configuration *c, usb_free_all_descriptors(f); kfree(dev); } +#endif static int printer_func_set_alt(struct usb_function *f, unsigned intf, unsigned alt) @@ -1180,6 +1189,7 @@ static void printer_func_disable(struct usb_function *f) spin_unlock_irqrestore(dev-lock, flags); } +#ifdef USBF_PRINTER_INCLUDED static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, char *pnp_string, unsigned q_len, int minor) { @@ -1240,6 +1250,179 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, INFO(dev, %s, version: DRIVER_VERSION \n, driver_desc); return 0; } +#else +static inline int gprinter_get_minor(void) +{ + return ida_simple_get(printer_ida, 0, 0, GFP_KERNEL); +} + +static inline void gprinter_put_minor(int minor) +{ + ida_simple_remove(printer_ida, minor); +} + +static int gprinter_setup(int); +static void gprinter_cleanup(void); + +static void gprinter_free_inst(struct usb_function_instance *f) +{ + struct f_printer_opts *opts; + + opts = container_of(f, struct f_printer_opts, func_inst); + + mutex_lock(printer_ida_lock); + + gprinter_put_minor(opts-minor); + if (idr_is_empty(printer_ida.idr)) + gprinter_cleanup(); + + mutex_unlock(printer_ida_lock); + + kfree(opts); +} + +static struct usb_function_instance *gprinter_alloc_inst(void) +{ + struct f_printer_opts *opts; + struct usb_function_instance *ret; + int status = 0; + + opts = kzalloc(sizeof(*opts), GFP_KERNEL); + if (!opts) + return ERR_PTR(-ENOMEM); + + opts-func_inst.free_func_inst = gprinter_free_inst; + ret = opts-func_inst; + + mutex_lock(printer_ida_lock); + + if (idr_is_empty(printer_ida.idr)) { + status = gprinter_setup(PRINTER_MINORS); + if (status)
[PATCHv3 18/29] usb: gadget: printer: don't access file global usb_printer_gadget in function's code
The printer_dev can be recovered from printer_func_unbind() function's parameters. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 3206ebc..806475c 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1159,7 +1159,7 @@ static void printer_func_unbind(struct usb_configuration *c, struct printer_dev *dev; struct usb_request *req; - dev = usb_printer_gadget; + dev = container_of(f, struct printer_dev, function); device_destroy(usb_gadget_class, g_printer_devno); -- 1.9.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
[PATCHv3 16/29] usb: gadget: printer: call gprinter_setup() from gadget's bind
Call gprinter_setup() from gadget's bind instead of module's init. Call gprinter_cleaup() corerspondingly. This detaches printer function's logic from legacy printer gadget's implementation. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 35 ++- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 83cea9a5c..b7889b1 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1330,45 +1330,47 @@ static int __init printer_bind(struct usb_composite_dev *cdev) { int ret; + ret = gprinter_setup(); + if (ret) + return ret; + ret = usb_string_ids_tab(cdev, strings); - if (ret 0) + if (ret 0) { + gprinter_cleanup(); return ret; + } device_desc.iManufacturer = strings[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings[USB_GADGET_PRODUCT_IDX].id; device_desc.iSerialNumber = strings[USB_GADGET_SERIAL_IDX].id; ret = usb_add_config(cdev, printer_cfg_driver, printer_do_config); - if (ret) + if (ret) { + gprinter_cleanup(); return ret; + } usb_composite_overwrite_options(cdev, coverwrite); return ret; } +static int __exit printer_unbind(struct usb_composite_dev *cdev) +{ + gprinter_cleanup(); + return 0; +} + static __refdata struct usb_composite_driver printer_driver = { .name = shortname, .dev= device_desc, .strings= dev_strings, .max_speed = USB_SPEED_SUPER, .bind = printer_bind, + .unbind = printer_unbind, }; static int __init init(void) { - int status; - - status = gprinter_setup(); - if (status) - return status; - - status = usb_composite_probe(printer_driver); - if (status) { - class_destroy(usb_gadget_class); - unregister_chrdev_region(g_printer_devno, 1); - pr_err(usb_gadget_probe_driver %x\n, status); - } - - return status; + return usb_composite_probe(printer_driver); } module_init(init); @@ -1377,7 +1379,6 @@ cleanup(void) { mutex_lock(usb_printer_gadget.lock_printer_io); usb_composite_unregister(printer_driver); - gprinter_cleanup(); mutex_unlock(usb_printer_gadget.lock_printer_io); } module_exit(cleanup); -- 1.9.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
[PATCHv3 06/29] usb: gadget: printer: add missing error handling
If cdev_add() in printer_bind_config() fails, care is taken to reverse the effects of initializations completed until the fail happens. But if printer_req_alloc() fails, it is just one of the two lists that is cleaned up while the effects of cdev_add() and device_create() are not reverted. This patch changes error handling so that at least as much cleanup is done as when a failure happens before printer_req_alloc() invocations. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 23 +-- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index eb02a6b..bbcd6aa 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1249,31 +1249,18 @@ static int __init printer_bind_config(struct usb_configuration *c) dev-current_rx_bytes = 0; dev-current_rx_buf = NULL; + status = -ENOMEM; for (i = 0; i QLEN; i++) { req = printer_req_alloc(dev-in_ep, USB_BUFSIZE, GFP_KERNEL); - if (!req) { - while (!list_empty(dev-tx_reqs)) { - req = container_of(dev-tx_reqs.next, - struct usb_request, list); - list_del(req-list); - printer_req_free(dev-in_ep, req); - } - return -ENOMEM; - } + if (!req) + goto fail; list_add(req-list, dev-tx_reqs); } for (i = 0; i QLEN; i++) { req = printer_req_alloc(dev-out_ep, USB_BUFSIZE, GFP_KERNEL); - if (!req) { - while (!list_empty(dev-rx_reqs)) { - req = container_of(dev-rx_reqs.next, - struct usb_request, list); - list_del(req-list); - printer_req_free(dev-out_ep, req); - } - return -ENOMEM; - } + if (!req) + goto fail; list_add(req-list, dev-rx_reqs); } -- 1.9.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
[PATCHv3 15/29] usb: gadget: printer: add setup and cleanup functions
Factor out gprinter_setup() and gprinter_cleanup() so that it is easy to change the place they are called from. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 46 + 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 42c46da..83cea9a5c 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1298,6 +1298,34 @@ static int __init printer_do_config(struct usb_configuration *c) } +static int gprinter_setup(void) +{ + int status; + + usb_gadget_class = class_create(THIS_MODULE, usb_printer_gadget); + if (IS_ERR(usb_gadget_class)) { + status = PTR_ERR(usb_gadget_class); + pr_err(unable to create usb_gadget class %d\n, status); + return status; + } + + status = alloc_chrdev_region(g_printer_devno, 0, 1, + USB printer gadget); + if (status) { + pr_err(alloc_chrdev_region %d\n, status); + class_destroy(usb_gadget_class); + } + + return status; +} + +/* must be called with struct printer_dev's lock_printer_io held */ +static void gprinter_cleanup(void) +{ + unregister_chrdev_region(g_printer_devno, 1); + class_destroy(usb_gadget_class); +} + static int __init printer_bind(struct usb_composite_dev *cdev) { int ret; @@ -1329,20 +1357,9 @@ init(void) { int status; - usb_gadget_class = class_create(THIS_MODULE, usb_printer_gadget); - if (IS_ERR(usb_gadget_class)) { - status = PTR_ERR(usb_gadget_class); - pr_err(unable to create usb_gadget class %d\n, status); - return status; - } - - status = alloc_chrdev_region(g_printer_devno, 0, 1, - USB printer gadget); - if (status) { - pr_err(alloc_chrdev_region %d\n, status); - class_destroy(usb_gadget_class); + status = gprinter_setup(); + if (status) return status; - } status = usb_composite_probe(printer_driver); if (status) { @@ -1360,8 +1377,7 @@ cleanup(void) { mutex_lock(usb_printer_gadget.lock_printer_io); usb_composite_unregister(printer_driver); - unregister_chrdev_region(g_printer_devno, 1); - class_destroy(usb_gadget_class); + gprinter_cleanup(); mutex_unlock(usb_printer_gadget.lock_printer_io); } module_exit(cleanup); -- 1.9.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
[PATCHv3 14/29] usb: gadget: printer: don't access file global pnp_string in function's code
In order to factor out a reusable f_printer, the function's code should not use file global variables related to legacy printer gadget's implementation. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index db5e2f0..42c46da 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -86,6 +86,7 @@ struct printer_dev { u8 printer_cdev_open; wait_queue_head_t wait; unsignedq_len; + char*pnp_string;/* We don't own memory! */ struct usb_function function; }; @@ -994,10 +995,10 @@ static int printer_func_setup(struct usb_function *f, if ((wIndex8) != dev-interface) break; - value = (pnp_string[0]8)|pnp_string[1]; - memcpy(req-buf, pnp_string, value); + value = (dev-pnp_string[0] 8) | dev-pnp_string[1]; + memcpy(req-buf, dev-pnp_string, value); DBG(dev, 1284 PNP String: %x %s\n, value, - pnp_string[2]); + dev-pnp_string[2]); break; case 1: /* Get Port Status */ @@ -1230,13 +1231,14 @@ static struct usb_configuration printer_cfg_driver = { }; static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, -unsigned q_len) +char *pnp_string, unsigned q_len) { struct printer_dev *dev; int status = -ENOMEM; size_t len; dev = usb_printer_gadget; + dev-pnp_string = pnp_string; dev-function.name = shortname; dev-function.bind = printer_func_bind; @@ -1249,7 +1251,7 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, INIT_LIST_HEAD(dev-rx_buffers); if (pnp_str) - strlcpy(pnp_string[2], pnp_str, PNP_STRING_LEN - 2); + strlcpy(dev-pnp_string[2], pnp_str, PNP_STRING_LEN - 2); len = strlen(pnp_string); pnp_string[0] = (len 8) 0xFF; @@ -1292,7 +1294,7 @@ static int __init printer_do_config(struct usb_configuration *c) printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - return f_printer_bind_config(c, iPNPstring, QLEN); + return f_printer_bind_config(c, iPNPstring, pnp_string, QLEN); } -- 1.9.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
[PATCHv3 17/29] usb: gadget: printer: eliminate file global printer_mutex
The mutex is a legacy after semi-automatic Big Kernel Lock removal. printer_open() does its own locking, so no need to duplicate it. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index b7889b1..3206ebc 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -48,7 +48,6 @@ USB_GADGET_COMPOSITE_OPTIONS(); #define DRIVER_DESCPrinter Gadget #define DRIVER_VERSION 2007 OCT 06 -static DEFINE_MUTEX(printer_mutex); static const char shortname [] = printer; static const char driver_desc [] = DRIVER_DESC; @@ -420,7 +419,6 @@ printer_open(struct inode *inode, struct file *fd) unsigned long flags; int ret = -EBUSY; - mutex_lock(printer_mutex); dev = container_of(inode-i_cdev, struct printer_dev, printer_cdev); spin_lock_irqsave(dev-lock, flags); @@ -436,7 +434,6 @@ printer_open(struct inode *inode, struct file *fd) spin_unlock_irqrestore(dev-lock, flags); DBG(dev, printer_open returned %x\n, ret); - mutex_unlock(printer_mutex); return ret; } -- 1.9.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: Reg : USB modeswitch details LE920 Module
Hi Arulpandiyan, 2015-03-02 18:42 GMT+01:00 Arulpandiyan Vadivel arulpandiyan.vadi...@aricent.com: Hi Daniele Greg, snip Regards, Arulpandiyan Vadivel. DISCLAIMER: This message is proprietary to Aricent and is intended solely for the use of the individual to whom it is addressed. It may contain privileged or confidential information and should not be circulated or used for any purpose other than for what it is intended. If you have received this message in error, please notify the originator immediately. If you are not the intended recipient, you are notified that you are strictly prohibited from using, copying, altering, or disclosing the contents of this message. Aricent accepts no responsibility for loss or damage arising from the use of the information transmitted by this email including damage from virus. I really wanted to answer your question, but due to this disclaimer I am not able to answer. Please resend your mail to the list without this disclaimer. Regards, Daniele -- 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 3/3] ARM: mvebu: armada-385-ap: Enable USB3 port
On 03.03.2015 11:59, Maxime Ripard wrote: On Mon, Mar 02, 2015 at 08:23:37PM +0100, Gregory CLEMENT wrote: Hi Maxime, On 19/01/2015 14:01, Maxime Ripard wrote: The Armada 385 AP board has a USB3 port exposed that uses a GPIO to drive the VBUS line. Enable the needed drivers to support this. it seems that this patch was not applied yet. Patch 1 is now in linux-next and should be part of 4.0-rc. But what about patch 2? IIRC, Greg or Matthias said that Matthias would look into these patches after the merge window. It still didn't happen though. Maxime Hi I understood that you wanted the first fix patch in as soon as possible so I sent it forward to Greg, and it's now in his usb-linus branch. The other two patches, 2/3 and 3/3 you said were regual patches (for usb-next?), Andrew said he can take 3/3 and wondered if 2/3 and 3/3 need to go together? It doesn't matter for me, I can take 2/3 if you like, but I'd prefer if someone with more USB PHY insight could ack it first. -Mathias -- 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] drivers: usb: gadget: udc: Fix NULL dereference
This patch fixes multiple instances of null pointer dereference in this code. ep-udc is assigned to udc. ep is just an offset from _ep. _ep is then checked for NULL. udc is dereferenced under the NULL check for _ep, making an invalid pointer reference. udc is then checked for NULL, if NULL, it is then dereferenced as udc-dev. To fix these issues, shift assignment of udc by dereferencing ep after null check for _ep, replace both dev_dbg statements with pr_debug. Found using Coccinelle. Signed-off-by: Tapasweni Pathak tapaswenipat...@gmail.com Suggested-by : Julia Lawall julia.law...@lip6.fr Reviewed-by : Julia Lawall julia.law...@lip6.fr --- drivers/usb/gadget/udc/lpc32xx_udc.c |7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 27fd413..6398539 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -1807,17 +1807,16 @@ static int lpc32xx_ep_queue(struct usb_ep *_ep, !list_empty(req-queue)) return -EINVAL; - udc = ep-udc; - if (!_ep) { - dev_dbg(udc-dev, invalid ep\n); + pr_debug(invalid ep\n); return -EINVAL; } + udc = ep-udc; if ((!udc) || (!udc-driver) || (udc-gadget.speed == USB_SPEED_UNKNOWN)) { - dev_dbg(udc-dev, invalid device\n); + pr_debug(invalid device\n); return -EINVAL; } -- 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/8] ARM OMAP2+ GPMC: fixes and bus children
Hi Roger, On Tue, Mar 3, 2015 at 1:55 PM, Roger Quadros rog...@ti.com wrote: I'm OK with this version. Tony, after you ACK these I will queue them for v4.1. Please use v4 of my patches. The DTS output has been changed and the comments have their colon. Regards, Robert -- 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: Control message failures kill entire XHCI stack
On 28.02.2015 09:16, Alistair Grant wrote: Hi Mathias Devin, On Thu, Feb 19, 2015 at 3:18 PM, Mathias Nyman mathias.ny...@linux.intel.com wrote: Got one more patch added to the for-usb-next-branch. It makes sure we allocate enough scratchpad memory for xhci. It's one possible cause. Patch will anyway go to 3.20, but you can try it out first to see if it helps My apologies for my slow response, I've been in hospital for almost two weeks having my gallbladder removed. I tried recording with the Hauppauge USB Live2 using the following kernel: * 3.19.0 with the following patches: * xhci: Allocate correct amount of scratchpad buffers * xhci: Don't touch TRBs memory if those are no longer on the endpoint ring * xhci: fix invalid pointer in reset device debugging * xhci: add debugging for reset device and stop endpoint commands * xhci: add command ring stop and restart debug messages Unfortunately it still fails with the xHCI host controller dying. I've included an extract from syslog which will hopefully show you the main activity. The entire syslog (boot, test, shutdown) is available from: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1412121/+attachment/4330313/+files/syslog Ok, thanks for the info. Hope you are feeling better. Does increasing the TRB count per segment help? diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 3b97f05..4e12e31 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1268,7 +1268,7 @@ union xhci_trb { * since the command ring is 64-byte aligned. * It must also be greater than 16. */ -#define TRBS_PER_SEGMENT 64 +#define TRBS_PER_SEGMENT 256 /* Allow two commands + a link TRB, along with any reserved command TRBs */ #define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3) #define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16) It should avoid ring expansion, which combined with canceling the urbs seems to always happend before this issue Take care -Mathias -- 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: keyboard/trackpad combo unusable on MacBookPro4,1 with bcm5974.ko
Alan Stern stern@... writes: I agree. The problem is that the HID core now tests for hdev-type == HID_TYPE_USBMOUSE, but it doesn't test for bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE like the older code did. This issue should be reported to the author of that second commit (CC'ed). OK. Let me know if there's anything else I can do to help fix this. Cheers, Christian -- 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
Request for comments
Hello, I am sending this email in order to get some feedback from you about a feature that I am planning to do in a driver I am working on. This new feature basically is to turn the relationship between driver and hardware IP more transparent, making the software more robust. Let me explain the idea: a) The hardware has the capability of supplying to the driver the IP version and crucial features that it support or not b) The driver would read the hardware capability features and work without hick-ups even if the developer has configured him (e.g. menuconfig during build process) to do some specific thing that is not supported by the current connected hardware c) If the driver is configured to do something that the connected hardware is not capable of doing, it simply logs a message to kernel log and automatically disables it trying to work has fluid as possible d) If the hardware does not have the capability of supplying information of this type to the driver, than it should work according to the configuration In your opinion this feature would be a value-added to a new driver / existent driver? Thank you for your time! Best regards Joao --- -- 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
What would cause the xhci_irq interrupt handler to not be called?
Hi, I'm doing some usb driver development work and running into an issue where my urb completion handler is not being called to give my driver back the urb/buffer. This issue occurs randomly, ie it'll happen anywhere w/in 5 minutes to over 4 hours. With the kernel dynamic debugging enabled for the usbcore and xhci_hcd modules, I see that the urb I submit to the usbcore appears to be mapped to the hcd's dma for transfer, but the xhci_irq never gets called to give the driver back the urb. Unfortunately, it results in my application being timed out eventually because any urbs I submit after this happens appears to not be sent to the usb wire according to usb protocol analyzer logs. This is with sending messages to my Control EP, with very low traffic. Could this be an issue with the usb controller that I'm using on my device? Can someone help me understand under what conditions should the xhci_irq/interrupt occur? Thanks, Jay -- 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: What would cause the xhci_irq interrupt handler to not be called?
On Tue, 3 Mar 2015, Jay Guillory wrote: I actually see the ACK sent from my device to the HC on the protocol analyzer logs. How can I check if the HC actually receives/sees the ACK? You're talking about a control transfer, right? Control transfers involve more than one stage and thus require more than one ACK. The way to know if all the ACKs have been received/sent is if your completion routine gets called. :-) 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: Request for comments
Hi, (please break your email at 80-characters, have a look at Documentation/email-clients.txt for tips about how to achieve that) On Tue, Mar 03, 2015 at 05:06:45PM +, Joao Pinto wrote: Hello, I am sending this email in order to get some feedback from you about a feature that I am planning to do in a driver I am working on. usually, an RFC comes with a patch implemeting (perhaps partialy) the feature you want comments on. Also, which driver you talking about ? which IP ? How are we supposed to provide any valid comments without knowing such details ? This new feature basically is to turn the relationship between driver and hardware IP more transparent, making the software more robust. transparent how ? PCI devices match against classes, product ids, vendor ids, etc. USB device match using similar techniques. How can something be more transparent than that ? Let me explain the idea: a) The hardware has the capability of supplying to the driver the IP version and crucial features that it support or not again, which HW ? Based on your email domain and the fact that you're Ccing linux-usb, I can only assume you talk about dwc2 because dwc3 already runtime-detects capabilities and versions. b) The driver would read the hardware capability features and work without hick-ups even if the developer has configured him (e.g. menuconfig during build process) to do some specific thing that is not supported by the current connected hardware this is really norm. Every good driver in the kernel today uses such capability registers to runtime-detect features and necessity for workaround to known errata. Look at drivers/usb/dwc3 for example. c) If the driver is configured to do something that the connected hardware is not capable of doing, it simply logs a message to kernel log and automatically disables it trying to work has fluid as possible that's also norm and implement in many, many drivers. d) If the hardware does not have the capability of supplying information of this type to the driver, than it should work according to the configuration also pretty much common sense. In your opinion this feature would be a value-added to a new driver / existent driver? it really dpeends. If you're talking about dwc3 we already do that, if you're talking about musb, then I'd NAK the patch because some implementations of MUSB have always-zero ConfigData, Revision and RAMbits which 100% hinders the possibility of runtime-detecting anything; if you're talking about dwc2, then it might be a very good patch worth looking over. DWC2's maintianer is a colleague of yours so perhaps, if you're really talking about that IP, Cc him ? As a general comment, make sure to always Cc maintainers and make extra clear which piece of HW you're talking about because, frankly, there are a ton of them. cheers -- balbi signature.asc Description: Digital signature
Re: Request for comments
On Tue, Mar 03, 2015 at 05:06:45PM +, Joao Pinto wrote: Hello, I am sending this email in order to get some feedback from you about a feature that I am planning to do in a driver I am working on. I don't see any code here, or really, any specifics, so there's nothing to comment on at all sorry. Remember, the Linux kernel community does things based on code, and specifics, only. good luck! 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: What would cause the xhci_irq interrupt handler to not be called?
On Tue, 3 Mar 2015, Jay Guillory wrote: Hi, I'm doing some usb driver development work and running into an issue where my urb completion handler is not being called to give my driver back the urb/buffer. This issue occurs randomly, ie it'll happen anywhere w/in 5 minutes to over 4 hours. With the kernel dynamic debugging enabled for the usbcore and xhci_hcd modules, I see that the urb I submit to the usbcore appears to be mapped to the hcd's dma for transfer, but the xhci_irq never gets called to give the driver back the urb. Unfortunately, it results in my application being timed out eventually because any urbs I submit after this happens appears to not be sent to the usb wire according to usb protocol analyzer logs. This is with sending messages to my Control EP, with very low traffic. Could this be an issue with the usb controller that I'm using on my device? Can someone help me understand under what conditions should the xhci_irq/interrupt occur? The interrupt will occur when the transfer is complete. The most likely reason for the transfer not to complete is because the device doesn't send any response. 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 v2] USB: serial: add nt124 usb to serial driver
This driver is for the NovaTech 124 4x serial expansion board for the NovaTech OrionLXm. Firmware source code can be found here: https://github.com/novatechweb/nt124 Signed-off-by: George McCollister george.mccollis...@gmail.com --- Changes to v1: - Added description after nt124.c on line 2. - Removed DRIVER_AUTHOR and DRIVER_DESC, use MODULE macros directly. - Removed some unnecessary new lines and comments. - Removed __packed from struct nt124_line_coding. - Added locking around ctrlin and ctrlout. - Switch ctrlin and ctrlout from unsigned int to u16. - Removed serial_transmit and added tx_empty. Use a hybrid notification/polling method to accurately determine when transmission is finished while minimizing bus traffic (see comments in the code for details). - Removed flowctrl from struct nt124_line_coding. - Use u16 for request and value, size_t for len arguments of nt124_ctrl_msg() - Use USB_CTRL_SET_TIMEOUT instead of 5000. - Use %04x for 16-bit variables and %zu for size_t variables in dev_dbg() and dev_err(). - Removed use of ?: constructs. - Removed nt124_set_control, nt124_set_line, nt124_send_break and - nt124_set_flowctrl macros in favor of calling nt124_ctrl_msg() directly. - Renamed nt124_process_notify() to nt124_process_status(). - Call usb_serial_handle_dcd_change() unconditionally when DCD has changed. - Removed in argument list assignments. - Use usb_translate_errors() in nt124_port_tiocmset(). - Use C_CSTOPB, C_CSIZE, C_PARENB, C_CMSPAR, C_PARODD, C_CRTSCTS macros. - Raise/lower RTS on !B0/B0. - Added NT124_BREAK_ON and NT124_BREAK_OFF #defines. - Change nt124_open() to just call nt124_set_termios() followed by usb_serial_generic_open(). - Don't set bulk_in_size and bulk_out_size. - Performed thorough testing. drivers/usb/serial/Kconfig | 9 + drivers/usb/serial/Makefile | 1 + drivers/usb/serial/nt124.c | 501 3 files changed, 511 insertions(+) create mode 100644 drivers/usb/serial/nt124.c diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index b7cf198..677a26a 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -510,6 +510,15 @@ config USB_SERIAL_NAVMAN To compile this driver as a module, choose M here: the module will be called navman. +config USB_SERIAL_NT124 + tristate USB NovaTech 124 Serial Driver + help + Say Y here if you want to use the NovaTech 124 4x USB to serial + board. + + To compile this driver as a module, choose M here: the + module will be called nt124. + config USB_SERIAL_PL2303 tristate USB Prolific 2303 Single Port Serial Driver help diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 349d9df..f88eaab 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_USB_SERIAL_MOS7720) += mos7720.o obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o obj-$(CONFIG_USB_SERIAL_MXUPORT) += mxuport.o obj-$(CONFIG_USB_SERIAL_NAVMAN)+= navman.o +obj-$(CONFIG_USB_SERIAL_NT124) += nt124.o obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o obj-$(CONFIG_USB_SERIAL_OPTICON) += opticon.o obj-$(CONFIG_USB_SERIAL_OPTION)+= option.o diff --git a/drivers/usb/serial/nt124.c b/drivers/usb/serial/nt124.c new file mode 100644 index 000..d837593 --- /dev/null +++ b/drivers/usb/serial/nt124.c @@ -0,0 +1,501 @@ +/* + * nt124.c - Driver for nt124 4x serial board based on STM32F103 + * + * Copyright (c) 2014 - 2015 NovaTech LLC + * + * Portions derived from the cdc-acm driver + * + * The original intention was to implement a cdc-acm compliant + * 4x USB to serial converter in the STM32F103 however several problems arose. + * The STM32F103 didn't have enough end points to implement 4 ports. + * CTS control was required by the application. + * Accurate notification of transmission completion was required. + * RTSCTS flow control support was required. + * + * The interrupt endpoint was eliminated and the control line information + * was moved to the first two bytes of the bulk in endpoint message. CTS + * control and mechanisms to enable RTSCTS flow control and deliver TXEMPTY + * information were added. + * + * Firmware source code can be found here: + * https://github.com/novatechweb/nt124 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Re: Control message failures kill entire XHCI stack
Hi Mathias, On Tue, Mar 3, 2015 at 2:21 PM, Mathias Nyman mathias.ny...@linux.intel.com wrote: On 28.02.2015 09:16, Alistair Grant wrote: ... * 3.19.0 with the following patches: * xhci: Allocate correct amount of scratchpad buffers * xhci: Don't touch TRBs memory if those are no longer on the endpoint ring * xhci: fix invalid pointer in reset device debugging * xhci: add debugging for reset device and stop endpoint commands * xhci: add command ring stop and restart debug messages Does increasing the TRB count per segment help? Success! Increasing TRBS_PER_SEGMENT from 64 to 256 allowed me to successfully record two 30 second segments of video, i.e. start recording with mythffmpeg, Ctrl-C after 30 seconds, then repeat (this is on top of the patched kernel I reported in my last message). This obviously is good news, it is also better than I typically saw using the ehci driver, as often the second attempt would fail with a Device or Resource Busy message (of course a single test is hardly conclusive, and it may still appear). It's getting a bit late here, so hopefully tomorrow I'll try recording for a longer period of time to make sure that succeeds as well. Included below is the syslog from the time I plugged the Live2 in to unplugging it after recording. There are three types of messages which don't look completely normal to me: Mar 3 20:20:45 alistair-XPS13 kernel: [ 90.952271] xhci_hcd :00:14.0: Cancel URB NOT on current ring Mar 3 20:22:40 alistair-XPS13 kernel: [ 205.582594] xhci_hcd :00:14.0: Starting stop cmd watchdog timer for slot 4 ep index 6. Mar 3 20:22:40 alistair-XPS13 kernel: [ 205.582811] xhci_hcd :00:14.0: WARN Set TR Deq Ptr cmd failed due to incorrect slot or ep state. Thanks! Alistair Mar 3 20:20:37 alistair-XPS13 kernel: [ 83.375647] usb 1-2: new high-speed USB device number 5 using xhci_hcd Mar 3 20:20:37 alistair-XPS13 kernel: [ 83.506190] usb 1-2: New USB device found, idVendor=2040, idProduct=c200 Mar 3 20:20:37 alistair-XPS13 kernel: [ 83.506194] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 Mar 3 20:20:37 alistair-XPS13 kernel: [ 83.506197] usb 1-2: Product: Hauppauge Device Mar 3 20:20:37 alistair-XPS13 kernel: [ 83.506199] usb 1-2: Manufacturer: Hauppauge Mar 3 20:20:37 alistair-XPS13 kernel: [ 83.506200] usb 1-2: SerialNumber: 0011446325 Mar 3 20:20:37 alistair-XPS13 mtp-probe: checking bus 1, device 5: /sys/devices/pci:00/:00:14.0/usb1/1-2 Mar 3 20:20:37 alistair-XPS13 mtp-probe: bus: 1, device: 5 was not an MTP device Mar 3 20:20:38 alistair-XPS13 kernel: [ 83.654357] cx231xx 1-2:1.1: New device Hauppauge Hauppauge Device @ 480 Mbps (2040:c200) with 6 interfaces Mar 3 20:20:38 alistair-XPS13 kernel: [ 83.654398] cx231xx 1-2:1.1: can't change interface 3 alt no. to 3: Max. Pkt size = 0 Mar 3 20:20:38 alistair-XPS13 kernel: [ 83.659158] cx231xx 1-2:1.1: can't change interface 4 alt no. to 1: Max. Pkt size = 0 Mar 3 20:20:38 alistair-XPS13 kernel: [ 83.660371] cx231xx 1-2:1.1: Identified as Hauppauge USB Live 2 (card=9) Mar 3 20:20:38 alistair-XPS13 kernel: [ 83.660587] i2c i2c-10: Added multiplexed i2c bus 12 Mar 3 20:20:38 alistair-XPS13 kernel: [ 83.660631] i2c i2c-10: Added multiplexed i2c bus 13 Mar 3 20:20:38 alistair-XPS13 kernel: [ 83.771556] cx25840 9-0044: cx23102 A/V decoder found @ 0x88 (cx231xx #0-0) Mar 3 20:20:40 alistair-XPS13 kernel: [ 85.767254] cx25840 9-0044: loaded v4l-cx231xx-avcore-01.fw firmware (16382 bytes) Mar 3 20:20:40 alistair-XPS13 kernel: [ 85.800371] cx231xx 1-2:1.1: v4l2 driver version 0.0.3 Mar 3 20:20:40 alistair-XPS13 kernel: [ 85.891907] cx231xx 1-2:1.1: Registered video device video1 [v4l2] Mar 3 20:20:40 alistair-XPS13 kernel: [ 85.892063] cx231xx 1-2:1.1: Registered VBI device vbi0 Mar 3 20:20:40 alistair-XPS13 kernel: [ 85.892069] cx231xx 1-2:1.1: video EndPoint Addr 0x84, Alternate settings: 5 Mar 3 20:20:40 alistair-XPS13 kernel: [ 85.892073] cx231xx 1-2:1.1: VBI EndPoint Addr 0x85, Alternate settings: 2 Mar 3 20:20:40 alistair-XPS13 kernel: [ 85.892077] cx231xx 1-2:1.1: sliced CC EndPoint Addr 0x86, Alternate settings: 2 Mar 3 20:20:40 alistair-XPS13 kernel: [ 85.892274] usbcore: registered new interface driver cx231xx Mar 3 20:20:40 alistair-XPS13 kernel: [ 85.908439] cx231xx 1-2:1.1: audio EndPoint Addr 0x83, Alternate settings: 3 Mar 3 20:20:40 alistair-XPS13 kernel: [ 85.908444] cx231xx 1-2:1.1: Cx231xx Audio Extension initialized Mar 3 20:20:40 alistair-XPS13 pulseaudio[3326]: [pulseaudio] source.c: Default and alternate sample rates are the same. Mar 3 20:20:40 alistair-XPS13 rtkit-daemon[2253]: Successfully made thread 3993 of process 3326 (n/a) owned by '1000' RT at priority 5. Mar 3 20:20:40 alistair-XPS13 rtkit-daemon[2253]: Supervising 5 threads of 1 processes of 1 users. Mar 3 20:20:45 alistair-XPS13 kernel: [ 90.951710] xhci_hcd :00:14.0: Starting stop cmd watchdog timer
Re: Request for comments
Hello Peter, On 3/3/2015 5:35 PM, Peter Stuge wrote: Hello Joao, Joao Pinto wrote: This new feature basically is to turn the relationship between driver and hardware IP more transparent, making the software more robust. This is an important matter already today, and will only become more important in the future. a) The hardware has the capability of supplying to the driver the IP version and crucial features that it support or not b) The driver would read the hardware capability features and work without hick-ups even if the developer has configured him (e.g. menuconfig during build process) to do some specific thing that is not supported by the current connected hardware Once the driver supports auto-detecting these features, I think that the manual configuration shall be removed. In my opinion a manual configuration should always exist to give the kernel user to enable/disable some features of the driver. c) If the driver is configured to do something that the connected hardware is not capable of doing, it simply logs a message to kernel log and automatically disables it trying to work has fluid as possible How the driver reacts in this situation is a matter of policy, which should probably not be specific to any one driver, but should probably be set at a slightly higher level, perhaps even by the person configuring/building the kernel. I agree with you. d) If the hardware does not have the capability of supplying information of this type to the driver, than it should work according to the configuration Hm? Can you be more specific? If it is *possible* for the combination of hardware+driver to work according to the configuration, why would the driver ever do anything else? A company that develops hardware IP can develop a driver that has special features that are specific to its IP. Imagine a USB super speed mode that is only supported by company X hardware IP. If in the future a peripheral connects to a PC using Linux that uses the hardware IP of company X, the driver will automatically recognize it and enable the special mode if configured to do so. In your opinion this feature would be a value-added to a new driver / existent driver? In general I feel strongly that hardware and drivers must stay close to each other, but some of the things you described are not completely clear to me, so it is difficult to give specific feedback. Can you provide more details? Please check above comments. Thanks //Peter Thanks for your time! Joao -- 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: What would cause the xhci_irq interrupt handler to not be called?
I actually see the ACK sent from my device to the HC on the protocol analyzer logs. How can I check if the HC actually receives/sees the ACK? Thanks! Jay -- 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: Request for comments
On Tue, Mar 03, 2015 at 06:35:51PM +0100, Peter Stuge wrote: c) If the driver is configured to do something that the connected hardware is not capable of doing, it simply logs a message to kernel log and automatically disables it trying to work has fluid as possible How the driver reacts in this situation is a matter of policy, which should probably not be specific to any one driver, but should probably be set at a slightly higher level, perhaps even by the person configuring/building the kernel. no, that's wrong. If I enable e.g. Isochronous endpoints on a version of DWC2 configured without Isochronous, I want the driver to just ignore Isochronous endpoints, not refuse to work. -- balbi signature.asc Description: Digital signature
Re: gadgetfs broken since 7f7f25e8
On Tue, Mar 03, 2015 at 10:47:14AM -0500, Alan Stern wrote: On Tue, 3 Mar 2015, Al Viro wrote: Looking at that thing again... why do they need to be dummy? After all, those methods start with get_ready_ep(), which will fail unless we have -state == STATE_EP_ENABLED. So they'd be failing just fine until that first write() anyway. Let's do the following: In addition to the changes you made, it looks like you will need the following or something similar (also untested). I'm not sure if this is race-free, but it's better than before. Right, ep0 has the same kind of problem... @@ -1240,6 +1241,10 @@ static int ep0_fasync (int f, struct file *fd, int on) { struct dev_data *dev = fd-private_data; + + if (dev-state = STATE_DEV_OPENED) + return -ENODEV; + Er... What is protecting dev-state here? Matter of fact, what's the point of that check at all? Right now you have .fasync = ep0_fasync both in ep0_io_operations and in dev_init_operations, so your delta changes the existing semantics... -- 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: What would cause the xhci_irq interrupt handler to not be called?
Alan Stern stern@... writes: On Tue, 3 Mar 2015, Jay Guillory wrote: I actually see the ACK sent from my device to the HC on the protocol analyzer logs. How can I check if the HC actually receives/sees the ACK? You're talking about a control transfer, right? Control transfers involve more than one stage and thus require more than one ACK. The way to know if all the ACKs have been received/sent is if your completion routine gets called. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majordomo@... More majordomo info at http://vger.kernel.org/majordomo-info.html Alan, You're correct. Thank you! After doing a little more reading and looking at the logs again, the device does not appear to be completing the transfer, specifically it's not completing the Status Stage. Best Regards, Jay -- 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: gadgetfs broken since 7f7f25e8
On Tue, Mar 03, 2015 at 10:47:14AM -0500, Alan Stern wrote: @@ -1279,6 +1284,9 @@ ep0_poll (struct file *fd, poll_table *w struct dev_data *dev = fd-private_data; int mask = 0; + if (dev-state = STATE_DEV_OPENED) + return -ENODEV; + poll_wait(fd, dev-wait, wait); spin_lock_irq (dev-lock); That, BTW, is wrong. -poll() does *not* return negatives - to imitate we don't have -poll() we need it to return DEFAULT_POLLMASK. -- 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] drivers: usb: gadget: udc: Fix NULL dereference
On Tue, Mar 03, 2015 at 06:28:42PM +0530, Tapasweni Pathak wrote: This patch fixes multiple instances of null pointer dereference in this code. ep-udc is assigned to udc. ep is just an offset from _ep. _ep is then checked for NULL. udc is dereferenced under the NULL check for _ep, making an invalid pointer reference. udc is then checked for NULL, if NULL, it is then dereferenced as udc-dev. To fix these issues, shift assignment of udc by dereferencing ep after null check for _ep, replace both dev_dbg statements with pr_debug. Found using Coccinelle. Signed-off-by: Tapasweni Pathak tapaswenipat...@gmail.com Suggested-by : Julia Lawall julia.law...@lip6.fr Reviewed-by : Julia Lawall julia.law...@lip6.fr --- drivers/usb/gadget/udc/lpc32xx_udc.c |7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 27fd413..6398539 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -1807,17 +1807,16 @@ static int lpc32xx_ep_queue(struct usb_ep *_ep, !list_empty(req-queue)) return -EINVAL; - udc = ep-udc; - if (!_ep) { - dev_dbg(udc-dev, invalid ep\n); + pr_debug(invalid ep\n); return -EINVAL; } + udc = ep-udc; if ((!udc) || (!udc-driver) || (udc-gadget.speed == USB_SPEED_UNKNOWN)) { - dev_dbg(udc-dev, invalid device\n); + pr_debug(invalid device\n); return -EINVAL; } It is driver code, we'd better use dev_dbg. If _ep exists, both ep and udc should exist. So, how about just checking _ep at the beginning: diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 27fd413..c65de0e 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -1803,7 +1803,7 @@ static int lpc32xx_ep_queue(struct usb_ep *_ep, req = container_of(_req, struct lpc32xx_request, req); ep = container_of(_ep, struct lpc32xx_ep, ep); - if (!_req || !_req-complete || !_req-buf || + if (!_ep || !_req || !_req-complete || !_req-buf || !list_empty(req-queue)) return -EINVAL; @@ -1815,8 +1815,7 @@ static int lpc32xx_ep_queue(struct usb_ep *_ep, } - if ((!udc) || (!udc-driver) || - (udc-gadget.speed == USB_SPEED_UNKNOWN)) { + if ((!udc-driver) || (udc-gadget.speed == USB_SPEED_UNKNOWN)) { dev_dbg(udc-dev, invalid device\n); return -EINVAL; } -- 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: Request for comments
Hello Joao, Joao Pinto wrote: This new feature basically is to turn the relationship between driver and hardware IP more transparent, making the software more robust. This is an important matter already today, and will only become more important in the future. a) The hardware has the capability of supplying to the driver the IP version and crucial features that it support or not b) The driver would read the hardware capability features and work without hick-ups even if the developer has configured him (e.g. menuconfig during build process) to do some specific thing that is not supported by the current connected hardware Once the driver supports auto-detecting these features, I think that the manual configuration shall be removed. c) If the driver is configured to do something that the connected hardware is not capable of doing, it simply logs a message to kernel log and automatically disables it trying to work has fluid as possible How the driver reacts in this situation is a matter of policy, which should probably not be specific to any one driver, but should probably be set at a slightly higher level, perhaps even by the person configuring/building the kernel. d) If the hardware does not have the capability of supplying information of this type to the driver, than it should work according to the configuration Hm? Can you be more specific? If it is *possible* for the combination of hardware+driver to work according to the configuration, why would the driver ever do anything else? In your opinion this feature would be a value-added to a new driver / existent driver? In general I feel strongly that hardware and drivers must stay close to each other, but some of the things you described are not completely clear to me, so it is difficult to give specific feedback. Can you provide more details? Thanks //Peter -- 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: gadgetfs broken since 7f7f25e8
On Mon, Mar 02, 2015 at 02:02:56PM +0100, Alexander Holler wrote: I exactly did what you've assumed, I've just fixed f_mode but not the already existing races which I haven't introduced. So I was right in not sending a patch as would have been blamed for not rewriting everything as so often. Another quick solution would be to just add some dummy ops for read/write to those file_operations which are missing it which are only returning -EINVAL or some other error which might make sense. Looking at that thing again... why do they need to be dummy? After all, those methods start with get_ready_ep(), which will fail unless we have -state == STATE_EP_ENABLED. So they'd be failing just fine until that first write() anyway. Let's do the following: * get_ready_ep() gets a new argument - true when called from ep_write_iter(), false otherwise. * make it quiet when it finds STATE_EP_READY (no printk, that is; the case won't be impossible after that change). * when that new argument is true, treat STATE_EP_READY the same way as STATE_EP_ENABLED (i.e. return zero and do not unlock). * in ep_write_iter(), after success of get_ready_ep() turn if (!usb_endpoint_dir_in(epdata-desc)) { into if (epdata-state == STATE_EP_ENABLED !usb_endpoint_dir_in(epdata-desc)) { - that logics only applies after config. * have ep_config() take kernel-side buffer (i.e. use memcpy() instead of copy_from_user() in there) and in the let's call ep_io or ep_aio (again, in ep_write_iter()) add ... or ep_config() in case it's not configured yet IOW, how about the following (completely untested) patch on top of vfs.git#gadget? Comments? diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index b825edc..c0e2532 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -74,6 +74,8 @@ MODULE_DESCRIPTION (DRIVER_DESC); MODULE_AUTHOR (David Brownell); MODULE_LICENSE (GPL); +static int ep_open(struct inode *, struct file *); + /*--*/ @@ -283,14 +285,15 @@ static void epio_complete (struct usb_ep *ep, struct usb_request *req) * still need dev-lock to use epdata-ep. */ static int -get_ready_ep (unsigned f_flags, struct ep_data *epdata) +get_ready_ep (unsigned f_flags, struct ep_data *epdata, bool is_write) { int val; if (f_flags O_NONBLOCK) { if (!mutex_trylock(epdata-lock)) goto nonblock; - if (epdata-state != STATE_EP_ENABLED) { + if (epdata-state != STATE_EP_ENABLED + (!is_write || epdata-state != STATE_EP_READY)) { mutex_unlock(epdata-lock); nonblock: val = -EAGAIN; @@ -305,18 +308,20 @@ nonblock: switch (epdata-state) { case STATE_EP_ENABLED: + return 0; + case STATE_EP_READY:/* not configured yet */ + if (is_write) + return 0; + // FALLTHRU + case STATE_EP_UNBOUND: /* clean disconnect */ break; // case STATE_EP_DISABLED: /* can't happen */ - // case STATE_EP_READY: /* can't happen */ default:/* error! */ pr_debug (%s: ep %p not available, state %d\n, shortname, epdata, epdata-state); - // FALLTHROUGH - case STATE_EP_UNBOUND: /* clean disconnect */ - val = -ENODEV; - mutex_unlock(epdata-lock); } - return val; + mutex_unlock(epdata-lock); + return -ENODEV; } static ssize_t @@ -390,7 +395,7 @@ static long ep_ioctl(struct file *fd, unsigned code, unsigned long value) struct ep_data *data = fd-private_data; int status; - if ((status = get_ready_ep (fd-f_flags, data)) 0) + if ((status = get_ready_ep (fd-f_flags, data, false)) 0) return status; spin_lock_irq (data-dev-lock); @@ -572,7 +577,7 @@ ep_read_iter(struct kiocb *iocb, struct iov_iter *to) ssize_t value; char *buf; - if ((value = get_ready_ep(file-f_flags, epdata)) 0) + if ((value = get_ready_ep(file-f_flags, epdata, false)) 0) return value; /* halt any endpoint by doing a wrong direction i/o call */ @@ -620,20 +625,25 @@ fail: return value; } +static ssize_t ep_config(struct ep_data *, const char *, size_t); + static ssize_t ep_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb-ki_filp; struct ep_data *epdata = file-private_data; size_t len = iov_iter_count(from); + bool configured; ssize_t value; char *buf; -
Re: [PATCH] udc: gadget: atmel_usba_udc: depend on COMMON_CLK_AT91
On 03/03/2015 at 09:26:20 +0100, Boris Brezillon wrote : config USB_ATMEL_USBA tristate Atmel USBA - depends on AVR32 || ARCH_AT91 + depends on AVR32 || ARCH_AT91 COMMON_CLK_AT91 I guess you should add parenthesis to make it clearer ? depends on AVR32 || (ARCH_AT91 COMMON_CLK_AT91) And I wonder why you need that. I though this option was selected by all at91 platforms ? That is currently the case but maybe, one day, one of the AT91 platform will not use the same clock driver. -- Alexandre Belloni, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com -- 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
[PATCHv3 05/29] usb: gadget: printer: revert usb_add_function() effect in error recovery
Whenever the goto fail branch is taken, the effect of usb_add_function() should be reverted. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 12247d3..eb02a6b 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1285,6 +1285,7 @@ static int __init printer_bind_config(struct usb_configuration *c) fail: printer_cfg_unbind(c); + usb_remove_function(c, dev-function); return status; } -- 1.9.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
[PATCHv3 10/29] usb: gadget: printer: move function-related bind code to function's bind
In order to factor out a reusable f_printer.c, the code related to the function should be placed in functions related to the function. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 114 +--- 1 file changed, 66 insertions(+), 48 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 494cd8a..c857044 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -85,6 +85,7 @@ struct printer_dev { struct cdev printer_cdev; u8 printer_cdev_open; wait_queue_head_t wait; + unsignedq_len; struct usb_function function; }; @@ -1045,18 +1046,25 @@ unknown: static int __init printer_func_bind(struct usb_configuration *c, struct usb_function *f) { + struct usb_gadget *gadget = c-cdev-gadget; struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct device *pdev; struct usb_composite_dev *cdev = c-cdev; struct usb_ep *in_ep; struct usb_ep *out_ep = NULL; + struct usb_request *req; int id; int ret; + u32 i; id = usb_interface_id(c, f); if (id 0) return id; intf_desc.bInterfaceNumber = id; + /* finish hookup to lower layer ... */ + dev-gadget = gadget; + /* all we really need is bulk IN/OUT */ in_ep = usb_ep_autoconfig(cdev-gadget, fs_ep_in_desc); if (!in_ep) { @@ -1085,7 +1093,64 @@ autoconf_fail: dev-in_ep = in_ep; dev-out_ep = out_ep; + + ret = -ENOMEM; + for (i = 0; i dev-q_len; i++) { + req = printer_req_alloc(dev-in_ep, USB_BUFSIZE, GFP_KERNEL); + if (!req) + goto fail_tx_reqs; + list_add(req-list, dev-tx_reqs); + } + + for (i = 0; i dev-q_len; i++) { + req = printer_req_alloc(dev-out_ep, USB_BUFSIZE, GFP_KERNEL); + if (!req) + goto fail_rx_reqs; + list_add(req-list, dev-rx_reqs); + } + + /* Setup the sysfs files for the printer gadget. */ + pdev = device_create(usb_gadget_class, NULL, g_printer_devno, + NULL, g_printer); + if (IS_ERR(pdev)) { + ERROR(dev, Failed to create device: g_printer\n); + ret = PTR_ERR(pdev); + goto fail_rx_reqs; + } + + /* +* Register a character device as an interface to a user mode +* program that handles the printer specific functionality. +*/ + cdev_init(dev-printer_cdev, printer_io_operations); + dev-printer_cdev.owner = THIS_MODULE; + ret = cdev_add(dev-printer_cdev, g_printer_devno, 1); + if (ret) { + ERROR(dev, Failed to open char device\n); + goto fail_cdev_add; + } + return 0; + +fail_cdev_add: + device_destroy(usb_gadget_class, g_printer_devno); + +fail_rx_reqs: + while (!list_empty(dev-rx_reqs)) { + req = container_of(dev-rx_reqs.next, struct usb_request, list); + list_del(req-list); + printer_req_free(dev-out_ep, req); + } + +fail_tx_reqs: + while (!list_empty(dev-tx_reqs)) { + req = container_of(dev-tx_reqs.next, struct usb_request, list); + list_del(req-list); + printer_req_free(dev-in_ep, req); + } + + return ret; + } static void printer_func_unbind(struct usb_configuration *c, @@ -1173,13 +1238,9 @@ static struct usb_configuration printer_cfg_driver = { static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, unsigned q_len) { - struct usb_gadget *gadget = c-cdev-gadget; struct printer_dev *dev; - struct device *pdev; int status = -ENOMEM; size_t len; - u32 i; - struct usb_request *req; dev = usb_printer_gadget; @@ -1193,31 +1254,11 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, INIT_LIST_HEAD(dev-rx_reqs); INIT_LIST_HEAD(dev-rx_buffers); + dev-q_len = q_len; status = usb_add_function(c, dev-function); if (status) return status; - /* Setup the sysfs files for the printer gadget. */ - pdev = device_create(usb_gadget_class, NULL, g_printer_devno, - NULL, g_printer); - if (IS_ERR(pdev)) { - ERROR(dev, Failed to create device: g_printer\n); - status = PTR_ERR(pdev); - goto fail; - } - - /* -* Register a character device as an interface
[PATCHv3 29/29] usb: gadget: printer: add configfs support
Add support for configfs interface so that f_printer can be used as a component of usb gadgets composed with it. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- .../ABI/testing/configfs-usb-gadget-printer| 9 ++ Documentation/usb/gadget-testing.txt | 47 drivers/usb/gadget/Kconfig | 13 +++ drivers/usb/gadget/function/f_printer.c| 130 - drivers/usb/gadget/function/u_printer.h| 7 ++ 5 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-printer diff --git a/Documentation/ABI/testing/configfs-usb-gadget-printer b/Documentation/ABI/testing/configfs-usb-gadget-printer new file mode 100644 index 000..6b0714e --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-printer @@ -0,0 +1,9 @@ +What: /config/usb-gadget/gadget/functions/printer.name +Date: Apr 2015 +KernelVersion: 4.1 +Description: + The attributes: + + pnp_string - Data to be passed to the host in pnp string + q_len - Number of requests per endpoint + diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index 076ac7b..f45b2bf 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -19,6 +19,7 @@ provided by gadgets. 16. UAC1 function 17. UAC2 function 18. UVC function +19. PRINTER function 1. ACM function @@ -726,3 +727,49 @@ with these patches: http://www.spinics.net/lists/linux-usb/msg99220.html host: luvcview -f yuv + +19. PRINTER function + + +The function is provided by usb_f_printer.ko module. + +Function-specific configfs interface + + +The function name to use when creating the function directory is printer. +The printer function provides these attributes in its function directory: + + pnp_string - Data to be passed to the host in pnp string + q_len - Number of requests per endpoint + +Testing the PRINTER function + + +The most basic testing: + +device: run the gadget +# ls -l /devices/virtual/usb_printer_gadget/ + +should show g_printernumber. + +If udev is active, then /dev/g_printernumber should appear automatically. + +host: + +If udev is active, then e.g. /dev/usb/lp0 should appear. + +host-device transmission: + +device: +# cat /dev/g_printernumber +host: +# cat /dev/usb/lp0 + +device-host transmission: + +# cat /dev/g_printernumber +host: +# cat /dev/usb/lp0 + +More advanced testing can be done with the prn_example +described in Documentation/usb/gadget-printer.txt. diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 9d507cf..3bb0e67 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -437,6 +437,19 @@ config USB_CONFIGFS_F_UVC device. It provides a userspace API to process UVC control requests and stream video data to the host. +config USB_CONFIGFS_F_PRINTER + bool Printer function + select USB_F_PRINTER + help + The Printer function channels data between the USB host and a + userspace program driving the print engine. The user space + program reads and writes the device file /dev/g_printerX to + receive or send printer data. It can use ioctl calls to + the device file to get or set printer status. + + For more information, see Documentation/usb/gadget_printer.txt + which includes sample code for accessing the device file. + source drivers/usb/gadget/legacy/Kconfig endchoice diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 7afe17d..757fcf0 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -1140,6 +1140,117 @@ static void printer_func_disable(struct usb_function *f) spin_unlock_irqrestore(dev-lock, flags); } +static inline struct f_printer_opts +*to_f_printer_opts(struct config_item *item) +{ + return container_of(to_config_group(item), struct f_printer_opts, + func_inst.group); +} + +CONFIGFS_ATTR_STRUCT(f_printer_opts); +CONFIGFS_ATTR_OPS(f_printer_opts); + +static void printer_attr_release(struct config_item *item) +{ + struct f_printer_opts *opts = to_f_printer_opts(item); + + usb_put_function_instance(opts-func_inst); +} + +static struct configfs_item_operations printer_item_ops = { + .release= printer_attr_release, + .show_attribute = f_printer_opts_attr_show, + .store_attribute = f_printer_opts_attr_store, +}; + +static ssize_t f_printer_opts_pnp_string_show(struct f_printer_opts *opts, + char *page) +{ + int result; + + mutex_lock(opts-lock); + result = strlcpy(page,
[PATCHv3 24/29] usb: gadget: printer: factor out f_printer
The legacy printer gadget now contains both a reusable printer function and legacy gadget proper implementations interwoven, but logically separate. This patch factors out a reusable f_printer. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/function/f_printer.c | 1279 +++ drivers/usb/gadget/legacy/printer.c | 1255 +- 2 files changed, 1285 insertions(+), 1249 deletions(-) create mode 100644 drivers/usb/gadget/function/f_printer.c diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c new file mode 100644 index 000..0847972 --- /dev/null +++ b/drivers/usb/gadget/function/f_printer.c @@ -0,0 +1,1279 @@ +/* + * f_printer.c - USB printer function driver + * + * Copied from drivers/usb/gadget/legacy/printer.c, + * which was: + * + * printer.c -- Printer gadget driver + * + * Copyright (C) 2003-2005 David Brownell + * Copyright (C) 2006 Craig W. Nadler + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include linux/module.h +#include linux/kernel.h +#include linux/delay.h +#include linux/ioport.h +#include linux/sched.h +#include linux/slab.h +#include linux/mutex.h +#include linux/errno.h +#include linux/init.h +#include linux/timer.h +#include linux/list.h +#include linux/interrupt.h +#include linux/device.h +#include linux/moduleparam.h +#include linux/fs.h +#include linux/poll.h +#include linux/types.h +#include linux/ctype.h +#include linux/cdev.h + +#include asm/byteorder.h +#include linux/io.h +#include linux/irq.h +#include linux/uaccess.h +#include asm/unaligned.h + +#include linux/usb/ch9.h +#include linux/usb/composite.h +#include linux/usb/gadget.h +#include linux/usb/g_printer.h + +#define PNP_STRING_LEN 1024 +#define PRINTER_MINORS 4 +#define GET_DEVICE_ID 0 +#define GET_PORT_STATUS1 +#define SOFT_RESET 2 + +static int major, minors; +static struct class *usb_gadget_class; + +/*-*/ + +struct printer_dev { + spinlock_t lock; /* lock this structure */ + /* lock buffer lists during read/write calls */ + struct mutexlock_printer_io; + struct usb_gadget *gadget; + s8 interface; + struct usb_ep *in_ep, *out_ep; + + struct list_headrx_reqs;/* List of free RX structs */ + struct list_headrx_reqs_active; /* List of Active RX xfers */ + struct list_headrx_buffers; /* List of completed xfers */ + /* wait until there is data to be read. */ + wait_queue_head_t rx_wait; + struct list_headtx_reqs;/* List of free TX structs */ + struct list_headtx_reqs_active; /* List of Active TX xfers */ + /* Wait until there are write buffers available to use. */ + wait_queue_head_t tx_wait; + /* Wait until all write buffers have been sent. */ + wait_queue_head_t tx_flush_wait; + struct usb_request *current_rx_req; + size_t current_rx_bytes; + u8 *current_rx_buf; + u8 printer_status; + u8 reset_printer; + int minor; + struct cdev printer_cdev; + u8 printer_cdev_open; + wait_queue_head_t wait; + unsignedq_len; + char*pnp_string;/* We don't own memory! */ + struct usb_function function; +}; + +static inline struct printer_dev *func_to_printer(struct usb_function *f) +{ + return container_of(f, struct printer_dev, function); +} + +/*-*/ + +/* + * DESCRIPTORS ... most are static, but strings and (full) configuration + * descriptors are built on demand. + */ + +/* holds our biggest descriptor */ +#define USB_DESC_BUFSIZE 256 +#define USB_BUFSIZE8192 + +static struct usb_interface_descriptor intf_desc = { + .bLength = sizeof(intf_desc), + .bDescriptorType = USB_DT_INTERFACE, + .bNumEndpoints =2, + .bInterfaceClass = USB_CLASS_PRINTER, + .bInterfaceSubClass = 1, /* Printer Sub-Class */ + .bInterfaceProtocol = 2, /* Bi-Directional */ + .iInterface = 0 +}; + +static struct usb_endpoint_descriptor fs_ep_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress =
[PATCHv3 11/29] usb: gadget: printer: call usb_add_function() last
Conversion to the new function interface requires splitting a something_bind_config() function into two parts: allocation of container_of struct usb_function and invocation of usb_add_function(). This patch moves the latter to the end of the f_printer_bind_config() in order to enable conversion to the new interface. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index c857044..5dbb93a 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1254,11 +1254,6 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, INIT_LIST_HEAD(dev-rx_reqs); INIT_LIST_HEAD(dev-rx_buffers); - dev-q_len = q_len; - status = usb_add_function(c, dev-function); - if (status) - return status; - if (pnp_str) strlcpy(pnp_string[2], pnp_str, sizeof(pnp_string) - 2); @@ -1280,7 +1275,11 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, dev-current_rx_req = NULL; dev-current_rx_bytes = 0; dev-current_rx_buf = NULL; + dev-q_len = q_len; + status = usb_add_function(c, dev-function); + if (status) + return status; INFO(dev, %s, version: DRIVER_VERSION \n, driver_desc); return 0; } -- 1.9.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
[PATCHv3 28/29] usb: gadget: printer: use module_usb_composite_driver helper macro
Substitute some boilerplate code with a dedicated macro. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 14 +- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index a8050f8..d5b6ee7 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -208,19 +208,7 @@ static __refdata struct usb_composite_driver printer_driver = { .unbind = printer_unbind, }; -static int __init -init(void) -{ - return usb_composite_probe(printer_driver); -} -module_init(init); - -static void __exit -cleanup(void) -{ - usb_composite_unregister(printer_driver); -} -module_exit(cleanup); +module_usb_composite_driver(printer_driver); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR(Craig Nadler); -- 1.9.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
[PATCHv3 21/29] usb: gadget: printer: name class specific requests
Avoid using magic numbers. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 955847f..78f5154 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -47,6 +47,9 @@ USB_GADGET_COMPOSITE_OPTIONS(); #define DRIVER_DESCPrinter Gadget #define DRIVER_VERSION 2007 OCT 06 +#define GET_DEVICE_ID 0 +#define GET_PORT_STATUS1 +#define SOFT_RESET 2 static const char shortname [] = printer; static const char driver_desc [] = DRIVER_DESC; @@ -992,7 +995,7 @@ static int printer_func_setup(struct usb_function *f, switch (ctrl-bRequestTypeUSB_TYPE_MASK) { case USB_TYPE_CLASS: switch (ctrl-bRequest) { - case 0: /* Get the IEEE-1284 PNP String */ + case GET_DEVICE_ID: /* Get the IEEE-1284 PNP String */ /* Only one printer interface is supported. */ if ((wIndex8) != dev-interface) break; @@ -1003,7 +1006,7 @@ static int printer_func_setup(struct usb_function *f, dev-pnp_string[2]); break; - case 1: /* Get Port Status */ + case GET_PORT_STATUS: /* Get Port Status */ /* Only one printer interface is supported. */ if (wIndex != dev-interface) break; @@ -1012,7 +1015,7 @@ static int printer_func_setup(struct usb_function *f, value = min(wLength, (u16) 1); break; - case 2: /* Soft Reset */ + case SOFT_RESET: /* Soft Reset */ /* Only one printer interface is supported. */ if (wIndex != dev-interface) break; -- 1.9.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
[PATCHv3 23/29] usb: gadget: printer: allocate printer_dev instances dynamically
With all the obstacles removed it is possible to allow more than one instance of the printer function. Since the function requires allocating character device region, a maximum number of allowed instances is defined. Such an approach is used in f_acm and in f_hid. With multiple instances it does not make sense to depend on a lock_printer_io member of a dynamically allocated (and destroyed) struct printer_dev to clean up after all instances of the printer function. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 62 - 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index c059af1..d1f85f8 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -51,11 +51,12 @@ USB_GADGET_COMPOSITE_OPTIONS(); #define GET_PORT_STATUS1 #define SOFT_RESET 2 +#define PRINTER_MINORS 4 + static const char shortname [] = printer; static const char driver_desc [] = DRIVER_DESC; -static dev_t g_printer_devno; - +static int major, minors; static struct class *usb_gadget_class; /*-*/ @@ -84,6 +85,7 @@ struct printer_dev { u8 *current_rx_buf; u8 printer_status; u8 reset_printer; + int minor; struct cdev printer_cdev; u8 printer_cdev_open; wait_queue_head_t wait; @@ -97,8 +99,6 @@ static inline struct printer_dev *func_to_printer(struct usb_function *f) return container_of(f, struct printer_dev, function); } -static struct printer_dev usb_printer_gadget; - /*-*/ /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! @@ -1096,6 +1096,7 @@ static int __init printer_func_bind(struct usb_configuration *c, struct usb_ep *in_ep; struct usb_ep *out_ep = NULL; struct usb_request *req; + dev_t devt; int id; int ret; u32 i; @@ -1153,8 +1154,9 @@ autoconf_fail: } /* Setup the sysfs files for the printer gadget. */ - pdev = device_create(usb_gadget_class, NULL, g_printer_devno, - NULL, g_printer); + devt = MKDEV(major, dev-minor); + pdev = device_create(usb_gadget_class, NULL, devt, + NULL, g_printer%d, dev-minor); if (IS_ERR(pdev)) { ERROR(dev, Failed to create device: g_printer\n); ret = PTR_ERR(pdev); @@ -1167,7 +1169,7 @@ autoconf_fail: */ cdev_init(dev-printer_cdev, printer_io_operations); dev-printer_cdev.owner = THIS_MODULE; - ret = cdev_add(dev-printer_cdev, g_printer_devno, 1); + ret = cdev_add(dev-printer_cdev, devt, 1); if (ret) { ERROR(dev, Failed to open char device\n); goto fail_cdev_add; @@ -1176,7 +1178,7 @@ autoconf_fail: return 0; fail_cdev_add: - device_destroy(usb_gadget_class, g_printer_devno); + device_destroy(usb_gadget_class, devt); fail_rx_reqs: while (!list_empty(dev-rx_reqs)) { @@ -1204,7 +1206,7 @@ static void printer_func_unbind(struct usb_configuration *c, dev = func_to_printer(f); - device_destroy(usb_gadget_class, g_printer_devno); + device_destroy(usb_gadget_class, MKDEV(major, dev-minor)); /* Remove Character Device */ cdev_del(dev-printer_cdev); @@ -1238,6 +1240,7 @@ static void printer_func_unbind(struct usb_configuration *c, printer_req_free(dev-out_ep, req); } usb_free_all_descriptors(f); + kfree(dev); } static int printer_func_set_alt(struct usb_function *f, @@ -1271,14 +1274,21 @@ static struct usb_configuration printer_cfg_driver = { }; static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, -char *pnp_string, unsigned q_len) +char *pnp_string, unsigned q_len, int minor) { struct printer_dev *dev; int status = -ENOMEM; size_t len; - dev = usb_printer_gadget; + if (minor = minors) + return -ENOENT; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + dev-pnp_string = pnp_string; + dev-minor = minor; dev-function.name = shortname; dev-function.bind = printer_func_bind; @@ -1315,8 +1325,10 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, dev-q_len = q_len; status = usb_add_function(c, dev-function); -
[PATCHv3 22/29] usb: gadget: printer: add req_match for printer function
Verify that a given usb_ctrlrequest is meant for printer function. The following parts of the request are tested: - bmRequestType:Data transfer direction - bmRequestType:Type - bmRequestType:Recipient - bRequest - wValue for bRequest 1 and 2 - wLength Additionally, the request is considered meant for this function iff the decoded interface number matches dev-interface. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 78f5154..c059af1 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -974,6 +974,41 @@ static void printer_soft_reset(struct printer_dev *dev) /*-*/ +static bool gprinter_req_match(struct usb_function *f, + const struct usb_ctrlrequest *ctrl) +{ + struct printer_dev *dev = func_to_printer(f); + u16 w_index = le16_to_cpu(ctrl-wIndex); + u16 w_value = le16_to_cpu(ctrl-wValue); + u16 w_length = le16_to_cpu(ctrl-wLength); + + if ((ctrl-bRequestType USB_RECIP_MASK) != USB_RECIP_INTERFACE || + (ctrl-bRequestType USB_TYPE_MASK) != USB_TYPE_CLASS) + return false; + + switch (ctrl-bRequest) { + case GET_DEVICE_ID: + w_index = 8; + if (w_length = PNP_STRING_LEN + (USB_DIR_IN ctrl-bRequestType)) + break; + return false; + case GET_PORT_STATUS: + if (!w_value w_length == 1 + (USB_DIR_IN ctrl-bRequestType)) + break; + return false; + case SOFT_RESET: + if (!w_value !w_length + (USB_DIR_OUT ctrl-bRequestType)) + break; + /* fall through */ + default: + return false; + } + return w_index == dev-interface; +} + /* * The setup() callback implements all the ep0 functionality that's not * handled lower down. @@ -1251,6 +1286,7 @@ static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, dev-function.unbind = printer_func_unbind; dev-function.set_alt = printer_func_set_alt; dev-function.disable = printer_func_disable; + dev-function.req_match = gprinter_req_match; INIT_LIST_HEAD(dev-tx_reqs); INIT_LIST_HEAD(dev-rx_reqs); INIT_LIST_HEAD(dev-rx_buffers); -- 1.9.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
[PATCHv3 19/29] usb: gadget: printer: add container_of helper for printer_dev
5 uses of container_of() in the same context justify wrapping it in a static inline function. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 806475c..955847f 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -89,6 +89,11 @@ struct printer_dev { struct usb_function function; }; +static inline struct printer_dev *func_to_printer(struct usb_function *f) +{ + return container_of(f, struct printer_dev, function); +} + static struct printer_dev usb_printer_gadget; /*-*/ @@ -973,7 +978,7 @@ static void printer_soft_reset(struct printer_dev *dev) static int printer_func_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { - struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct printer_dev *dev = func_to_printer(f); struct usb_composite_dev *cdev = f-config-cdev; struct usb_request *req = cdev-req; int value = -EOPNOTSUPP; @@ -1047,7 +1052,7 @@ static int __init printer_func_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_gadget *gadget = c-cdev-gadget; - struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct printer_dev *dev = func_to_printer(f); struct device *pdev; struct usb_composite_dev *cdev = c-cdev; struct usb_ep *in_ep; @@ -1159,7 +1164,7 @@ static void printer_func_unbind(struct usb_configuration *c, struct printer_dev *dev; struct usb_request *req; - dev = container_of(f, struct printer_dev, function); + dev = func_to_printer(f); device_destroy(usb_gadget_class, g_printer_devno); @@ -1200,7 +1205,7 @@ static void printer_func_unbind(struct usb_configuration *c, static int printer_func_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { - struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct printer_dev *dev = func_to_printer(f); int ret = -ENOTSUPP; if (!alt) @@ -1211,7 +1216,7 @@ static int printer_func_set_alt(struct usb_function *f, static void printer_func_disable(struct usb_function *f) { - struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct printer_dev *dev = func_to_printer(f); unsigned long flags; DBG(dev, %s\n, __func__); -- 1.9.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 2/8] ARM OMAP2+ GPMC: add bus children
Hi Roger, On Tue, Mar 3, 2015 at 11:09 AM, Roger Quadros rog...@ti.com wrote: If that is the case then I'd rather not check for return value of of_platform_populate(). Failure in populating GPMC child's children is already out of scope of GPMC driver. Well, I'd rather leave it in for now. If something *does* break in the future, the user will at least get a message about it. Regards, Robert -- 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
[PATCHv3 00/29] Equivalent of g_printer with configfs
This series aims at integrating configfs into printer, the way it has been done for acm, ncm, ecm, eem, ecm subset, rndis, obex, phonet, mass_storage, FunctionFS, loopback, sourcesink, uac1, uac2, uvc, midi and hid. The printer gadget before the changes has some bugs, and although it uses the composite framework, it is not ready for splitting into a reusable f_printer.c and a legacy printer.c. Most of the patches in the series are preparation for factoring out f_printer.c. Once f_printer.c is extracted from printer.c, it can be converted to use the new function interface, and then the usual procedure of adding configfs support follows. Rebased onto Felipe's testing/next. v2..v3: - merged v1 with v2 version - fixed the bug with handling of req_match method according to Bin Liu's suggestion - removed Felipe's Signed-off-by because the whole v1 + v2 series was dropped by him BACKWARD COMPATIBILITY == Please note that the old g_printer.ko is still available and works. There is just one minor difference, the dev node at the gadget's side is called /dev/g_printernumber instead of /dev/g_printer. This makes sense, because there are more than one instances of this function allowed after the series is applied. If /dev/g_printer is needed, it can be easily added as a symlink with udev rules. 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/printer.instance name e.g. mkdir functions/printer.usb0. In the printer.usb0 directory there will be the following attributes: pnp_string - Data to be passed to the host in pnp string q_len - Number of requests per endpoint. Below is a script which creates a printer gadget on a board with dwc2: $ modprobe libcomposite $ mount none cfg -t configfs $ mkdir cfg/usb_gadget/g1 $ cd cfg/usb_gadget/g1 $ mkdir configs/c.1 $ mkdir functions/printer.usb0 $ mkdir strings/0x409 $ mkdir configs/c.1/strings/0x409 $ echo 0x0525 idVendor $ echo 0xa4a8 idProduct $ echo 1 strings/0x409/serialnumber $ echo Samsung strings/0x409/manufacturer $ echo Printer Gadget strings/0x409/product $ echo 10 functions/printer.usb0/q_len $ echo MFG:linux;MDL:g_printer;CLS:PRINTER;SN:1; functions/printer.usb0/pnp_string $ echo Conf 1 configs/c.1/strings/0x409/configuration $ echo 120 configs/c.1/MaxPower $ ln -s functions/printer.usb0 configs/c.1 $ echo 1248.hsotg UDC TESTING THE FUNCTION The most basic testing: device: run the gadget, ls -l /devices/virtual/usb_printer_gadget/ should show g_printernumber. If udev is active, then /dev/g_printernumber should appear automatically. host: If udev is active, then e.g. /dev/usb/lp0 should appear. host-device transmission: device: # cat /dev/g_printernumber host: # cat /dev/usb/lp0 device-host transmission: # cat /dev/g_printernumber host: # cat /dev/usb/lp0 More advanced testing can be done with the prn_example described in Documentation/usb/gadget-printer.txt. Andrzej Pietrasiewicz (29): usb: gadget: composite: don't try standard handling for non-standard requests usb: gadget: printer: enqueue printer's response for setup request usb: gadget: printer: remove unused and empty printer_unbind usb: gadget: printer: eliminate random pointer dereference usb: gadget: printer: revert usb_add_function() effect in error recovery usb: gadget: printer: add missing error handling usb: gadget: printer: eliminate pdev member of struct printer_dev usb: gadget: printer: follow the naming convention for usb_add_config callback usb: gadget: printer: standardize printer_do_config usb: gadget: printer: move function-related bind code to function's bind usb: gadget: printer: call usb_add_function() last usb: gadget: printer: move function-related unbind code to function's unbind usb: gadget: printer: define pnp string buffer length usb: gadget: printer: don't access file global pnp_string in function's code usb: gadget: printer: add setup and cleanup functions usb: gadget: printer: call gprinter_setup() from gadget's bind usb: gadget: printer: eliminate file global printer_mutex usb: gadget: printer: don't access file global usb_printer_gadget in function's code usb: gadget: printer: add container_of helper for printer_dev usb: gadget: composite: add req_match method to usb_function usb: gadget: printer: name class specific requests usb: gadget: printer: add req_match for printer function usb: gadget: printer: allocate printer_dev instances dynamically usb: gadget: printer: factor out f_printer usb: gadget: f_printer: convert to new function interface with backward compatibility usb:
[PATCHv3 03/29] usb: gadget: printer: remove unused and empty printer_unbind
The unbind() method is optional is usb_composite_driver. In this particular driver the method does nothing so it can be removed. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 6385c19..21ea317 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1288,11 +1288,6 @@ fail: return status; } -static int printer_unbind(struct usb_composite_dev *cdev) -{ - return 0; -} - static int __init printer_bind(struct usb_composite_dev *cdev) { int ret; @@ -1317,7 +1312,6 @@ static __refdata struct usb_composite_driver printer_driver = { .strings= dev_strings, .max_speed = USB_SPEED_SUPER, .bind = printer_bind, - .unbind = printer_unbind, }; static int __init -- 1.9.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
[PATCHv3 09/29] usb: gadget: printer: standardize printer_do_config
Follow the convention of distributing source code between something_do_config() and something_bind_config(). Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 39 +++-- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index c865833..494cd8a 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1170,7 +1170,8 @@ static struct usb_configuration printer_cfg_driver = { .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, }; -static int __init printer_do_config(struct usb_configuration *c) +static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str, +unsigned q_len) { struct usb_gadget *gadget = c-cdev-gadget; struct printer_dev *dev; @@ -1180,8 +1181,6 @@ static int __init printer_do_config(struct usb_configuration *c) u32 i; struct usb_request *req; - usb_ep_autoconfig_reset(gadget); - dev = usb_printer_gadget; dev-function.name = shortname; @@ -1219,21 +1218,13 @@ static int __init printer_do_config(struct usb_configuration *c) goto fail; } - if (iPNPstring) - strlcpy(pnp_string[2], iPNPstring, (sizeof pnp_string)-2); + if (pnp_str) + strlcpy(pnp_string[2], pnp_str, sizeof(pnp_string) - 2); len = strlen(pnp_string); pnp_string[0] = (len 8) 0xFF; pnp_string[1] = len 0xFF; - usb_gadget_set_selfpowered(gadget); - - if (gadget_is_otg(gadget)) { - otg_descriptor.bmAttributes |= USB_OTG_HNP; - printer_cfg_driver.descriptors = otg_desc; - printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; - } - spin_lock_init(dev-lock); mutex_init(dev-lock_printer_io); INIT_LIST_HEAD(dev-tx_reqs_active); @@ -1250,14 +1241,14 @@ static int __init printer_do_config(struct usb_configuration *c) dev-current_rx_buf = NULL; status = -ENOMEM; - for (i = 0; i QLEN; i++) { + for (i = 0; i q_len; i++) { req = printer_req_alloc(dev-in_ep, USB_BUFSIZE, GFP_KERNEL); if (!req) goto fail; list_add(req-list, dev-tx_reqs); } - for (i = 0; i QLEN; i++) { + for (i = 0; i q_len; i++) { req = printer_req_alloc(dev-out_ep, USB_BUFSIZE, GFP_KERNEL); if (!req) goto fail; @@ -1276,6 +1267,24 @@ fail: return status; } +static int __init printer_do_config(struct usb_configuration *c) +{ + struct usb_gadget *gadget = c-cdev-gadget; + + usb_ep_autoconfig_reset(gadget); + + usb_gadget_set_selfpowered(gadget); + + if (gadget_is_otg(gadget)) { + otg_descriptor.bmAttributes |= USB_OTG_HNP; + printer_cfg_driver.descriptors = otg_desc; + printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; + } + + return f_printer_bind_config(c, iPNPstring, QLEN); + +} + static int __init printer_bind(struct usb_composite_dev *cdev) { int ret; -- 1.9.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
[PATCHv3 02/29] usb: gadget: printer: enqueue printer's response for setup request
Function-specific setup requests should be handled in such a way, that apart from filling in the data buffer, the requests are also actually enqueued: if function-specific setup is called from composte_setup(), the usb_ep_queue() block of code in composite_setup() is skipped. The printer function lacks this part and it results in e.g. get device id requests failing: the host expects some response, the device prepares it but does not equeue it for sending to the host, so the host finally asserts timeout. This patch adds enqueueing the prepared responses. Cc: sta...@vger.kernel.org # v3.4+ Fixes: 2e87edf49227: usb: gadget: make g_printer use composite Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/legacy/printer.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 9054598..6385c19 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1031,6 +1031,15 @@ unknown: break; } /* host either stalls (value 0) or reports success */ + if (value = 0) { + req-length = value; + req-zero = value wLength; + value = usb_ep_queue(cdev-gadget-ep0, req, GFP_ATOMIC); + if (value 0) { + ERROR(dev, %s:%d Error!\n, __func__, __LINE__); + req-status = 0; + } + } return value; } -- 1.9.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 v2 3/3] ARM: mvebu: armada-385-ap: Enable USB3 port
On Mon, Mar 02, 2015 at 08:23:37PM +0100, Gregory CLEMENT wrote: Hi Maxime, On 19/01/2015 14:01, Maxime Ripard wrote: The Armada 385 AP board has a USB3 port exposed that uses a GPIO to drive the VBUS line. Enable the needed drivers to support this. it seems that this patch was not applied yet. Patch 1 is now in linux-next and should be part of 4.0-rc. But what about patch 2? IIRC, Greg or Matthias said that Matthias would look into these patches after the merge window. It still didn't happen though. Maxime -- Maxime Ripard, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com signature.asc Description: Digital signature
Re: [PATCH 2/8] ARM OMAP2+ GPMC: add bus children
Hi Robert, On 27/02/15 17:08, Robert Abel wrote: Hi Roger, On Fri, Feb 27, 2015 at 11:24 AM, Roger Quadros rog...@ti.com wrote: + /* is child a common bus? */ + if (of_match_node(of_default_bus_match_table, child)) + /* create children and other common bus children */ + if (of_platform_populate(child, of_default_bus_match_table, NULL, pdev-dev)) + goto err_child_fail; this would print failed to create gpmc child but we have already created the gpmc child in the first of_platform_device_create() call. A more appropriate message would be failed to populate all children of child-name Also do you want to return failure? it will result in of_node_put() of the child and another print message about probing gpmc child %s failed in gpmc_probe_dt(). IMO if the GPMC node's child was created fine then we shouldn't return error. As of_platform_populate _always_ return 0 no matter what, the only way to reach that message is if probing the child failed. GPMCs child is already probed. It is the child's child we are talking about in of_platform_populate. As I cannot see into the future when of_platform_populate might actually be changed to return meaningful codes, we shouldn't try to foresee what the actual problem might be today either. This is a battle for another day. If that is the case then I'd rather not check for return value of of_platform_populate(). Failure in populating GPMC child's children is already out of scope of GPMC driver. cheers, -roger -- 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