From 9b2035a0b9ee9745c236cc2ec1ec0b0eae692a1a Mon Sep 17 00:00:00 2001 From: Neil Zhang Date: Tue, 10 Jul 2012 10:07:01 +0800 Subject: usb: gadget: mv_udc: reduce the delay interval There are several places use udelay(LOOPS_USEC) to wait the status to be changed, but the delay interval is a bit too long, so reduce it to enhance the performance. Signed-off-by: Neil Zhang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 75db2c306cea..9e40f89635b2 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -53,7 +53,7 @@ #define READSAFE_TIMEOUT 1000 #define DTD_TIMEOUT 1000 -#define LOOPS_USEC_SHIFT 4 +#define LOOPS_USEC_SHIFT 1 #define LOOPS_USEC (1 << LOOPS_USEC_SHIFT) #define LOOPS(timeout) ((timeout) >> LOOPS_USEC_SHIFT) -- cgit v1.2.3-59-g8ed1b From a07bc24e2773e11cb4a6c03d72cd3cdb50c41914 Mon Sep 17 00:00:00 2001 From: Neil Zhang Date: Tue, 10 Jul 2012 10:07:02 +0800 Subject: usb: gadget: mv_udc: remove unused code Clean unused code for mv_udc driver. Signed-off-by: Neil Zhang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 9e40f89635b2..c05d340c7d02 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -51,7 +51,6 @@ #define EPSTATUS_TIMEOUT 10000 #define PRIME_TIMEOUT 10000 #define READSAFE_TIMEOUT 1000 -#define DTD_TIMEOUT 1000 #define LOOPS_USEC_SHIFT 1 #define LOOPS_USEC (1 << LOOPS_USEC_SHIFT) @@ -64,7 +63,6 @@ static const char driver_desc[] = DRIVER_DESC; /* controller device global variable */ static struct mv_udc *the_controller; -int mv_usb_otgsc; static void nuke(struct mv_ep *ep, int status); static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver); -- cgit v1.2.3-59-g8ed1b From 0344606bec0f3325ba9c1d4de74a5dd98911916d Mon Sep 17 00:00:00 2001 From: Neil Zhang Date: Tue, 10 Jul 2012 10:07:03 +0800 Subject: usb: gadget: mv_udc: avoid sleeping on spinlock build_dtd() can be called when hold a spinlock, but GFP_KERNEL may cause dma_pool_alloc() sleep, So we need use GFP_ATOMIC instead of GFP_KERNEL. But using GFP_ATOMIC may cause failure when allocating memory, add error handler to handle it. Signed-off-by: Alexey Khoroshilov Signed-off-by: Neil Zhang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 52 +++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 11 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index c05d340c7d02..425a204d29c2 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -373,7 +373,7 @@ static struct mv_dtd *build_dtd(struct mv_req *req, unsigned *length, * Be careful that no _GFP_HIGHMEM is set, * or we can not use dma_to_virt */ - dtd = dma_pool_alloc(udc->dtd_pool, GFP_KERNEL, dma); + dtd = dma_pool_alloc(udc->dtd_pool, GFP_ATOMIC, dma); if (dtd == NULL) return dtd; @@ -706,6 +706,7 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) struct mv_req *req = container_of(_req, struct mv_req, req); struct mv_udc *udc = ep->udc; unsigned long flags; + int retval; /* catch various bogus parameters */ if (!_req || !req->req.complete || !req->req.buf @@ -753,15 +754,17 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* build dtds and push them to device queue */ if (!req_to_dtd(req)) { - int retval; retval = queue_dtd(ep, req); if (retval) { spin_unlock_irqrestore(&udc->lock, flags); - return retval; + dev_err(&udc->dev->dev, "Failed to queue dtd\n"); + goto err_unmap_dma; } } else { spin_unlock_irqrestore(&udc->lock, flags); - return -ENOMEM; + dev_err(&udc->dev->dev, "Failed to dma_pool_alloc\n"); + retval = -ENOMEM; + goto err_unmap_dma; } /* Update ep0 state */ @@ -773,6 +776,22 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) spin_unlock_irqrestore(&udc->lock, flags); return 0; + +err_unmap_dma: + if (req->mapped) { + dma_unmap_single(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, + ((ep_dir(ep) == EP_DIR_IN) ? + DMA_TO_DEVICE : DMA_FROM_DEVICE)); + req->req.dma = DMA_ADDR_INVALID; + req->mapped = 0; + } else + dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, + ((ep_dir(ep) == EP_DIR_IN) ? + DMA_TO_DEVICE : DMA_FROM_DEVICE)); + + return retval; } static void mv_prime_ep(struct mv_ep *ep, struct mv_req *req) @@ -1497,15 +1516,17 @@ udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty) } /* prime the data phase */ - if (!req_to_dtd(req)) + if (!req_to_dtd(req)) { retval = queue_dtd(ep, req); - else{ /* no mem */ + if (retval) { + dev_err(&udc->dev->dev, + "Failed to queue dtd when prime status\n"); + goto out; + } + } else{ /* no mem */ retval = -ENOMEM; - goto out; - } - - if (retval) { - dev_err(&udc->dev->dev, "response error on GET_STATUS request\n"); + dev_err(&udc->dev->dev, + "Failed to dma_pool_alloc when prime status\n"); goto out; } @@ -1513,6 +1534,15 @@ udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty) return 0; out: + if (req->mapped) { + dma_unmap_single(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, + ((ep_dir(ep) == EP_DIR_IN) ? + DMA_TO_DEVICE : DMA_FROM_DEVICE)); + req->req.dma = DMA_ADDR_INVALID; + req->mapped = 0; + } + return retval; } -- cgit v1.2.3-59-g8ed1b From 583a7263c7ed05c9a625d50950551ba5749c9379 Mon Sep 17 00:00:00 2001 From: Neil Zhang Date: Tue, 10 Jul 2012 10:07:04 +0800 Subject: usb: gadget: mv_udc: enable stream mode According to ChipIdea's reference manual in section 8.5.2 "Non-streaming operational mode in device mode", we'd better enable stream mode, especially that ISO endpoints are not supported when the SDIS bit is set. Signed-off-by: Neil Zhang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 425a204d29c2..4d3a4136b376 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -1082,7 +1082,7 @@ static int udc_reset(struct mv_udc *udc) tmp |= USBMODE_CTRL_MODE_DEVICE; /* turn setup lockout off, require setup tripwire in usbcmd */ - tmp |= USBMODE_SETUP_LOCK_OFF | USBMODE_STREAM_DISABLE; + tmp |= USBMODE_SETUP_LOCK_OFF; writel(tmp, &udc->op_regs->usbmode); -- cgit v1.2.3-59-g8ed1b From 60326ce377090541db9ba1a05a041316ab5b46ec Mon Sep 17 00:00:00 2001 From: Chao Xie Date: Tue, 10 Jul 2012 10:07:05 +0800 Subject: usb: gadget: mv_udc: add iso support In order to support iso, we need do the following things: 1. fix length for one dtd 2. allow req contains multiple packets for a ISO transfer Signed-off-by: Chao Xie Signed-off-by: Yu Xu Signed-off-by: Neil Zhang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 4d3a4136b376..ff6154d1816e 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -355,17 +355,24 @@ done: return retval; } - static struct mv_dtd *build_dtd(struct mv_req *req, unsigned *length, dma_addr_t *dma, int *is_last) { - u32 temp; struct mv_dtd *dtd; struct mv_udc *udc; + struct mv_dqh *dqh; + u32 temp, mult = 0; /* how big will this transfer be? */ - *length = min(req->req.length - req->req.actual, - (unsigned)EP_MAX_LENGTH_TRANSFER); + if (usb_endpoint_xfer_isoc(req->ep->ep.desc)) { + dqh = req->ep->dqh; + mult = (dqh->max_packet_length >> EP_QUEUE_HEAD_MULT_POS) + & 0x3; + *length = min(req->req.length - req->req.actual, + (unsigned)(mult * req->ep->ep.maxpacket)); + } else + *length = min(req->req.length - req->req.actual, + (unsigned)EP_MAX_LENGTH_TRANSFER); udc = req->ep->udc; @@ -407,6 +414,8 @@ static struct mv_dtd *build_dtd(struct mv_req *req, unsigned *length, if (*is_last && !req->req.no_interrupt) temp |= DTD_IOC; + temp |= mult << 10; + dtd->size_ioc_sts = temp; mb(); @@ -718,10 +727,6 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) dev_err(&udc->dev->dev, "%s, bad ep", __func__); return -EINVAL; } - if (ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { - if (req->req.length > ep->ep.maxpacket) - return -EMSGSIZE; - } udc = ep->udc; if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) -- cgit v1.2.3-59-g8ed1b From 1dcaa252fdf01e4ba49ece156812043baf01c7cc Mon Sep 17 00:00:00 2001 From: Yunfan Zhang Date: Tue, 10 Jul 2012 10:07:06 +0800 Subject: usb: gadget: mv_udc: fix hang when shutdown Fix system hang in udc shutdown routine which caused by accessing usb register when clock is disabled. So enable usb clock before access register. Signed-off-by: Yunfan Zhang Signed-off-by: Neil Zhang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index ff6154d1816e..58edff9abcef 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2501,9 +2501,11 @@ static void mv_udc_shutdown(struct platform_device *dev) u32 mode; /* reset controller mode to IDLE */ + mv_udc_enable(udc); mode = readl(&udc->op_regs->usbmode); mode &= ~3; writel(mode, &udc->op_regs->usbmode); + mv_udc_disable(udc); } static struct platform_driver udc_driver = { -- cgit v1.2.3-59-g8ed1b From 11c37c8b64b9d9d4ab19d387e6028eee3ec188d3 Mon Sep 17 00:00:00 2001 From: Neil Zhang Date: Tue, 10 Jul 2012 10:07:07 +0800 Subject: usb: gadget: mv_udc: fix boot up hang Fix boot up hang when enable udc without otg enabled. The root cause is that the clock will be shut down when probe routine is finished because of clock gating. When a gadget driver is registered at this time, it will call mv_udc_start which in turn will call mv_udc_vbus_session. If there is no cable attached at the boot up time, the vbus is low, so it will call stop_activity path without clock enabled which will cause system hang then. Actually, we need't go this path when clock is disabled, what we need to do is just jump out. Signed-off-by: Neil Zhang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 58edff9abcef..ad91de4d60d8 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -1221,12 +1221,16 @@ static int mv_udc_vbus_session(struct usb_gadget *gadget, int is_active) udc_start(udc); } } else if (udc->driver && udc->softconnect) { + if (!udc->active) + goto out; + /* stop all the transfer in queue*/ stop_activity(udc, udc->driver); udc_stop(udc); mv_udc_disable(udc); } +out: spin_unlock_irqrestore(&udc->lock, flags); return retval; } -- cgit v1.2.3-59-g8ed1b From 4fefe9f6de3d6e0b5e58b17cbab9c47c74f88cb6 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Thu, 19 Jul 2012 00:20:11 +0200 Subject: usb composite: fix locking in usb_function_activate The lockdep hunter mentions a non consistent usage of spin_lock and spin_lock_irqsafe in the composite_disconnect and usb_function_activate function: [ 15.700897] ================================= [ 15.705255] [ INFO: inconsistent lock state ] [ 15.709617] 3.5.0-rc5+ #413 Not tainted [ 15.713453] --------------------------------- [ 15.717812] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. [ 15.723822] uvc-gadget/116 [HC1[1]:SC0[0]:HE0:SE1] takes: [ 15.729222] (&(&cdev->lock)->rlock){?.+...}, at: [<7f0049e8>] composite_disconnect+0x2c/0x74 [g_webcam] [ 15.738797] {HARDIRQ-ON-W} state was registered at: [ 15.743677] [<8006de3c>] mark_lock+0x148/0x688 [ 15.748325] [<8006ecb0>] __lock_acquire+0x934/0x1b74 [ 15.753481] [<8007047c>] lock_acquire+0x98/0x138 [ 15.758288] [<804c776c>] _raw_spin_lock+0x4c/0x84 [ 15.763188] [<7f006ae4>] usb_function_activate+0x28/0x94 [g_webcam] [ 15.769652] [<7f00820c>] usb_ep_autoconfig_reset+0x78/0x98 [g_webcam] [ 15.776287] [<7f0082a4>] uvc_v4l2_open+0x78/0x94 [g_webcam] [ 15.782054] [<80366a38>] v4l2_open+0x104/0x130 [ 15.786697] [<800efd30>] chrdev_open+0xa0/0x170 [ 15.791423] [<800e9718>] do_dentry_open.isra.13+0x1e8/0x264 [ 15.797186] [<800ea5d4>] nameidata_to_filp+0x58/0x94 [ 15.802340] [<800fa29c>] do_last.isra.31+0x2a0/0x808 [ 15.807497] [<800faa40>] path_openat+0xc8/0x3e8 [ 15.812216] [<800fae90>] do_filp_open+0x3c/0x90 [ 15.816936] [<800ea6fc>] do_sys_open+0xec/0x184 [ 15.821655] [<800ea7c4>] sys_open+0x30/0x34 [ 15.826027] [<8000e5c0>] ret_fast_syscall+0x0/0x48 [ 15.831015] irq event stamp: 6048 [ 15.834330] hardirqs last enabled at (6047): [<804c81b8>] _raw_spin_unlock_irqrestore+0x40/0x54 [ 15.843132] hardirqs last disabled at (6048): [<8000e174>] __irq_svc+0x34/0x60 [ 15.850370] softirqs last enabled at (5940): [<80028380>] __do_softirq+0x188/0x270 [ 15.858043] softirqs last disabled at (5935): [<80028944>] irq_exit+0xa0/0xa8 [ 15.865195] [ 15.865195] other info that might help us debug this: [ 15.871724] Possible unsafe locking scenario: [ 15.871724] [ 15.877645] CPU0 [ 15.880091] ---- [ 15.882537] lock(&(&cdev->lock)->rlock); [ 15.886659] [ 15.889278] lock(&(&cdev->lock)->rlock); [ 15.893573] [ 15.893573] *** DEADLOCK *** [ 15.893573] [ 15.899496] no locks held by uvc-gadget/116. [ 15.903765] [ 15.903765] stack backtrace: [ 15.908125] Backtrace: [ 15.910604] [<80012038>] (dump_backtrace+0x0/0x114) from [<804bf8a4>] (dump_stack+0x20/0x24) [ 15.919043] r6:dfb8e6f0 r5:dfb8e400 r4:809717ec r3:60000193 [ 15.924766] [<804bf884>] (dump_stack+0x0/0x24) from [<804c0c0c>] (print_usage_bug+0x258/0x2c0) [ 15.933388] [<804c09b4>] (print_usage_bug+0x0/0x2c0) from [<8006e240>] (mark_lock+0x54c/0x688) [ 15.942006] [<8006dcf4>] (mark_lock+0x0/0x688) from [<8006edb8>] (__lock_acquire+0xa3c/0x1b74) [ 15.950625] [<8006e37c>] (__lock_acquire+0x0/0x1b74) from [<8007047c>] (lock_acquire+0x98/0x138) [ 15.959418] [<800703e4>] (lock_acquire+0x0/0x138) from [<804c78fc>] (_raw_spin_lock_irqsave+0x58/0x94) [ 15.968736] [<804c78a4>] (_raw_spin_lock_irqsave+0x0/0x94) from [<7f0049e8>] (composite_disconnect+0x2c/0x74 [g_webcam]) [ 15.979605] r7:00000012 r6:df82b0c4 r5:ded755bc r4:ded75580 [ 15.985331] [<7f0049bc>] (composite_disconnect+0x0/0x74 [g_webcam]) from [<8033c170>] (_gadget_stop_activity+0xc4/0x120) [ 15.996200] r6:df82b0c4 r5:df82b0c8 r4:df82b0d0 r3:7f0049bc [ 16.001919] [<8033c0ac>] (_gadget_stop_activity+0x0/0x120) from [<8033e390>] (udc_irq+0x724/0xcb8) [ 16.010877] r6:df82b010 r5:00000000 r4:df82b010 r3:00000000 [ 16.016595] [<8033dc6c>] (udc_irq+0x0/0xcb8) from [<8033baec>] (ci_irq+0x64/0xdc) [ 16.024086] [<8033ba88>] (ci_irq+0x0/0xdc) from [<80086538>] (handle_irq_event_percpu+0x74/0x298) [ 16.032958] r5:807fd414 r4:df38fdc0 [ 16.036566] [<800864c4>] (handle_irq_event_percpu+0x0/0x298) from [<800867a8>] (handle_irq_event+0x4c/0x6c) [ 16.046315] [<8008675c>] (handle_irq_event+0x0/0x6c) from [<80089318>] (handle_level_irq+0xbc/0x11c) [ 16.055447] r6:def04000 r5:807fd414 r4:807fd3c0 r3:00020000 [ 16.061166] [<8008925c>] (handle_level_irq+0x0/0x11c) from [<80085cc8>] (generic_handle_irq+0x38/0x4c) [ 16.070472] r5:807f7f64 r4:8081e9f8 [ 16.074082] [<80085c90>] (generic_handle_irq+0x0/0x4c) from [<8000ef98>] (handle_IRQ+0x5c/0xbc) [ 16.082788] [<8000ef3c>] (handle_IRQ+0x0/0xbc) from [<800085cc>] (tzic_handle_irq+0x6c/0x9c) [ 16.091225] r8:00000000 r7:def059b0 r6:00000001 r5:00000000 r4:00000000 r3:00000012 [ 16.099141] [<80008560>] (tzic_handle_irq+0x0/0x9c) from [<8000e184>] (__irq_svc+0x44/0x60) [ 16.107494] Exception stack(0xdef059b0 to 0xdef059f8) [ 16.112550] 59a0: 00000001 00000001 00000000 dfb8e400 [ 16.120732] 59c0: 40000013 81a2e500 00000000 81a2e500 00000000 00000000 80862418 def05a0c [ 16.128912] 59e0: def059c8 def059f8 80070e24 804c81bc 20000013 ffffffff [ 16.135542] [<804c8178>] (_raw_spin_unlock_irqrestore+0x0/0x54) from [<8003d0ec>] (__queue_work+0x108/0x470) [ 16.145369] r5:dfb1a30c r4:81b93c00 [ 16.148978] [<8003cfe4>] (__queue_work+0x0/0x470) from [<8003d4e0>] (queue_work_on+0x4c/0x54) [ 16.157511] [<8003d494>] (queue_work_on+0x0/0x54) from [<8003d544>] (queue_work+0x30/0x34) [ 16.165774] r6:df2e6900 r5:80e0c2f8 r4:dfb1a2c8 r3:def04000 [ 16.171495] [<8003d514>] (queue_work+0x0/0x34) from [<80493284>] (rpc_make_runnable+0x9c/0xac) [ 16.180113] [<804931e8>] (rpc_make_runnable+0x0/0xac) from [<80493c88>] (rpc_execute+0x40/0xa8) [ 16.188811] r5:def05ad4 r4:dfb1a2c8 [ 16.192426] [<80493c48>] (rpc_execute+0x0/0xa8) from [<8048c734>] (rpc_run_task+0xa8/0xb4) [ 16.200690] r8:00000001 r7:df74f520 r6:ded75700 r5:def05ad4 r4:dfb1a2c8 r3:00000002 [ 16.208618] [<8048c68c>] (rpc_run_task+0x0/0xb4) from [<801f1608>] (nfs_initiate_read+0xb4/0xd4) [ 16.217403] r5:df3e86c0 r4:00000000 [ 16.221015] [<801f1554>] (nfs_initiate_read+0x0/0xd4) from [<801f1c64>] (nfs_generic_pg_readpages+0x9c/0x114) [ 16.230937] [<801f1bc8>] (nfs_generic_pg_readpages+0x0/0x114) from [<801f0744>] (__nfs_pageio_add_request+0xe8/0x214) [ 16.241545] r8:000bf000 r7:00000000 r6:00000000 r5:deef4640 r4:def05c1c r3:801f1bc8 [ 16.249463] [<801f065c>] (__nfs_pageio_add_request+0x0/0x214) from [<801f0e3c>] (nfs_pageio_add_request+0x28/0x54) [ 16.259818] [<801f0e14>] (nfs_pageio_add_request+0x0/0x54) from [<801f1394>] (readpage_async_filler+0x114/0x170) [ 16.269992] r5:def05c58 r4:80fd7300 [ 16.273607] [<801f1280>] (readpage_async_filler+0x0/0x170) from [<800bb418>] (read_cache_pages+0xa0/0x108) [ 16.283259] r8:00200200 r7:00100100 r6:df74f654 r5:def05cd0 r4:80fd7300 [ 16.290034] [<800bb378>] (read_cache_pages+0x0/0x108) from [<801f218c>] (nfs_readpages+0xc4/0x168) [ 16.298999] [<801f20c8>] (nfs_readpages+0x0/0x168) from [<800bb1d0>] (__do_page_cache_readahead+0x254/0x354) [ 16.308833] [<800baf7c>] (__do_page_cache_readahead+0x0/0x354) from [<800bb5d0>] (ra_submit+0x38/0x40) [ 16.318145] [<800bb598>] (ra_submit+0x0/0x40) from [<800bb6b0>] (ondemand_readahead+0xd8/0x3b0) [ 16.326851] [<800bb5d8>] (ondemand_readahead+0x0/0x3b0) from [<800bba20>] (page_cache_async_readahead+0x98/0xa8) [ 16.337043] [<800bb988>] (page_cache_async_readahead+0x0/0xa8) from [<800b2118>] (generic_file_aio_read+0x5b4/0x7c4) [ 16.347565] r6:00000000 r5:df74f654 r4:80fd70a0 [ 16.352231] [<800b1b64>] (generic_file_aio_read+0x0/0x7c4) from [<801e82c0>] (nfs_file_read+0x7c/0xcc) [ 16.361544] [<801e8244>] (nfs_file_read+0x0/0xcc) from [<800eab80>] (do_sync_read+0xb4/0xf4) [ 16.369981] r9:00000000 r8:def05f70 r7:00000000 r6:00000000 r5:dec34900 r4:fffffdee [ 16.377896] [<800eaacc>] (do_sync_read+0x0/0xf4) from [<800eb548>] (vfs_read+0xb4/0x144) [ 16.385987] r8:00000000 r7:def05f70 r6:76a95008 r5:003e3dd6 r4:dec34900 [ 16.392761] [<800eb494>] (vfs_read+0x0/0x144) from [<800eb624>] (sys_read+0x4c/0x78) [ 16.400504] r8:00000000 r7:00000003 r6:003e3dd6 r5:76a95008 r4:dec34900 [ 16.407279] [<800eb5d8>] (sys_read+0x0/0x78) from [<8000e5c0>] (ret_fast_syscall+0x0/0x48) [ 16.415543] r9:def04000 r8:8000e864 r6:000086b4 r5:00000000 r4:00000000 [ 20.872729] gadget: high-speed config #1: Video [ 20.877368] gadget: uvc_function_set_alt(0, 0) [ 20.881908] gadget: uvc_function_set_alt(1, 0) [ 20.891464] gadget: uvc_function_set_alt(1, 0) Signed-off-by: Michael Grzeschik Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 3f72110da1b0..2cb1030203b5 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -300,9 +300,10 @@ int usb_function_deactivate(struct usb_function *function) int usb_function_activate(struct usb_function *function) { struct usb_composite_dev *cdev = function->config->cdev; + unsigned long flags; int status = 0; - spin_lock(&cdev->lock); + spin_lock_irqsave(&cdev->lock, flags); if (WARN_ON(cdev->deactivations == 0)) status = -EINVAL; @@ -312,7 +313,7 @@ int usb_function_activate(struct usb_function *function) status = usb_gadget_connect(cdev->gadget); } - spin_unlock(&cdev->lock); + spin_unlock_irqrestore(&cdev->lock, flags); return status; } -- cgit v1.2.3-59-g8ed1b From 2868fea2d615d9f445a0ccaf988e1418a9787ebe Mon Sep 17 00:00:00 2001 From: "Du, Changbin" Date: Tue, 24 Jul 2012 08:19:25 +0800 Subject: usb: gadget: s3c-hsotg: fix core reset timeout failure The timeout values were 1000 and timeout issue occured many times on my s3c6410 Soc based board (mostly when booting whith USB cable not connected). This patch increase the values to 10000 to guarantee the success of reset. Having set timeout to 10000, I printed the remained timeout values which could cause timeout issue before this change (tested several times). the first timeout value remained: timeout = 8079 timeout = 8079 timeout = 8078 timeout = 8081 the second timeout value remained: timeout = 7940 timeout = 7945 timeout = 7940 timeout = 7938 Seeing from above values, I think the value 10000 is big enough. Signed-off-by: Du, Changbin Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index b13e0bb5f5b8..a826cb98d306 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2197,7 +2197,7 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) /* issue soft reset */ writel(GRSTCTL_CSftRst, hsotg->regs + GRSTCTL); - timeout = 1000; + timeout = 10000; do { grstctl = readl(hsotg->regs + GRSTCTL); } while ((grstctl & GRSTCTL_CSftRst) && timeout-- > 0); @@ -2207,7 +2207,7 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) return -EINVAL; } - timeout = 1000; + timeout = 10000; while (1) { u32 grstctl = readl(hsotg->regs + GRSTCTL); -- cgit v1.2.3-59-g8ed1b From d3091cfff73ce44c6b0cb61b25074f0ac648604f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 7 Aug 2012 19:07:58 +0300 Subject: usb: gadget: use native print_hex_dump_bytes() Acked-by: Michal Nazarewicz Signed-off-by: Andy Shevchenko Signed-off-by: Felipe Balbi --- drivers/usb/gadget/rndis.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index b35babed6fcb..e4192b887de9 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -863,26 +863,8 @@ int rndis_msg_parser(u8 configNr, u8 *buf) */ pr_warning("%s: unknown RNDIS message 0x%08X len %d\n", __func__, MsgType, MsgLength); - { - unsigned i; - for (i = 0; i < MsgLength; i += 16) { - pr_debug("%03d: " - " %02x %02x %02x %02x" - " %02x %02x %02x %02x" - " %02x %02x %02x %02x" - " %02x %02x %02x %02x" - "\n", - i, - buf[i], buf [i+1], - buf[i+2], buf[i+3], - buf[i+4], buf [i+5], - buf[i+6], buf[i+7], - buf[i+8], buf [i+9], - buf[i+10], buf[i+11], - buf[i+12], buf [i+13], - buf[i+14], buf[i+15]); - } - } + print_hex_dump_bytes(__func__, DUMP_PREFIX_OFFSET, + buf, MsgLength); break; } -- cgit v1.2.3-59-g8ed1b From 974e9323deefbab923d7aa8f0e4bcf9066c2ec97 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Thu, 9 Aug 2012 11:23:52 +0300 Subject: usb: gadget: udc-core: Race between disconnect/unbind and setup usb_gadget_remove_driver() runs through a four-step sequence to shut down the gadget driver. For the case of a composite gadget + at91 UDC, this would look like: udc->driver->disconnect(udc->gadget); // composite_disconnect() usb_gadget_disconnect(udc->gadget); // at91_pullup(gadget, 0) udc->driver->unbind(udc->gadget); // composite_unbind() usb_gadget_udc_stop(udc->gadget, udc->driver); // at91_stop() The UDC driver can receive SETUP packets from the host up until the point when usb_gadget_disconnect() returns. On rare occasions, the gadget driver may see this sequence: udc->driver->disconnect(udc->gadget); // composite_disconnect() udc->driver->setup(udc->gadget, &ctrl); // composite_setup() udc->driver->unbind(udc->gadget); // composite_unbind() Some gadget drivers, such as composite, assume this will never happen and crash as a result. The fix is to quiesce the UDC hardware (via usb_gadget_disconnect) before running the gadget driver through the disconnect/unbind sequence. Reviewed-by: Peter Chen Signed-off-by: Kevin Cernekee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index e5e44f8cde9a..bae243c23141 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -262,8 +262,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); if (udc_is_newstyle(udc)) { - udc->driver->disconnect(udc->gadget); usb_gadget_disconnect(udc->gadget); + udc->driver->disconnect(udc->gadget); udc->driver->unbind(udc->gadget); usb_gadget_udc_stop(udc->gadget, udc->driver); } else { -- cgit v1.2.3-59-g8ed1b From 8c7ca99250de69dfe97c5f4f6e2eb11dc6145779 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 6 Jul 2012 18:30:21 +0300 Subject: usb: gadget: use %pm to print mac addresses %pm already provides pretty print for mac addresses, let's use that and drop homebrew mac address printing. Signed-off-by: Andy Shevchenko Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_ecm.c | 5 +---- drivers/usb/gadget/f_ncm.c | 5 +---- drivers/usb/gadget/f_subset.c | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 30b908f2a53d..95bc94f8e570 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -897,10 +897,7 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) return -ENOMEM; /* export host's Ethernet address in CDC format */ - snprintf(ecm->ethaddr, sizeof ecm->ethaddr, - "%02X%02X%02X%02X%02X%02X", - ethaddr[0], ethaddr[1], ethaddr[2], - ethaddr[3], ethaddr[4], ethaddr[5]); + snprintf(ecm->ethaddr, sizeof ecm->ethaddr, "%pm", ethaddr); ecm_string_defs[1].s = ecm->ethaddr; ecm->port.cdc_filter = DEFAULT_FILTER; diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c index aab8eded045b..b651b529c67f 100644 --- a/drivers/usb/gadget/f_ncm.c +++ b/drivers/usb/gadget/f_ncm.c @@ -1346,10 +1346,7 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) return -ENOMEM; /* export host's Ethernet address in CDC format */ - snprintf(ncm->ethaddr, sizeof ncm->ethaddr, - "%02X%02X%02X%02X%02X%02X", - ethaddr[0], ethaddr[1], ethaddr[2], - ethaddr[3], ethaddr[4], ethaddr[5]); + snprintf(ncm->ethaddr, sizeof ncm->ethaddr, "%pm", ethaddr); ncm_string_defs[1].s = ncm->ethaddr; spin_lock_init(&ncm->lock); diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index 21ab474aca07..4060c0bd9785 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c @@ -436,10 +436,7 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) return -ENOMEM; /* export host's Ethernet address in CDC format */ - snprintf(geth->ethaddr, sizeof geth->ethaddr, - "%02X%02X%02X%02X%02X%02X", - ethaddr[0], ethaddr[1], ethaddr[2], - ethaddr[3], ethaddr[4], ethaddr[5]); + snprintf(geth->ethaddr, sizeof geth->ethaddr, "%pm", ethaddr); geth_string_defs[1].s = geth->ethaddr; geth->port.cdc_filter = DEFAULT_FILTER; -- cgit v1.2.3-59-g8ed1b From 4e177260e547e438c78c60b6db6f755bb89e0596 Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Mon, 20 Aug 2012 18:39:23 +0900 Subject: usb: renesas_usbhs: modify the irq handler for sharing irq When IORESOURCE_IRQ_SHAREABLE is set, the irq handler may be called even if the interupt of the USB module doesn't happen. So, it may clear the interrupt flags by mistake. This patch fixes it. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 82a628f96c03..35c5208f3249 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c @@ -209,14 +209,18 @@ int usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state) return (int)irq_state->intsts0 & CTSQ_MASK; } -static void usbhs_status_get_each_irq(struct usbhs_priv *priv, - struct usbhs_irq_state *state) +static int usbhs_status_get_each_irq(struct usbhs_priv *priv, + struct usbhs_irq_state *state) { struct usbhs_mod *mod = usbhs_mod_get_current(priv); + u16 intenb0, intenb1; state->intsts0 = usbhs_read(priv, INTSTS0); state->intsts1 = usbhs_read(priv, INTSTS1); + intenb0 = usbhs_read(priv, INTENB0); + intenb1 = usbhs_read(priv, INTENB1); + /* mask */ if (mod) { state->brdysts = usbhs_read(priv, BRDYSTS); @@ -226,6 +230,20 @@ static void usbhs_status_get_each_irq(struct usbhs_priv *priv, state->bempsts &= mod->irq_bempsts; state->brdysts &= mod->irq_brdysts; } + + /* + * Check whether the irq enable registers and the irq status are set + * when IRQF_SHARED is set. + */ + if (priv->irqflags & IRQF_SHARED) { + if (!(intenb0 & state->intsts0) && + !(intenb1 & state->intsts1) && + !(state->bempsts) && + !(state->brdysts)) + return -EIO; + } + + return 0; } /* @@ -238,7 +256,8 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) struct usbhs_priv *priv = data; struct usbhs_irq_state irq_state; - usbhs_status_get_each_irq(priv, &irq_state); + if (usbhs_status_get_each_irq(priv, &irq_state) < 0) + return IRQ_NONE; /* * clear interrupt -- cgit v1.2.3-59-g8ed1b From 252d8cec49a79d26fafb845337dd16e5e1012c1b Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Mon, 20 Aug 2012 10:30:12 +0200 Subject: usb: gadget: lpc32xx_udc: Port to new start/stop interface This patch adjusts the LPC32xx USB gadget driver to the new udc_start / udc_stop interface. Signed-off-by: Roland Stigge Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 49 ++++++++++++---------------------------- 1 file changed, 14 insertions(+), 35 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index f1ec99e69cb7..7e31ac2bf224 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -2599,9 +2599,8 @@ static int lpc32xx_pullup(struct usb_gadget *gadget, int is_on) return 0; } -static int lpc32xx_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); -static int lpc32xx_stop(struct usb_gadget_driver *driver); +static int lpc32xx_start(struct usb_gadget *, struct usb_gadget_driver *); +static int lpc32xx_stop(struct usb_gadget *, struct usb_gadget_driver *); static const struct usb_gadget_ops lpc32xx_udc_ops = { .get_frame = lpc32xx_get_frame, @@ -2609,8 +2608,8 @@ static const struct usb_gadget_ops lpc32xx_udc_ops = { .set_selfpowered = lpc32xx_set_selfpowered, .vbus_session = lpc32xx_vbus_session, .pullup = lpc32xx_pullup, - .start = lpc32xx_start, - .stop = lpc32xx_stop, + .udc_start = lpc32xx_start, + .udc_stop = lpc32xx_stop, }; static void nop_release(struct device *dev) @@ -2987,14 +2986,13 @@ static irqreturn_t lpc32xx_usb_vbus_irq(int irq, void *_udc) return IRQ_HANDLED; } -static int lpc32xx_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) +static int lpc32xx_start(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { - struct lpc32xx_udc *udc = &controller; - int retval, i; + struct lpc32xx_udc *udc = to_udc(gadget); + int i; - if (!driver || driver->max_speed < USB_SPEED_FULL || - !bind || !driver->setup) { + if (!driver || driver->max_speed < USB_SPEED_FULL || !driver->setup) { dev_err(udc->dev, "bad parameter.\n"); return -EINVAL; } @@ -3011,18 +3009,6 @@ static int lpc32xx_start(struct usb_gadget_driver *driver, udc->selfpowered = 1; udc->vbus = 0; - retval = bind(&udc->gadget); - if (retval) { - dev_err(udc->dev, "bind() returned %d\n", retval); - udc->enabled = 0; - udc->selfpowered = 0; - udc->driver = NULL; - udc->gadget.dev.driver = NULL; - return retval; - } - - dev_dbg(udc->dev, "bound to %s\n", driver->driver.name); - /* Force VBUS process once to check for cable insertion */ udc->last_vbus = udc->vbus = 0; schedule_work(&udc->vbus_job); @@ -3034,22 +3020,19 @@ static int lpc32xx_start(struct usb_gadget_driver *driver, return 0; } -static int lpc32xx_stop(struct usb_gadget_driver *driver) +static int lpc32xx_stop(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { int i; - struct lpc32xx_udc *udc = &controller; + struct lpc32xx_udc *udc = to_udc(gadget); - if (!driver || driver != udc->driver || !driver->unbind) + if (!driver || driver != udc->driver) return -EINVAL; - /* Disable USB pullup */ - isp1301_pullup_enable(udc, 0, 1); - for (i = IRQ_USB_LP; i <= IRQ_USB_ATX; i++) disable_irq(udc->udp_irq[i]); if (udc->clocked) { - spin_lock(&udc->lock); stop_activity(udc); spin_unlock(&udc->lock); @@ -3069,20 +3052,16 @@ static int lpc32xx_stop(struct usb_gadget_driver *driver) } udc->enabled = 0; - pullup(udc, 0); - - driver->unbind(&udc->gadget); udc->gadget.dev.driver = NULL; udc->driver = NULL; - dev_dbg(udc->dev, "unbound from %s\n", driver->driver.name); return 0; } static void lpc32xx_udc_shutdown(struct platform_device *dev) { /* Force disconnect on reboot */ - struct lpc32xx_udc *udc = &controller; + struct lpc32xx_udc *udc = platform_get_drvdata(dev); pullup(udc, 0); } -- cgit v1.2.3-59-g8ed1b From 78ca9139736f059b70bd797b01227271e0efa681 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Mon, 20 Aug 2012 10:30:13 +0200 Subject: usb: gadget: lpc32xx_udc: Remove usb_endpoint_descriptor This patch removes the utilization of struct usb_endpoint_descriptor, as done by other drivers also. This was done on request by the USB gadget maintainers, since this API is obsoleted. Signed-off-by: Roland Stigge Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 7e31ac2bf224..6dd8f69886e0 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -141,8 +141,6 @@ struct lpc32xx_ep { u32 totalints; bool wedge; - - const struct usb_endpoint_descriptor *desc; }; /* @@ -556,10 +554,8 @@ static int proc_udc_show(struct seq_file *s, void *unused) if (udc->enabled && udc->vbus) { proc_ep_show(s, &udc->ep[0]); - list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { - if (ep->desc) - proc_ep_show(s, ep); - } + list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) + proc_ep_show(s, ep); } spin_unlock_irqrestore(&udc->lock, flags); @@ -1453,7 +1449,6 @@ static void udc_reinit(struct lpc32xx_udc *udc) if (i != 0) list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); - ep->desc = NULL; ep->ep.maxpacket = ep->maxpacket; INIT_LIST_HEAD(&ep->queue); ep->req_pending = 0; @@ -1515,7 +1510,7 @@ static void nuke(struct lpc32xx_ep *ep, int status) done(ep, req, status); } - if (ep->desc && status == -ESHUTDOWN) { + if (status == -ESHUTDOWN) { uda_disable_hwepint(ep->udc, ep->hwep_num); udc_disable_hwep(ep->udc, ep->hwep_num); } @@ -1658,9 +1653,6 @@ static int lpc32xx_ep_disable(struct usb_ep *_ep) nuke(ep, -ESHUTDOWN); - /* restore the endpoint's pristine config */ - ep->desc = NULL; - /* Clear all DMA statuses for this EP */ udc_ep_dma_disable(udc, ep->hwep_num); writel(1 << ep->hwep_num, USBD_EOTINTCLR(udc->udp_baseaddr)); @@ -1696,7 +1688,7 @@ static int lpc32xx_ep_enable(struct usb_ep *_ep, unsigned long flags; /* Verify EP data */ - if ((!_ep) || (!ep) || (!desc) || (ep->desc) || + if ((!_ep) || (!ep) || (!desc) || (desc->bDescriptorType != USB_DT_ENDPOINT)) { dev_dbg(udc->dev, "bad ep or descriptor\n"); return -EINVAL; @@ -1754,7 +1746,6 @@ static int lpc32xx_ep_enable(struct usb_ep *_ep, /* Initialize endpoint to match the selected descriptor */ ep->is_in = (desc->bEndpointAddress & USB_DIR_IN) != 0; - ep->desc = desc; ep->ep.maxpacket = maxpacket; /* Map hardware endpoint from base and direction */ @@ -1837,7 +1828,7 @@ static int lpc32xx_ep_queue(struct usb_ep *_ep, udc = ep->udc; - if (!_ep || (!ep->desc && ep->hwep_num_base != 0)) { + if (!_ep) { dev_dbg(udc->dev, "invalid ep\n"); return -EINVAL; } @@ -1976,7 +1967,7 @@ static int lpc32xx_ep_set_halt(struct usb_ep *_ep, int value) struct lpc32xx_udc *udc = ep->udc; unsigned long flags; - if ((!ep) || (ep->desc == NULL) || (ep->hwep_num <= 1)) + if ((!ep) || (ep->hwep_num <= 1)) return -EINVAL; /* Don't halt an IN EP */ @@ -2262,7 +2253,7 @@ static int udc_get_status(struct lpc32xx_udc *udc, u16 reqtype, u16 wIndex) case USB_RECIP_ENDPOINT: tmp = wIndex & USB_ENDPOINT_NUMBER_MASK; ep = &udc->ep[tmp]; - if ((tmp == 0) || (tmp >= NUM_ENDPOINTS) || (tmp && !ep->desc)) + if ((tmp == 0) || (tmp >= NUM_ENDPOINTS)) return -EOPNOTSUPP; if (wIndex & USB_DIR_IN) { -- cgit v1.2.3-59-g8ed1b From c4846a1807fc6138e2f010d65757feb4b7b0c2cf Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Mon, 20 Aug 2012 10:30:14 +0200 Subject: usb: gadget: lpc32xx_udc: Support multiple controllers The lpc32xx_udc driver supported only one controller by defining a global static struct for it. This patch enables multiple instances of the controller by dynamic allocation of the struct at probe(). A static struct is kept as a template on initialization since it does some complex preset, reflecting fixed hardware endpoint structure. Signed-off-by: Roland Stigge Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 55 +++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 26 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 6dd8f69886e0..a0195f20bf3b 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -2608,10 +2608,9 @@ static void nop_release(struct device *dev) /* nothing to free */ } -static struct lpc32xx_udc controller = { +static const struct lpc32xx_udc controller_template = { .gadget = { .ops = &lpc32xx_udc_ops, - .ep0 = &controller.ep[0].ep, .name = driver_name, .dev = { .init_name = "gadget", @@ -2623,7 +2622,6 @@ static struct lpc32xx_udc controller = { .name = "ep0", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 0, .hwep_num = 0, /* Can be 0 or 1, has special handling */ @@ -2635,7 +2633,6 @@ static struct lpc32xx_udc controller = { .name = "ep1-int", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 2, .hwep_num = 0, /* 2 or 3, will be set later */ @@ -2647,7 +2644,6 @@ static struct lpc32xx_udc controller = { .name = "ep2-bulk", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 4, .hwep_num = 0, /* 4 or 5, will be set later */ @@ -2659,7 +2655,6 @@ static struct lpc32xx_udc controller = { .name = "ep3-iso", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 1023, .hwep_num_base = 6, .hwep_num = 0, /* 6 or 7, will be set later */ @@ -2671,7 +2666,6 @@ static struct lpc32xx_udc controller = { .name = "ep4-int", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 8, .hwep_num = 0, /* 8 or 9, will be set later */ @@ -2683,7 +2677,6 @@ static struct lpc32xx_udc controller = { .name = "ep5-bulk", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 10, .hwep_num = 0, /* 10 or 11, will be set later */ @@ -2695,7 +2688,6 @@ static struct lpc32xx_udc controller = { .name = "ep6-iso", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 1023, .hwep_num_base = 12, .hwep_num = 0, /* 12 or 13, will be set later */ @@ -2707,7 +2699,6 @@ static struct lpc32xx_udc controller = { .name = "ep7-int", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 14, .hwep_num = 0, @@ -2719,7 +2710,6 @@ static struct lpc32xx_udc controller = { .name = "ep8-bulk", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 16, .hwep_num = 0, @@ -2731,7 +2721,6 @@ static struct lpc32xx_udc controller = { .name = "ep9-iso", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 1023, .hwep_num_base = 18, .hwep_num = 0, @@ -2743,7 +2732,6 @@ static struct lpc32xx_udc controller = { .name = "ep10-int", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 20, .hwep_num = 0, @@ -2755,7 +2743,6 @@ static struct lpc32xx_udc controller = { .name = "ep11-bulk", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 22, .hwep_num = 0, @@ -2767,7 +2754,6 @@ static struct lpc32xx_udc controller = { .name = "ep12-iso", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 1023, .hwep_num_base = 24, .hwep_num = 0, @@ -2779,7 +2765,6 @@ static struct lpc32xx_udc controller = { .name = "ep13-int", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 26, .hwep_num = 0, @@ -2791,7 +2776,6 @@ static struct lpc32xx_udc controller = { .name = "ep14-bulk", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 64, .hwep_num_base = 28, .hwep_num = 0, @@ -2803,7 +2787,6 @@ static struct lpc32xx_udc controller = { .name = "ep15-bulk", .ops = &lpc32xx_ep_ops, }, - .udc = &controller, .maxpacket = 1023, .hwep_num_base = 30, .hwep_num = 0, @@ -3090,12 +3073,21 @@ static u64 lpc32xx_usbd_dmamask = ~(u32) 0x7F; static int __init lpc32xx_udc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct lpc32xx_udc *udc = &controller; + struct lpc32xx_udc *udc; int retval, i; struct resource *res; dma_addr_t dma_handle; struct device_node *isp1301_node; + udc = kzalloc(sizeof(*udc), GFP_KERNEL); + if (!udc) + return -ENOMEM; + + memcpy(udc, &controller_template, sizeof(*udc)); + for (i = 0; i <= 15; i++) + udc->ep[i].udc = udc; + udc->gadget.ep0 = &udc->ep[0].ep; + /* init software state */ udc->gadget.dev.parent = dev; udc->pdev = pdev; @@ -3110,8 +3102,10 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) } udc->isp1301_i2c_client = isp1301_get_client(isp1301_node); - if (!udc->isp1301_i2c_client) - return -EPROBE_DEFER; + if (!udc->isp1301_i2c_client) { + retval = -EPROBE_DEFER; + goto phy_fail; + } dev_info(udc->dev, "ISP1301 I2C device at address 0x%x\n", udc->isp1301_i2c_client->addr); @@ -3130,8 +3124,10 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) * IORESOURCE_IRQ, USB transceiver interrupt number */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENXIO; + if (!res) { + retval = -ENXIO; + goto resource_fail; + } spin_lock_init(&udc->lock); @@ -3141,7 +3137,8 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) if (udc->udp_irq[i] < 0) { dev_err(udc->dev, "irq resource %d not available!\n", i); - return udc->udp_irq[i]; + retval = udc->udp_irq[i]; + goto irq_fail; } } @@ -3149,7 +3146,8 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) udc->io_p_size = resource_size(res); if (!request_mem_region(udc->io_p_start, udc->io_p_size, driver_name)) { dev_err(udc->dev, "someone's using UDC memory\n"); - return -EBUSY; + retval = -EBUSY; + goto request_mem_region_fail; } udc->udp_baseaddr = ioremap(udc->io_p_start, udc->io_p_size); @@ -3346,7 +3344,11 @@ pll_get_fail: io_map_fail: release_mem_region(udc->io_p_start, udc->io_p_size); dev_err(udc->dev, "%s probe failed, %d\n", driver_name, retval); - +request_mem_region_fail: +irq_fail: +resource_fail: +phy_fail: + kfree(udc); return retval; } @@ -3384,6 +3386,7 @@ static int __devexit lpc32xx_udc_remove(struct platform_device *pdev) clk_put(udc->usb_pll_clk); iounmap(udc->udp_baseaddr); release_mem_region(udc->io_p_start, udc->io_p_size); + kfree(udc); return 0; } -- cgit v1.2.3-59-g8ed1b From d0d860758bd350206242962a223858bd01cd8a93 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 20 Aug 2012 16:12:47 -0400 Subject: usb: gadget: dummy-hcd: remember to update driver pointer This patch (as1599) fixes dummy-hcd to make it update the appropriate driver pointer when a new gadget driver is bound or unbound. Without this change, the gadget driver's name doesn't appear in dev_printk output. Signed-off-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index b799106027ad..91916f693ff7 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -909,6 +909,7 @@ static int dummy_udc_start(struct usb_gadget *g, dum->devstatus = 0; dum->driver = driver; + dum->gadget.dev.driver = &driver->driver; dev_dbg(udc_dev(dum), "binding gadget driver '%s'\n", driver->driver.name); return 0; @@ -923,6 +924,7 @@ static int dummy_udc_stop(struct usb_gadget *g, dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", driver->driver.name); + dum->gadget.dev.driver = NULL; dum->driver = NULL; return 0; -- cgit v1.2.3-59-g8ed1b From 2e8e25b882f8077c5fb38c111c0cb0fb079fb62d Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 22 Aug 2012 15:48:58 +0530 Subject: usb: gadget: s3c2410_udc: Replace with Fixes the following warning: WARNING: Use #include instead of Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index f2e51f50e528..7acecc0acf18 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From c2892cd4d9251d62419b731816633b9041fa7e3c Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 22 Aug 2012 15:48:59 +0530 Subject: usb: gadget: s3c2410_udc: Use pr_* and dev_err functions Replace printk with corresponding pr_* and dev_err functions. Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 7acecc0acf18..55a571e15cd2 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -12,6 +12,8 @@ * (at your option) any later version. */ +#define pr_fmt(fmt) "s3c2410_udc: " fmt + #include #include #include @@ -115,7 +117,7 @@ static int dprintk(int level, const char *fmt, ...) sizeof(printk_buf)-len, fmt, args); va_end(args); - return printk(KERN_DEBUG "%s", printk_buf); + return pr_debug("%s", printk_buf); } #else static int dprintk(int level, const char *fmt, ...) @@ -1683,13 +1685,13 @@ static int s3c2410_udc_start(struct usb_gadget_driver *driver, return -EBUSY; if (!bind || !driver->setup || driver->max_speed < USB_SPEED_FULL) { - printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n", + dev_err(&udc->gadget.dev, "Invalid driver: bind %p setup %p speed %d\n", bind, driver->setup, driver->max_speed); return -EINVAL; } #if defined(MODULE) if (!driver->unbind) { - printk(KERN_ERR "Invalid driver: no unbind method\n"); + dev_err(&udc->gadget.dev, "Invalid driver: no unbind method\n"); return -EINVAL; } #endif @@ -1700,7 +1702,7 @@ static int s3c2410_udc_start(struct usb_gadget_driver *driver, /* Bind the driver */ if ((retval = device_add(&udc->gadget.dev)) != 0) { - printk(KERN_ERR "Error in device_add() : %d\n",retval); + dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval); goto register_error; } @@ -2073,7 +2075,7 @@ static int __init udc_init(void) s3c2410_udc_debugfs_root = debugfs_create_dir(gadget_name, NULL); if (IS_ERR(s3c2410_udc_debugfs_root)) { - printk(KERN_ERR "%s: debugfs dir creation failed %ld\n", + pr_err("%s: debugfs dir creation failed %ld\n", gadget_name, PTR_ERR(s3c2410_udc_debugfs_root)); s3c2410_udc_debugfs_root = NULL; } -- cgit v1.2.3-59-g8ed1b From ff24166c3996a343f3901a47bd5fef6181ac21f9 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 22 Aug 2012 15:49:00 +0530 Subject: usb: gadget: s3c2410_udc: Silence checkpatch errors and warnings Silences about 75 errors and warnings related to - Spacing - Alignment of braces - Line over 80 characters Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 124 +++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 64 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 55a571e15cd2..d9e3a21b3ddc 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -127,10 +127,10 @@ static int dprintk(int level, const char *fmt, ...) #endif static int s3c2410_udc_debugfs_seq_show(struct seq_file *m, void *p) { - u32 addr_reg,pwr_reg,ep_int_reg,usb_int_reg; + u32 addr_reg, pwr_reg, ep_int_reg, usb_int_reg; u32 ep_int_en_reg, usb_int_en_reg, ep0_csr; - u32 ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2; - u32 ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2; + u32 ep1_i_csr1, ep1_i_csr2, ep1_o_csr1, ep1_o_csr2; + u32 ep2_i_csr1, ep2_i_csr2, ep2_o_csr1, ep2_o_csr2; addr_reg = udc_read(S3C2410_UDC_FUNC_ADDR_REG); pwr_reg = udc_read(S3C2410_UDC_PWR_REG); @@ -166,10 +166,10 @@ static int s3c2410_udc_debugfs_seq_show(struct seq_file *m, void *p) "EP2_I_CSR2 : 0x%04X\n" "EP2_O_CSR1 : 0x%04X\n" "EP2_O_CSR2 : 0x%04X\n", - addr_reg,pwr_reg,ep_int_reg,usb_int_reg, + addr_reg, pwr_reg, ep_int_reg, usb_int_reg, ep_int_en_reg, usb_int_en_reg, ep0_csr, - ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2, - ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2 + ep1_i_csr1, ep1_i_csr2, ep1_o_csr1, ep1_o_csr2, + ep2_i_csr1, ep2_i_csr2, ep2_o_csr1, ep2_o_csr2 ); return 0; @@ -232,7 +232,7 @@ static inline void s3c2410_udc_set_ep0_de_out(void __iomem *base) { udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); - udc_writeb(base,(S3C2410_UDC_EP0_CSR_SOPKTRDY + udc_writeb(base, (S3C2410_UDC_EP0_CSR_SOPKTRDY | S3C2410_UDC_EP0_CSR_DE), S3C2410_UDC_EP0_CSR_REG); } @@ -265,7 +265,7 @@ static void s3c2410_udc_done(struct s3c2410_ep *ep, list_del_init(&req->queue); - if (likely (req->req.status == -EINPROGRESS)) + if (likely(req->req.status == -EINPROGRESS)) req->req.status = status; else status = req->req.status; @@ -282,9 +282,9 @@ static void s3c2410_udc_nuke(struct s3c2410_udc *udc, if (&ep->queue == NULL) return; - while (!list_empty (&ep->queue)) { + while (!list_empty(&ep->queue)) { struct s3c2410_request *req; - req = list_entry (ep->queue.next, struct s3c2410_request, + req = list_entry(ep->queue.next, struct s3c2410_request, queue); s3c2410_udc_done(ep, req, status); } @@ -391,10 +391,10 @@ static int s3c2410_udc_write_fifo(struct s3c2410_ep *ep, if (idx == 0) { /* Reset signal => no need to say 'data sent' */ - if (! (udc_read(S3C2410_UDC_USB_INT_REG) + if (!(udc_read(S3C2410_UDC_USB_INT_REG) & S3C2410_UDC_USBINT_RESET)) s3c2410_udc_set_ep0_de_in(base_addr); - ep->dev->ep0state=EP0_IDLE; + ep->dev->ep0state = EP0_IDLE; } else { udc_write(idx, S3C2410_UDC_INDEX_REG); ep_csr = udc_read(S3C2410_UDC_IN_CSR1_REG); @@ -408,7 +408,7 @@ static int s3c2410_udc_write_fifo(struct s3c2410_ep *ep, } else { if (idx == 0) { /* Reset signal => no need to say 'data sent' */ - if (! (udc_read(S3C2410_UDC_USB_INT_REG) + if (!(udc_read(S3C2410_UDC_USB_INT_REG) & S3C2410_UDC_USBINT_RESET)) s3c2410_udc_set_ep0_ipr(base_addr); } else { @@ -444,7 +444,7 @@ static int s3c2410_udc_read_fifo(struct s3c2410_ep *ep, u8 *buf; u32 ep_csr; unsigned bufferspace; - int is_last=1; + int is_last = 1; unsigned avail; int fifo_count = 0; u32 idx; @@ -512,7 +512,7 @@ static int s3c2410_udc_read_fifo(struct s3c2410_ep *ep, /* Only ep0 debug messages are interesting */ if (idx == 0) dprintk(DEBUG_VERBOSE, "%s fifo count : %d [last %d]\n", - __func__, fifo_count,is_last); + __func__, fifo_count, is_last); if (is_last) { if (idx == 0) { @@ -544,7 +544,7 @@ static int s3c2410_udc_read_fifo(struct s3c2410_ep *ep, static int s3c2410_udc_read_fifo_crq(struct usb_ctrlrequest *crq) { - unsigned char *outbuf = (unsigned char*)crq; + unsigned char *outbuf = (unsigned char *)crq; int bytes_read = 0; udc_write(0, S3C2410_UDC_INDEX_REG); @@ -650,7 +650,7 @@ static void s3c2410_udc_handle_ep0_idle(struct s3c2410_udc *dev, switch (crq->bRequest) { case USB_REQ_SET_CONFIGURATION: - dprintk(DEBUG_NORMAL, "USB_REQ_SET_CONFIGURATION ... \n"); + dprintk(DEBUG_NORMAL, "USB_REQ_SET_CONFIGURATION ...\n"); if (crq->bRequestType == USB_RECIP_DEVICE) { dev->req_config = 1; @@ -659,7 +659,7 @@ static void s3c2410_udc_handle_ep0_idle(struct s3c2410_udc *dev, break; case USB_REQ_SET_INTERFACE: - dprintk(DEBUG_NORMAL, "USB_REQ_SET_INTERFACE ... \n"); + dprintk(DEBUG_NORMAL, "USB_REQ_SET_INTERFACE ...\n"); if (crq->bRequestType == USB_RECIP_INTERFACE) { dev->req_config = 1; @@ -668,7 +668,7 @@ static void s3c2410_udc_handle_ep0_idle(struct s3c2410_udc *dev, break; case USB_REQ_SET_ADDRESS: - dprintk(DEBUG_NORMAL, "USB_REQ_SET_ADDRESS ... \n"); + dprintk(DEBUG_NORMAL, "USB_REQ_SET_ADDRESS ...\n"); if (crq->bRequestType == USB_RECIP_DEVICE) { tmp = crq->wValue & 0x7F; @@ -681,13 +681,12 @@ static void s3c2410_udc_handle_ep0_idle(struct s3c2410_udc *dev, break; case USB_REQ_GET_STATUS: - dprintk(DEBUG_NORMAL, "USB_REQ_GET_STATUS ... \n"); + dprintk(DEBUG_NORMAL, "USB_REQ_GET_STATUS ...\n"); s3c2410_udc_clear_ep0_opr(base_addr); if (dev->req_std) { - if (!s3c2410_udc_get_status(dev, crq)) { + if (!s3c2410_udc_get_status(dev, crq)) return; - } } break; @@ -752,7 +751,7 @@ static void s3c2410_udc_handle_ep0_idle(struct s3c2410_udc *dev, /* deferred i/o == no response yet */ } else if (dev->req_pending) { dprintk(DEBUG_VERBOSE, "dev->req_pending... what now?\n"); - dev->req_pending=0; + dev->req_pending = 0; } dprintk(DEBUG_VERBOSE, "ep0state %s\n", ep0states[dev->ep0state]); @@ -803,16 +802,14 @@ static void s3c2410_udc_handle_ep0(struct s3c2410_udc *dev) case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR etc */ dprintk(DEBUG_NORMAL, "EP0_IN_DATA_PHASE ... what now?\n"); - if (!(ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY) && req) { + if (!(ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY) && req) s3c2410_udc_write_fifo(ep, req); - } break; case EP0_OUT_DATA_PHASE: /* SET_DESCRIPTOR etc */ dprintk(DEBUG_NORMAL, "EP0_OUT_DATA_PHASE ... what now?\n"); - if ((ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) && req ) { - s3c2410_udc_read_fifo(ep,req); - } + if ((ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) && req) + s3c2410_udc_read_fifo(ep, req); break; case EP0_END_XFER: @@ -838,7 +835,7 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep) u32 ep_csr1; u32 idx; - if (likely (!list_empty(&ep->queue))) + if (likely(!list_empty(&ep->queue))) req = list_entry(ep->queue.next, struct s3c2410_request, queue); else @@ -860,9 +857,8 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep) return; } - if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && req) { - s3c2410_udc_write_fifo(ep,req); - } + if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && req) + s3c2410_udc_write_fifo(ep, req); } else { udc_write(idx, S3C2410_UDC_INDEX_REG); ep_csr1 = udc_read(S3C2410_UDC_OUT_CSR1_REG); @@ -875,9 +871,8 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep) return; } - if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) { - s3c2410_udc_read_fifo(ep,req); - } + if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) + s3c2410_udc_read_fifo(ep, req); } } @@ -1059,7 +1054,7 @@ static int s3c2410_udc_ep_enable(struct usb_ep *_ep, struct s3c2410_ep *ep; u32 max, tmp; unsigned long flags; - u32 csr1,csr2; + u32 csr1, csr2; u32 int_en_reg; ep = to_s3c2410_ep(_ep); @@ -1075,7 +1070,7 @@ static int s3c2410_udc_ep_enable(struct usb_ep *_ep, max = usb_endpoint_maxp(desc) & 0x1fff; - local_irq_save (flags); + local_irq_save(flags); _ep->maxpacket = max & 0x7ff; ep->ep.desc = desc; ep->halted = 0; @@ -1119,11 +1114,11 @@ static int s3c2410_udc_ep_enable(struct usb_ep *_ep, /* print some debug message */ tmp = desc->bEndpointAddress; - dprintk (DEBUG_NORMAL, "enable %s(%d) ep%x%s-blk max %02x\n", - _ep->name,ep->num, tmp, + dprintk(DEBUG_NORMAL, "enable %s(%d) ep%x%s-blk max %02x\n", + _ep->name, ep->num, tmp, desc->bEndpointAddress & USB_DIR_IN ? "in" : "out", max); - local_irq_restore (flags); + local_irq_restore(flags); s3c2410_udc_set_halt(_ep, 0); return 0; @@ -1151,7 +1146,7 @@ static int s3c2410_udc_ep_disable(struct usb_ep *_ep) ep->ep.desc = NULL; ep->halted = 1; - s3c2410_udc_nuke (ep->dev, ep, -ESHUTDOWN); + s3c2410_udc_nuke(ep->dev, ep, -ESHUTDOWN); /* disable irqs */ int_en_reg = udc_read(S3C2410_UDC_EP_INT_EN_REG); @@ -1172,16 +1167,16 @@ s3c2410_udc_alloc_request(struct usb_ep *_ep, gfp_t mem_flags) { struct s3c2410_request *req; - dprintk(DEBUG_VERBOSE,"%s(%p,%d)\n", __func__, _ep, mem_flags); + dprintk(DEBUG_VERBOSE, "%s(%p,%d)\n", __func__, _ep, mem_flags); if (!_ep) return NULL; - req = kzalloc (sizeof(struct s3c2410_request), mem_flags); + req = kzalloc(sizeof(struct s3c2410_request), mem_flags); if (!req) return NULL; - INIT_LIST_HEAD (&req->queue); + INIT_LIST_HEAD(&req->queue); return &req->req; } @@ -1199,7 +1194,7 @@ s3c2410_udc_free_request(struct usb_ep *_ep, struct usb_request *_req) if (!ep || !_req || (!ep->ep.desc && _ep->name != ep0name)) return; - WARN_ON (!list_empty (&req->queue)); + WARN_ON(!list_empty(&req->queue)); kfree(req); } @@ -1222,12 +1217,12 @@ static int s3c2410_udc_queue(struct usb_ep *_ep, struct usb_request *_req, } dev = ep->dev; - if (unlikely (!dev->driver + if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) { return -ESHUTDOWN; } - local_irq_save (flags); + local_irq_save(flags); if (unlikely(!_req || !_req->complete || !_req->buf || !list_empty(&req->queue))) { @@ -1235,7 +1230,7 @@ static int s3c2410_udc_queue(struct usb_ep *_ep, struct usb_request *_req, dprintk(DEBUG_NORMAL, "%s: 1 X X X\n", __func__); else { dprintk(DEBUG_NORMAL, "%s: 0 %01d %01d %01d\n", - __func__, !_req->complete,!_req->buf, + __func__, !_req->complete, !_req->buf, !list_empty(&req->queue)); } @@ -1301,7 +1296,7 @@ static int s3c2410_udc_queue(struct usb_ep *_ep, struct usb_request *_req, } /* pio or dma irq handler advances the queue. */ - if (likely (req != 0)) + if (likely(req != 0)) list_add_tail(&req->queue, &ep->queue); local_irq_restore(flags); @@ -1331,11 +1326,11 @@ static int s3c2410_udc_dequeue(struct usb_ep *_ep, struct usb_request *_req) udc = to_s3c2410_udc(ep->gadget); - local_irq_save (flags); + local_irq_save(flags); - list_for_each_entry (req, &ep->queue, queue) { + list_for_each_entry(req, &ep->queue, queue) { if (&req->req == _req) { - list_del_init (&req->queue); + list_del_init(&req->queue); _req->status = -ECONNRESET; retval = 0; break; @@ -1350,7 +1345,7 @@ static int s3c2410_udc_dequeue(struct usb_ep *_ep, struct usb_request *_req) s3c2410_udc_done(ep, req, -ECONNRESET); } - local_irq_restore (flags); + local_irq_restore(flags); return retval; } @@ -1369,7 +1364,7 @@ static int s3c2410_udc_set_halt(struct usb_ep *_ep, int value) return -EINVAL; } - local_irq_save (flags); + local_irq_save(flags); idx = ep->bEndpointAddress & 0x7F; @@ -1378,7 +1373,7 @@ static int s3c2410_udc_set_halt(struct usb_ep *_ep, int value) s3c2410_udc_set_ep0_de_out(base_addr); } else { udc_write(idx, S3C2410_UDC_INDEX_REG); - ep_csr = udc_read((ep->bEndpointAddress &USB_DIR_IN) + ep_csr = udc_read((ep->bEndpointAddress & USB_DIR_IN) ? S3C2410_UDC_IN_CSR1_REG : S3C2410_UDC_OUT_CSR1_REG); @@ -1406,7 +1401,7 @@ static int s3c2410_udc_set_halt(struct usb_ep *_ep, int value) } ep->halted = value ? 1 : 0; - local_irq_restore (flags); + local_irq_restore(flags); return 0; } @@ -1486,9 +1481,9 @@ static int s3c2410_udc_set_pullup(struct s3c2410_udc *udc, int is_on) } s3c2410_udc_disable(udc); } - } - else + } else { return -EOPNOTSUPP; + } return 0; } @@ -1619,20 +1614,20 @@ static void s3c2410_udc_reinit(struct s3c2410_udc *dev) u32 i; /* device/ep0 records init */ - INIT_LIST_HEAD (&dev->gadget.ep_list); - INIT_LIST_HEAD (&dev->gadget.ep0->ep_list); + INIT_LIST_HEAD(&dev->gadget.ep_list); + INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); dev->ep0state = EP0_IDLE; for (i = 0; i < S3C2410_ENDPOINTS; i++) { struct s3c2410_ep *ep = &dev->ep[i]; if (i != 0) - list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list); + list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list); ep->dev = dev; ep->ep.desc = NULL; ep->halted = 0; - INIT_LIST_HEAD (&ep->queue); + INIT_LIST_HEAD(&ep->queue); } } @@ -1867,7 +1862,7 @@ static int s3c2410_udc_probe(struct platform_device *pdev) memory.ep[4].fifo_size = S3C2440_EP_FIFO_SIZE; } - spin_lock_init (&udc->lock); + spin_lock_init(&udc->lock); udc_info = pdev->dev.platform_data; rsrc_start = S3C2410_PA_USBDEV; @@ -2030,7 +2025,8 @@ static int s3c2410_udc_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int s3c2410_udc_suspend(struct platform_device *pdev, pm_message_t message) +static int +s3c2410_udc_suspend(struct platform_device *pdev, pm_message_t message) { s3c2410_udc_command(S3C2410_UDC_P_DISABLE); -- cgit v1.2.3-59-g8ed1b From 1660c8944652aac142e622d276c3750f735a568f Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 22 Aug 2012 15:49:01 +0530 Subject: usb: gadget: s3c2410_udc: Move assignment outside if condition Fixes the following checkpatch errors: ERROR: do not use assignment in if condition Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index d9e3a21b3ddc..e895ea12b67e 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1696,7 +1696,8 @@ static int s3c2410_udc_start(struct usb_gadget_driver *driver, udc->gadget.dev.driver = &driver->driver; /* Bind the driver */ - if ((retval = device_add(&udc->gadget.dev)) != 0) { + retval = device_add(&udc->gadget.dev); + if (retval) { dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval); goto register_error; } @@ -1704,7 +1705,8 @@ static int s3c2410_udc_start(struct usb_gadget_driver *driver, dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n", driver->driver.name); - if ((retval = bind(&udc->gadget)) != 0) { + retval = bind(&udc->gadget); + if (retval) { device_del(&udc->gadget.dev); goto register_error; } -- cgit v1.2.3-59-g8ed1b From 86bab36662d47388102ca437a3cbfd79e0ea75cd Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 22 Aug 2012 15:49:02 +0530 Subject: usb: gadget: s3c2410_udc: Do not use integer for NULL 'req' being a pointer shouldn't be equated with 0. Fixes the following compilation warning: drivers/usb/gadget/s3c2410_udc.c:1299:13: warning: Using plain integer as NULL pointer Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index e895ea12b67e..b627c9b51fda 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1296,7 +1296,7 @@ static int s3c2410_udc_queue(struct usb_ep *_ep, struct usb_request *_req, } /* pio or dma irq handler advances the queue. */ - if (likely(req != 0)) + if (likely(req)) list_add_tail(&req->queue, &ep->queue); local_irq_restore(flags); -- cgit v1.2.3-59-g8ed1b From 85b8614d722389202af298e1bf8a599c431fef19 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Fri, 24 Aug 2012 20:46:18 +0200 Subject: usb: gadget: get rid of USB_GADGET_{DUAL,SUPER}SPEED This commit removes USB_GADGET_DUALSPEED and USB_GADGET_SUPERSPEED Kconfig options. Since now kernel allows many UDC drivers to be compiled, those options may turn to no longer be valid. For instance, if someone decides to build UDC that supports super speed and UDC that supports high speed only, the latter will be "assumed" to support super speed since USB_GADGET_SUPERSPEED will be selected by the former. The test of whether CONFIG_USB_GADGET_*SPEED was defined was just an optimisation which removed otherwise dead code (ie. if UDC is not dual speed, there is no need to handle cases that can happen if speed is high). This commit removes those checks. Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/Kconfig | 1 - drivers/usb/dwc3/Kconfig | 2 -- drivers/usb/gadget/Kconfig | 25 ------------------------- drivers/usb/gadget/composite.c | 9 +-------- drivers/usb/gadget/inode.c | 15 ++++----------- drivers/usb/gadget/u_ether.c | 7 ------- drivers/usb/musb/Kconfig | 1 - include/linux/usb/gadget.h | 19 ++----------------- 8 files changed, 7 insertions(+), 72 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index 8337fb5d988d..272109ff5aa3 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig @@ -13,7 +13,6 @@ if USB_CHIPIDEA config USB_CHIPIDEA_UDC bool "ChipIdea device controller" depends on USB_GADGET - select USB_GADGET_DUALSPEED help Say Y here to enable device controller functionality of the ChipIdea driver. diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index d13c60f42139..f6a6e070c2ac 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -2,8 +2,6 @@ config USB_DWC3 tristate "DesignWare USB3 DRD Core Support" depends on (USB && USB_GADGET) select USB_OTG_UTILS - select USB_GADGET_DUALSPEED - select USB_GADGET_SUPERSPEED select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD help Say Y or M here if your system has a Dual Role SuperSpeed diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 51ab5fd5d468..2ba0d0e2eed6 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -154,7 +154,6 @@ config USB_LPC32XX config USB_ATMEL_USBA tristate "Atmel USBA" - select USB_GADGET_DUALSPEED depends on AVR32 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 help USBA is the integrated high-speed USB Device controller on @@ -163,7 +162,6 @@ config USB_ATMEL_USBA config USB_FSL_USB2 tristate "Freescale Highspeed USB DR Peripheral Controller" depends on FSL_SOC || ARCH_MXC - select USB_GADGET_DUALSPEED select USB_FSL_MPH_DR_OF if OF help Some of Freescale PowerPC and i.MX processors have a High Speed @@ -179,7 +177,6 @@ config USB_FSL_USB2 config USB_FUSB300 tristate "Faraday FUSB300 USB Peripheral Controller" depends on !PHYS_ADDR_T_64BIT - select USB_GADGET_DUALSPEED help Faraday usb device controller FUSB300 driver @@ -227,7 +224,6 @@ config USB_PXA25X_SMALL config USB_R8A66597 tristate "Renesas R8A66597 USB Peripheral Controller" - select USB_GADGET_DUALSPEED help R8A66597 is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers. @@ -240,7 +236,6 @@ config USB_R8A66597 config USB_RENESAS_USBHS_UDC tristate 'Renesas USBHS controller' depends on USB_RENESAS_USBHS - select USB_GADGET_DUALSPEED help Renesas USBHS is a discrete USB host and peripheral controller chip that supports both full and high speed USB 2.0 data transfers. @@ -268,7 +263,6 @@ config USB_PXA27X config USB_S3C_HSOTG tristate "S3C HS/OtG USB Device controller" depends on S3C_DEV_USB_HSOTG - select USB_GADGET_DUALSPEED help The Samsung S3C64XX USB2.0 high-speed gadget controller integrated into the S3C64XX series SoC. @@ -305,7 +299,6 @@ config USB_S3C2410_DEBUG config USB_S3C_HSUDC tristate "S3C2416, S3C2443 and S3C2450 USB Device Controller" depends on ARCH_S3C24XX - select USB_GADGET_DUALSPEED help Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC integrated with dual speed USB 2.0 device controller. It has @@ -315,7 +308,6 @@ config USB_S3C_HSUDC config USB_MV_UDC tristate "Marvell USB2.0 Device Controller" - select USB_GADGET_DUALSPEED help Marvell Socs (including PXA and MMP series) include a high speed USB2.0 OTG controller, which can be configured as high speed or @@ -338,14 +330,12 @@ config USB_MV_U3D config USB_GADGET_MUSB_HDRC tristate "Inventra HDRC USB Peripheral (TI, ADI, ...)" depends on USB_MUSB_HDRC - select USB_GADGET_DUALSPEED help This OTG-capable silicon IP is used in dual designs including the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin config USB_M66592 tristate "Renesas M66592 USB Peripheral Controller" - select USB_GADGET_DUALSPEED help M66592 is a discrete USB peripheral controller chip that supports both full and high speed USB 2.0 data transfers. @@ -362,7 +352,6 @@ config USB_M66592 config USB_AMD5536UDC tristate "AMD5536 UDC" depends on PCI - select USB_GADGET_DUALSPEED help The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. It is a USB Highspeed DMA capable USB device controller. Beside ep0 @@ -389,7 +378,6 @@ config USB_FSL_QE config USB_NET2272 tristate "PLX NET2272" - select USB_GADGET_DUALSPEED help PLX NET2272 is a USB peripheral controller which supports both full and high speed USB 2.0 data transfers. @@ -413,7 +401,6 @@ config USB_NET2272_DMA config USB_NET2280 tristate "NetChip 228x" depends on PCI - select USB_GADGET_DUALSPEED help NetChip 2280 / 2282 is a PCI based USB peripheral controller which supports both full and high speed USB 2.0 data transfers. @@ -443,7 +430,6 @@ config USB_GOKU config USB_EG20T tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" depends on PCI - select USB_GADGET_DUALSPEED help This is a USB device driver for EG20T PCH. EG20T PCH is the platform controller hub that is used in Intel's @@ -470,8 +456,6 @@ config USB_EG20T config USB_DUMMY_HCD tristate "Dummy HCD (DEVELOPMENT)" depends on USB=y || (USB=m && USB_GADGET=m) - select USB_GADGET_DUALSPEED - select USB_GADGET_SUPERSPEED help This host controller driver emulates USB, looping all data transfer requests back to a USB "gadget driver" in the same host. The host @@ -496,15 +480,6 @@ config USB_DUMMY_HCD endmenu -# Selected by UDC drivers that support high-speed operation. -config USB_GADGET_DUALSPEED - bool - -# Selected by UDC drivers that support super-speed opperation -config USB_GADGET_SUPERSPEED - bool - depends on USB_GADGET_DUALSPEED - # # USB Gadget Drivers # diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 2cb1030203b5..91411a6d741b 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1586,12 +1586,6 @@ composite_resume(struct usb_gadget *gadget) /*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - .max_speed = USB_SPEED_SUPER, -#else - .max_speed = USB_SPEED_HIGH, -#endif - .unbind = composite_unbind, .setup = composite_setup, @@ -1636,8 +1630,7 @@ int usb_composite_probe(struct usb_composite_driver *driver, driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; - composite_driver.max_speed = - min_t(u8, composite_driver.max_speed, driver->max_speed); + composite_driver.max_speed = driver->max_speed; composite = driver; composite_gadget_bind = bind; diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index e58b16442971..ae13a106fb96 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -828,7 +828,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (value == 0) data->state = STATE_EP_ENABLED; break; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_SPEED_HIGH: /* fails if caller didn't provide that descriptor... */ ep->desc = &data->hs_desc; @@ -836,7 +835,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (value == 0) data->state = STATE_EP_ENABLED; break; -#endif default: DBG(data->dev, "unconnected, %s init abandoned\n", data->name); @@ -1324,7 +1322,6 @@ static const struct file_operations ep0_io_operations = { * Unrecognized ep0 requests may be handled in user space. */ -#ifdef CONFIG_USB_GADGET_DUALSPEED static void make_qualifier (struct dev_data *dev) { struct usb_qualifier_descriptor qual; @@ -1347,7 +1344,6 @@ static void make_qualifier (struct dev_data *dev) memcpy (dev->rbuf, &qual, sizeof qual); } -#endif static int config_buf (struct dev_data *dev, u8 type, unsigned index) @@ -1427,7 +1423,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) dev->dev->bMaxPacketSize0 = dev->gadget->ep0->maxpacket; req->buf = dev->dev; break; -#ifdef CONFIG_USB_GADGET_DUALSPEED case USB_DT_DEVICE_QUALIFIER: if (!dev->hs_config) break; @@ -1437,7 +1432,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) break; case USB_DT_OTHER_SPEED_CONFIG: // FALLTHROUGH -#endif case USB_DT_CONFIG: value = config_buf (dev, w_value >> 8, @@ -1763,11 +1757,6 @@ gadgetfs_suspend (struct usb_gadget *gadget) } static struct usb_gadget_driver gadgetfs_driver = { -#ifdef CONFIG_USB_GADGET_DUALSPEED - .max_speed = USB_SPEED_HIGH, -#else - .max_speed = USB_SPEED_FULL, -#endif .function = (char *) driver_desc, .unbind = gadgetfs_unbind, .setup = gadgetfs_setup, @@ -1900,6 +1889,10 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) /* triggers gadgetfs_bind(); then we can enumerate. */ spin_unlock_irq (&dev->lock); + if (dev->hs_config) + gadgetfs_driver.max_speed = USB_SPEED_HIGH; + else + gadgetfs_driver.max_speed = USB_SPEED_FULL; value = usb_gadget_probe_driver(&gadgetfs_driver, gadgetfs_bind); if (value != 0) { kfree (dev->buf); diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 90e82e288eb9..1154a99dc8db 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -83,17 +83,10 @@ struct eth_dev { #define DEFAULT_QLEN 2 /* double buffering by default */ - -#ifdef CONFIG_USB_GADGET_DUALSPEED - static unsigned qmult = 5; module_param(qmult, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(qmult, "queue length multiplier at high/super speed"); -#else /* full speed (low speed doesn't do bulk) */ -#define qmult 1 -#endif - /* for dual-speed hardware, use deeper queues at high/super speed */ static inline int qlen(struct usb_gadget *gadget) { diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index ef0c3f9f0947..1b9f005ae9a5 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -12,7 +12,6 @@ config USB_MUSB_HDRC select TWL4030_USB if MACH_OMAP_3430SDP select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA select USB_OTG_UTILS - select USB_GADGET_DUALSPEED help Say Y here if your system has a dual role high speed USB controller based on the Mentor Graphics silicon IP. Then diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 9517466ababb..d05b220f0fd3 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -558,14 +558,7 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev) */ static inline int gadget_is_dualspeed(struct usb_gadget *g) { -#ifdef CONFIG_USB_GADGET_DUALSPEED - /* runtime test would check "g->max_speed" ... that might be - * useful to work around hardware bugs, but is mostly pointless - */ - return 1; -#else - return 0; -#endif + return g->max_speed >= USB_SPEED_HIGH; } /** @@ -575,15 +568,7 @@ static inline int gadget_is_dualspeed(struct usb_gadget *g) */ static inline int gadget_is_superspeed(struct usb_gadget *g) { -#ifdef CONFIG_USB_GADGET_SUPERSPEED - /* - * runtime test would check "g->max_speed" ... that might be - * useful to work around hardware bugs, but is mostly pointless - */ - return 1; -#else - return 0; -#endif + return g->max_speed >= USB_SPEED_SUPER; } /** -- cgit v1.2.3-59-g8ed1b From 44fd6c0266d3ec752be1bf003015544ea45f473f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 25 Aug 2012 21:57:06 +0200 Subject: usb: gadget: lpc32xx_udc.c: adjust inconsistent IS_ERR and PTR_ERR Change the call to PTR_ERR to access the value just tested by IS_ERR. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression e,e1; @@ ( if (IS_ERR(e)) { ... PTR_ERR(e) ... } | if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... } | *if (IS_ERR(e)) { ... * PTR_ERR(e1) ... } ) // Signed-off-by: Julia Lawall Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index a0195f20bf3b..f696fb9b136d 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -3176,7 +3176,7 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) udc->usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg"); if (IS_ERR(udc->usb_otg_clk)) { dev_err(udc->dev, "failed to acquire USB otg clock\n"); - retval = PTR_ERR(udc->usb_slv_clk); + retval = PTR_ERR(udc->usb_otg_clk); goto usb_otg_clk_get_fail; } -- cgit v1.2.3-59-g8ed1b From 9d2333d0d9bc03da3d8c11f92c602dac97ffea1e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 09:43:00 +0800 Subject: usb: gadget: remove duplicated include from pxa25x_udc.c From: Wei Yongjun Remove duplicated include. Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa25x_udc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 907ad3ecb341..c246c08a242d 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 78f0c53ef8563009bf089ef90c7204f526d4a589 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 3 Sep 2012 15:48:18 +0530 Subject: usb: gadget: s3c-hsudc: Use devm_* functions devm_* functions are used to replace kzalloc, request_mem_region, ioremap clk_get and request_irq functions in probe call. With the usage of devm_* functions explicit freeing and unmapping is not required. Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 41 +++++++++-------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index e26a4e7ed2bf..fe4a46197181 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -135,7 +135,6 @@ struct s3c_hsudc_req { * @dev: The device reference used by probe function. * @lock: Lock to synchronize the usage of Endpoints (EP's are indexed). * @regs: Remapped base address of controller's register space. - * @mem_rsrc: Device memory resource used for remapping device register space. * irq: IRQ number used by the controller. * uclk: Reference to the controller clock. * ep0state: Current state of EP0. @@ -150,7 +149,6 @@ struct s3c_hsudc { struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsudc_supply_names)]; spinlock_t lock; void __iomem *regs; - struct resource *mem_rsrc; int irq; struct clk *uclk; int ep0state; @@ -1271,7 +1269,7 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) struct s3c24xx_hsudc_platdata *pd = pdev->dev.platform_data; int ret, i; - hsudc = kzalloc(sizeof(struct s3c_hsudc) + + hsudc = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsudc) + sizeof(struct s3c_hsudc_ep) * pd->epnum, GFP_KERNEL); if (!hsudc) { @@ -1296,25 +1294,12 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "unable to obtain driver resource data\n"); - ret = -ENODEV; - goto err_res; - } - - hsudc->mem_rsrc = request_mem_region(res->start, resource_size(res), - dev_name(&pdev->dev)); - if (!hsudc->mem_rsrc) { - dev_err(dev, "failed to reserve register area\n"); - ret = -ENODEV; - goto err_res; - } - hsudc->regs = ioremap(res->start, resource_size(res)); + hsudc->regs = devm_request_and_ioremap(&pdev->dev, res); if (!hsudc->regs) { dev_err(dev, "error mapping device register area\n"); ret = -EBUSY; - goto err_remap; + goto err_res; } spin_lock_init(&hsudc->lock); @@ -1337,21 +1322,22 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) ret = platform_get_irq(pdev, 0); if (ret < 0) { dev_err(dev, "unable to obtain IRQ number\n"); - goto err_irq; + goto err_res; } hsudc->irq = ret; - ret = request_irq(hsudc->irq, s3c_hsudc_irq, 0, driver_name, hsudc); + ret = devm_request_irq(&pdev->dev, hsudc->irq, s3c_hsudc_irq, 0, + driver_name, hsudc); if (ret < 0) { dev_err(dev, "irq request failed\n"); - goto err_irq; + goto err_res; } - hsudc->uclk = clk_get(&pdev->dev, "usb-device"); + hsudc->uclk = devm_clk_get(&pdev->dev, "usb-device"); if (IS_ERR(hsudc->uclk)) { dev_err(dev, "failed to find usb-device clock source\n"); ret = PTR_ERR(hsudc->uclk); - goto err_clk; + goto err_res; } clk_enable(hsudc->uclk); @@ -1377,21 +1363,12 @@ err_add_udc: device_unregister(&hsudc->gadget.dev); err_add_device: clk_disable(hsudc->uclk); - clk_put(hsudc->uclk); -err_clk: - free_irq(hsudc->irq, hsudc); -err_irq: - iounmap(hsudc->regs); - -err_remap: - release_mem_region(res->start, resource_size(res)); err_res: if (!IS_ERR_OR_NULL(hsudc->transceiver)) usb_put_phy(hsudc->transceiver); regulator_bulk_free(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); err_supplies: - kfree(hsudc); return ret; } -- cgit v1.2.3-59-g8ed1b From affaab4c58d8e5f7c30ca2be351277cf72d2336f Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 3 Sep 2012 15:48:19 +0530 Subject: usb: gadget: s3c-hsudc: Add missing braces around sizeof Silences the following checkpatch warning: WARNING: sizeof *hsreq should be sizeof(*hsreq) Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index fe4a46197181..35cdc6a5a589 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -833,7 +833,7 @@ static struct usb_request *s3c_hsudc_alloc_request(struct usb_ep *_ep, { struct s3c_hsudc_req *hsreq; - hsreq = kzalloc(sizeof *hsreq, gfp_flags); + hsreq = kzalloc(sizeof(*hsreq), gfp_flags); if (!hsreq) return 0; -- cgit v1.2.3-59-g8ed1b From dc2cdcaf4caafeb069d01704fdfda24f9c1f443a Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 3 Sep 2012 15:48:20 +0530 Subject: usb: gadget: s3c-hsudc: Replace 0 with NULL for pointers Silences the following type of sparse warnings: warning: Using plain integer as NULL pointer Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 35cdc6a5a589..d8e785d4ad59 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -835,7 +835,7 @@ static struct usb_request *s3c_hsudc_alloc_request(struct usb_ep *_ep, hsreq = kzalloc(sizeof(*hsreq), gfp_flags); if (!hsreq) - return 0; + return NULL; INIT_LIST_HEAD(&hsreq->queue); return &hsreq->req; @@ -904,16 +904,16 @@ static int s3c_hsudc_queue(struct usb_ep *_ep, struct usb_request *_req, csr = readl((u32)hsudc->regs + offset); if (!(csr & S3C_ESR_TX_SUCCESS) && (s3c_hsudc_write_fifo(hsep, hsreq) == 1)) - hsreq = 0; + hsreq = NULL; } else { csr = readl((u32)hsudc->regs + offset); if ((csr & S3C_ESR_RX_SUCCESS) && (s3c_hsudc_read_fifo(hsep, hsreq) == 1)) - hsreq = 0; + hsreq = NULL; } } - if (hsreq != 0) + if (hsreq) list_add_tail(&hsreq->queue, &hsep->queue); spin_unlock_irqrestore(&hsudc->lock, flags); -- cgit v1.2.3-59-g8ed1b From 84749c6dcb694a7aa793221ea8cc3d70bd46d466 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 3 Sep 2012 16:15:18 +0530 Subject: usb: gadget: s3c-hsotg: Use devm_clk_get function devm_* functions are already used in this file. Hence convert clk_get to devm_clk_get for completeness. Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsotg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index a826cb98d306..5b90a3c159e6 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -3516,7 +3516,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) hsotg->dev = dev; hsotg->plat = plat; - hsotg->clk = clk_get(&pdev->dev, "otg"); + hsotg->clk = devm_clk_get(&pdev->dev, "otg"); if (IS_ERR(hsotg->clk)) { dev_err(dev, "cannot get otg clock\n"); return PTR_ERR(hsotg->clk); @@ -3664,7 +3664,6 @@ err_supplies: err_clk: clk_disable_unprepare(hsotg->clk); - clk_put(hsotg->clk); return ret; } @@ -3690,7 +3689,6 @@ static int __devexit s3c_hsotg_remove(struct platform_device *pdev) regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); clk_disable_unprepare(hsotg->clk); - clk_put(hsotg->clk); device_unregister(&hsotg->gadget.dev); return 0; -- cgit v1.2.3-59-g8ed1b From 613065e53cb191d00d9d4fc377398b656ed05a45 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 25 Aug 2012 12:38:52 -0700 Subject: usb: gadget: bcm63xx UDC driver Driver for the "USB20D" / "USBD" block on BCM6328, BCM6368, BCM6816, BCM6362, BCM3383, and others. The hardware block was designed to support networking applications (direct connection of a home router to a PC), and the endpoint configuration is fixed. [ balbi@ti.com : dropped USB_GADGET_DUALSPEED from Kconfig ] Signed-off-by: Kevin Cernekee Acked-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 11 + drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/bcm63xx_udc.c | 2464 +++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/gadget_chips.h | 3 + 4 files changed, 2479 insertions(+) create mode 100644 drivers/usb/gadget/bcm63xx_udc.c (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 2ba0d0e2eed6..75b76d5a0fe9 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -159,6 +159,17 @@ config USB_ATMEL_USBA USBA is the integrated high-speed USB Device controller on the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. +config USB_BCM63XX_UDC + tristate "Broadcom BCM63xx Peripheral Controller" + depends on BCM63XX + help + Many Broadcom BCM63xx chipsets (such as the BCM6328) have a + high speed USB Device Port with support for four fixed endpoints + (plus endpoint zero). + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "bcm63xx_udc". + config USB_FSL_USB2 tristate "Freescale Highspeed USB DR Peripheral Controller" depends on FSL_SOC || ARCH_MXC diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 3fd8cd09d2c1..d84f92325a74 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_USB_OMAP) += omap_udc.o obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o obj-$(CONFIG_USB_AT91) += at91_udc.o obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o +obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o fsl_usb2_udc-y := fsl_udc_core.o fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c new file mode 100644 index 000000000000..9ca792224cd4 --- /dev/null +++ b/drivers/usb/gadget/bcm63xx_udc.c @@ -0,0 +1,2464 @@ +/* + * bcm63xx_udc.c -- BCM63xx UDC high/full speed USB device controller + * + * Copyright (C) 2012 Kevin Cernekee + * Copyright (C) 2012 Broadcom Corporation + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define DRV_MODULE_NAME "bcm63xx_udc" + +static const char bcm63xx_ep0name[] = "ep0"; +static const char *const bcm63xx_ep_name[] = { + bcm63xx_ep0name, + "ep1in-bulk", "ep2out-bulk", "ep3in-int", "ep4out-int", +}; + +static bool use_fullspeed; +module_param(use_fullspeed, bool, S_IRUGO); +MODULE_PARM_DESC(use_fullspeed, "true for fullspeed only"); + +/* + * RX IRQ coalescing options: + * + * false (default) - one IRQ per DATAx packet. Slow but reliable. The + * driver is able to pass the "testusb" suite and recover from conditions like: + * + * 1) Device queues up a 2048-byte RX IUDMA transaction on an OUT bulk ep + * 2) Host sends 512 bytes of data + * 3) Host decides to reconfigure the device and sends SET_INTERFACE + * 4) Device shuts down the endpoint and cancels the RX transaction + * + * true - one IRQ per transfer, for transfers <= 2048B. Generates + * considerably fewer IRQs, but error recovery is less robust. Does not + * reliably pass "testusb". + * + * TX always uses coalescing, because we can cancel partially complete TX + * transfers by repeatedly flushing the FIFO. The hardware doesn't allow + * this on RX. + */ +static bool irq_coalesce; +module_param(irq_coalesce, bool, S_IRUGO); +MODULE_PARM_DESC(irq_coalesce, "take one IRQ per RX transfer"); + +#define BCM63XX_NUM_EP 5 +#define BCM63XX_NUM_IUDMA 6 +#define BCM63XX_NUM_FIFO_PAIRS 3 + +#define IUDMA_RESET_TIMEOUT_US 10000 + +#define IUDMA_EP0_RXCHAN 0 +#define IUDMA_EP0_TXCHAN 1 + +#define IUDMA_MAX_FRAGMENT 2048 +#define BCM63XX_MAX_CTRL_PKT 64 + +#define BCMEP_CTRL 0x00 +#define BCMEP_ISOC 0x01 +#define BCMEP_BULK 0x02 +#define BCMEP_INTR 0x03 + +#define BCMEP_OUT 0x00 +#define BCMEP_IN 0x01 + +#define BCM63XX_SPD_FULL 1 +#define BCM63XX_SPD_HIGH 0 + +#define IUDMA_DMAC_OFFSET 0x200 +#define IUDMA_DMAS_OFFSET 0x400 + +enum bcm63xx_ep0_state { + EP0_REQUEUE, + EP0_IDLE, + EP0_IN_DATA_PHASE_SETUP, + EP0_IN_DATA_PHASE_COMPLETE, + EP0_OUT_DATA_PHASE_SETUP, + EP0_OUT_DATA_PHASE_COMPLETE, + EP0_OUT_STATUS_PHASE, + EP0_IN_FAKE_STATUS_PHASE, + EP0_SHUTDOWN, +}; + +static const char __maybe_unused bcm63xx_ep0_state_names[][32] = { + "REQUEUE", + "IDLE", + "IN_DATA_PHASE_SETUP", + "IN_DATA_PHASE_COMPLETE", + "OUT_DATA_PHASE_SETUP", + "OUT_DATA_PHASE_COMPLETE", + "OUT_STATUS_PHASE", + "IN_FAKE_STATUS_PHASE", + "SHUTDOWN", +}; + +/** + * struct iudma_ch_cfg - Static configuration for an IUDMA channel. + * @ep_num: USB endpoint number. + * @n_bds: Number of buffer descriptors in the ring. + * @ep_type: Endpoint type (control, bulk, interrupt). + * @dir: Direction (in, out). + * @n_fifo_slots: Number of FIFO entries to allocate for this channel. + * @max_pkt_hs: Maximum packet size in high speed mode. + * @max_pkt_fs: Maximum packet size in full speed mode. + */ +struct iudma_ch_cfg { + int ep_num; + int n_bds; + int ep_type; + int dir; + int n_fifo_slots; + int max_pkt_hs; + int max_pkt_fs; +}; + +static const struct iudma_ch_cfg iudma_defaults[] = { + + /* This controller was designed to support a CDC/RNDIS application. + It may be possible to reconfigure some of the endpoints, but + the hardware limitations (FIFO sizing and number of DMA channels) + may significantly impact flexibility and/or stability. Change + these values at your own risk. + + ep_num ep_type n_fifo_slots max_pkt_fs + idx | n_bds | dir | max_pkt_hs | + | | | | | | | | */ + [0] = { -1, 4, BCMEP_CTRL, BCMEP_OUT, 32, 64, 64 }, + [1] = { 0, 4, BCMEP_CTRL, BCMEP_OUT, 32, 64, 64 }, + [2] = { 2, 16, BCMEP_BULK, BCMEP_OUT, 128, 512, 64 }, + [3] = { 1, 16, BCMEP_BULK, BCMEP_IN, 128, 512, 64 }, + [4] = { 4, 4, BCMEP_INTR, BCMEP_OUT, 32, 64, 64 }, + [5] = { 3, 4, BCMEP_INTR, BCMEP_IN, 32, 64, 64 }, +}; + +struct bcm63xx_udc; + +/** + * struct iudma_ch - Represents the current state of a single IUDMA channel. + * @ch_idx: IUDMA channel index (0 to BCM63XX_NUM_IUDMA-1). + * @ep_num: USB endpoint number. -1 for ep0 RX. + * @enabled: Whether bcm63xx_ep_enable() has been called. + * @max_pkt: "Chunk size" on the USB interface. Based on interface speed. + * @is_tx: true for TX, false for RX. + * @bep: Pointer to the associated endpoint. NULL for ep0 RX. + * @udc: Reference to the device controller. + * @read_bd: Next buffer descriptor to reap from the hardware. + * @write_bd: Next BD available for a new packet. + * @end_bd: Points to the final BD in the ring. + * @n_bds_used: Number of BD entries currently occupied. + * @bd_ring: Base pointer to the BD ring. + * @bd_ring_dma: Physical (DMA) address of bd_ring. + * @n_bds: Total number of BDs in the ring. + * + * ep0 has two IUDMA channels (IUDMA_EP0_RXCHAN and IUDMA_EP0_TXCHAN), as it is + * bidirectional. The "struct usb_ep" associated with ep0 is for TX (IN) + * only. + * + * Each bulk/intr endpoint has a single IUDMA channel and a single + * struct usb_ep. + */ +struct iudma_ch { + unsigned int ch_idx; + int ep_num; + bool enabled; + int max_pkt; + bool is_tx; + struct bcm63xx_ep *bep; + struct bcm63xx_udc *udc; + + struct bcm_enet_desc *read_bd; + struct bcm_enet_desc *write_bd; + struct bcm_enet_desc *end_bd; + int n_bds_used; + + struct bcm_enet_desc *bd_ring; + dma_addr_t bd_ring_dma; + unsigned int n_bds; +}; + +/** + * struct bcm63xx_ep - Internal (driver) state of a single endpoint. + * @ep_num: USB endpoint number. + * @iudma: Pointer to IUDMA channel state. + * @ep: USB gadget layer representation of the EP. + * @udc: Reference to the device controller. + * @queue: Linked list of outstanding requests for this EP. + * @halted: 1 if the EP is stalled; 0 otherwise. + */ +struct bcm63xx_ep { + unsigned int ep_num; + struct iudma_ch *iudma; + struct usb_ep ep; + struct bcm63xx_udc *udc; + struct list_head queue; + unsigned halted:1; +}; + +/** + * struct bcm63xx_req - Internal (driver) state of a single request. + * @queue: Links back to the EP's request list. + * @req: USB gadget layer representation of the request. + * @offset: Current byte offset into the data buffer (next byte to queue). + * @bd_bytes: Number of data bytes in outstanding BD entries. + * @iudma: IUDMA channel used for the request. + */ +struct bcm63xx_req { + struct list_head queue; /* ep's requests */ + struct usb_request req; + unsigned int offset; + unsigned int bd_bytes; + struct iudma_ch *iudma; +}; + +/** + * struct bcm63xx_udc - Driver/hardware private context. + * @lock: Spinlock to mediate access to this struct, and (most) HW regs. + * @dev: Generic Linux device structure. + * @pd: Platform data (board/port info). + * @usbd_clk: Clock descriptor for the USB device block. + * @usbh_clk: Clock descriptor for the USB host block. + * @gadget: USB slave device. + * @driver: Driver for USB slave devices. + * @usbd_regs: Base address of the USBD/USB20D block. + * @iudma_regs: Base address of the USBD's associated IUDMA block. + * @bep: Array of endpoints, including ep0. + * @iudma: Array of all IUDMA channels used by this controller. + * @cfg: USB configuration number, from SET_CONFIGURATION wValue. + * @iface: USB interface number, from SET_INTERFACE wIndex. + * @alt_iface: USB alt interface number, from SET_INTERFACE wValue. + * @ep0_ctrl_req: Request object for bcm63xx_udc-initiated ep0 transactions. + * @ep0_ctrl_buf: Data buffer for ep0_ctrl_req. + * @ep0state: Current state of the ep0 state machine. + * @ep0_wq: Workqueue struct used to wake up the ep0 state machine. + * @wedgemap: Bitmap of wedged endpoints. + * @ep0_req_reset: USB reset is pending. + * @ep0_req_set_cfg: Need to spoof a SET_CONFIGURATION packet. + * @ep0_req_set_iface: Need to spoof a SET_INTERFACE packet. + * @ep0_req_shutdown: Driver is shutting down; requesting ep0 to halt activity. + * @ep0_req_completed: ep0 request has completed; worker has not seen it yet. + * @ep0_reply: Pending reply from gadget driver. + * @ep0_request: Outstanding ep0 request. + * @debugfs_root: debugfs directory: /sys/kernel/debug/. + * @debugfs_usbd: debugfs file "usbd" for controller state. + * @debugfs_iudma: debugfs file "usbd" for IUDMA state. + */ +struct bcm63xx_udc { + spinlock_t lock; + + struct device *dev; + struct bcm63xx_usbd_platform_data *pd; + struct clk *usbd_clk; + struct clk *usbh_clk; + + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + + void __iomem *usbd_regs; + void __iomem *iudma_regs; + + struct bcm63xx_ep bep[BCM63XX_NUM_EP]; + struct iudma_ch iudma[BCM63XX_NUM_IUDMA]; + + int cfg; + int iface; + int alt_iface; + + struct bcm63xx_req ep0_ctrl_req; + u8 *ep0_ctrl_buf; + + int ep0state; + struct work_struct ep0_wq; + + unsigned long wedgemap; + + unsigned ep0_req_reset:1; + unsigned ep0_req_set_cfg:1; + unsigned ep0_req_set_iface:1; + unsigned ep0_req_shutdown:1; + + unsigned ep0_req_completed:1; + struct usb_request *ep0_reply; + struct usb_request *ep0_request; + + struct dentry *debugfs_root; + struct dentry *debugfs_usbd; + struct dentry *debugfs_iudma; +}; + +static const struct usb_ep_ops bcm63xx_udc_ep_ops; + +/*********************************************************************** + * Convenience functions + ***********************************************************************/ + +static inline struct bcm63xx_udc *gadget_to_udc(struct usb_gadget *g) +{ + return container_of(g, struct bcm63xx_udc, gadget); +} + +static inline struct bcm63xx_ep *our_ep(struct usb_ep *ep) +{ + return container_of(ep, struct bcm63xx_ep, ep); +} + +static inline struct bcm63xx_req *our_req(struct usb_request *req) +{ + return container_of(req, struct bcm63xx_req, req); +} + +static inline u32 usbd_readl(struct bcm63xx_udc *udc, u32 off) +{ + return bcm_readl(udc->usbd_regs + off); +} + +static inline void usbd_writel(struct bcm63xx_udc *udc, u32 val, u32 off) +{ + bcm_writel(val, udc->usbd_regs + off); +} + +static inline u32 usb_dma_readl(struct bcm63xx_udc *udc, u32 off) +{ + return bcm_readl(udc->iudma_regs + off); +} + +static inline void usb_dma_writel(struct bcm63xx_udc *udc, u32 val, u32 off) +{ + bcm_writel(val, udc->iudma_regs + off); +} + +static inline u32 usb_dmac_readl(struct bcm63xx_udc *udc, u32 off) +{ + return bcm_readl(udc->iudma_regs + IUDMA_DMAC_OFFSET + off); +} + +static inline void usb_dmac_writel(struct bcm63xx_udc *udc, u32 val, u32 off) +{ + bcm_writel(val, udc->iudma_regs + IUDMA_DMAC_OFFSET + off); +} + +static inline u32 usb_dmas_readl(struct bcm63xx_udc *udc, u32 off) +{ + return bcm_readl(udc->iudma_regs + IUDMA_DMAS_OFFSET + off); +} + +static inline void usb_dmas_writel(struct bcm63xx_udc *udc, u32 val, u32 off) +{ + bcm_writel(val, udc->iudma_regs + IUDMA_DMAS_OFFSET + off); +} + +static inline void set_clocks(struct bcm63xx_udc *udc, bool is_enabled) +{ + if (is_enabled) { + clk_enable(udc->usbh_clk); + clk_enable(udc->usbd_clk); + udelay(10); + } else { + clk_disable(udc->usbd_clk); + clk_disable(udc->usbh_clk); + } +} + +/*********************************************************************** + * Low-level IUDMA / FIFO operations + ***********************************************************************/ + +/** + * bcm63xx_ep_dma_select - Helper function to set up the init_sel signal. + * @udc: Reference to the device controller. + * @idx: Desired init_sel value. + * + * The "init_sel" signal is used as a selection index for both endpoints + * and IUDMA channels. Since these do not map 1:1, the use of this signal + * depends on the context. + */ +static void bcm63xx_ep_dma_select(struct bcm63xx_udc *udc, int idx) +{ + u32 val = usbd_readl(udc, USBD_CONTROL_REG); + + val &= ~USBD_CONTROL_INIT_SEL_MASK; + val |= idx << USBD_CONTROL_INIT_SEL_SHIFT; + usbd_writel(udc, val, USBD_CONTROL_REG); +} + +/** + * bcm63xx_set_stall - Enable/disable stall on one endpoint. + * @udc: Reference to the device controller. + * @bep: Endpoint on which to operate. + * @is_stalled: true to enable stall, false to disable. + * + * See notes in bcm63xx_update_wedge() regarding automatic clearing of + * halt/stall conditions. + */ +static void bcm63xx_set_stall(struct bcm63xx_udc *udc, struct bcm63xx_ep *bep, + bool is_stalled) +{ + u32 val; + + val = USBD_STALL_UPDATE_MASK | + (is_stalled ? USBD_STALL_ENABLE_MASK : 0) | + (bep->ep_num << USBD_STALL_EPNUM_SHIFT); + usbd_writel(udc, val, USBD_STALL_REG); +} + +/** + * bcm63xx_fifo_setup - (Re)initialize FIFO boundaries and settings. + * @udc: Reference to the device controller. + * + * These parameters depend on the USB link speed. Settings are + * per-IUDMA-channel-pair. + */ +static void bcm63xx_fifo_setup(struct bcm63xx_udc *udc) +{ + int is_hs = udc->gadget.speed == USB_SPEED_HIGH; + u32 i, val, rx_fifo_slot, tx_fifo_slot; + + /* set up FIFO boundaries and packet sizes; this is done in pairs */ + rx_fifo_slot = tx_fifo_slot = 0; + for (i = 0; i < BCM63XX_NUM_IUDMA; i += 2) { + const struct iudma_ch_cfg *rx_cfg = &iudma_defaults[i]; + const struct iudma_ch_cfg *tx_cfg = &iudma_defaults[i + 1]; + + bcm63xx_ep_dma_select(udc, i >> 1); + + val = (rx_fifo_slot << USBD_RXFIFO_CONFIG_START_SHIFT) | + ((rx_fifo_slot + rx_cfg->n_fifo_slots - 1) << + USBD_RXFIFO_CONFIG_END_SHIFT); + rx_fifo_slot += rx_cfg->n_fifo_slots; + usbd_writel(udc, val, USBD_RXFIFO_CONFIG_REG); + usbd_writel(udc, + is_hs ? rx_cfg->max_pkt_hs : rx_cfg->max_pkt_fs, + USBD_RXFIFO_EPSIZE_REG); + + val = (tx_fifo_slot << USBD_TXFIFO_CONFIG_START_SHIFT) | + ((tx_fifo_slot + tx_cfg->n_fifo_slots - 1) << + USBD_TXFIFO_CONFIG_END_SHIFT); + tx_fifo_slot += tx_cfg->n_fifo_slots; + usbd_writel(udc, val, USBD_TXFIFO_CONFIG_REG); + usbd_writel(udc, + is_hs ? tx_cfg->max_pkt_hs : tx_cfg->max_pkt_fs, + USBD_TXFIFO_EPSIZE_REG); + + usbd_readl(udc, USBD_TXFIFO_EPSIZE_REG); + } +} + +/** + * bcm63xx_fifo_reset_ep - Flush a single endpoint's FIFO. + * @udc: Reference to the device controller. + * @ep_num: Endpoint number. + */ +static void bcm63xx_fifo_reset_ep(struct bcm63xx_udc *udc, int ep_num) +{ + u32 val; + + bcm63xx_ep_dma_select(udc, ep_num); + + val = usbd_readl(udc, USBD_CONTROL_REG); + val |= USBD_CONTROL_FIFO_RESET_MASK; + usbd_writel(udc, val, USBD_CONTROL_REG); + usbd_readl(udc, USBD_CONTROL_REG); +} + +/** + * bcm63xx_fifo_reset - Flush all hardware FIFOs. + * @udc: Reference to the device controller. + */ +static void bcm63xx_fifo_reset(struct bcm63xx_udc *udc) +{ + int i; + + for (i = 0; i < BCM63XX_NUM_FIFO_PAIRS; i++) + bcm63xx_fifo_reset_ep(udc, i); +} + +/** + * bcm63xx_ep_init - Initial (one-time) endpoint initialization. + * @udc: Reference to the device controller. + */ +static void bcm63xx_ep_init(struct bcm63xx_udc *udc) +{ + u32 i, val; + + for (i = 0; i < BCM63XX_NUM_IUDMA; i++) { + const struct iudma_ch_cfg *cfg = &iudma_defaults[i]; + + if (cfg->ep_num < 0) + continue; + + bcm63xx_ep_dma_select(udc, cfg->ep_num); + val = (cfg->ep_type << USBD_EPNUM_TYPEMAP_TYPE_SHIFT) | + ((i >> 1) << USBD_EPNUM_TYPEMAP_DMA_CH_SHIFT); + usbd_writel(udc, val, USBD_EPNUM_TYPEMAP_REG); + } +} + +/** + * bcm63xx_ep_setup - Configure per-endpoint settings. + * @udc: Reference to the device controller. + * + * This needs to be rerun if the speed/cfg/intf/altintf changes. + */ +static void bcm63xx_ep_setup(struct bcm63xx_udc *udc) +{ + u32 val, i; + + usbd_writel(udc, USBD_CSR_SETUPADDR_DEF, USBD_CSR_SETUPADDR_REG); + + for (i = 0; i < BCM63XX_NUM_IUDMA; i++) { + const struct iudma_ch_cfg *cfg = &iudma_defaults[i]; + int max_pkt = udc->gadget.speed == USB_SPEED_HIGH ? + cfg->max_pkt_hs : cfg->max_pkt_fs; + int idx = cfg->ep_num; + + udc->iudma[i].max_pkt = max_pkt; + + if (idx < 0) + continue; + udc->bep[idx].ep.maxpacket = max_pkt; + + val = (idx << USBD_CSR_EP_LOG_SHIFT) | + (cfg->dir << USBD_CSR_EP_DIR_SHIFT) | + (cfg->ep_type << USBD_CSR_EP_TYPE_SHIFT) | + (udc->cfg << USBD_CSR_EP_CFG_SHIFT) | + (udc->iface << USBD_CSR_EP_IFACE_SHIFT) | + (udc->alt_iface << USBD_CSR_EP_ALTIFACE_SHIFT) | + (max_pkt << USBD_CSR_EP_MAXPKT_SHIFT); + usbd_writel(udc, val, USBD_CSR_EP_REG(idx)); + } +} + +/** + * iudma_write - Queue a single IUDMA transaction. + * @udc: Reference to the device controller. + * @iudma: IUDMA channel to use. + * @breq: Request containing the transaction data. + * + * For RX IUDMA, this will queue a single buffer descriptor, as RX IUDMA + * does not honor SOP/EOP so the handling of multiple buffers is ambiguous. + * So iudma_write() may be called several times to fulfill a single + * usb_request. + * + * For TX IUDMA, this can queue multiple buffer descriptors if needed. + */ +static void iudma_write(struct bcm63xx_udc *udc, struct iudma_ch *iudma, + struct bcm63xx_req *breq) +{ + int first_bd = 1, last_bd = 0, extra_zero_pkt = 0; + unsigned int bytes_left = breq->req.length - breq->offset; + const int max_bd_bytes = !irq_coalesce && !iudma->is_tx ? + iudma->max_pkt : IUDMA_MAX_FRAGMENT; + + iudma->n_bds_used = 0; + breq->bd_bytes = 0; + breq->iudma = iudma; + + if ((bytes_left % iudma->max_pkt == 0) && bytes_left && breq->req.zero) + extra_zero_pkt = 1; + + do { + struct bcm_enet_desc *d = iudma->write_bd; + u32 dmaflags = 0; + unsigned int n_bytes; + + if (d == iudma->end_bd) { + dmaflags |= DMADESC_WRAP_MASK; + iudma->write_bd = iudma->bd_ring; + } else { + iudma->write_bd++; + } + iudma->n_bds_used++; + + n_bytes = min_t(int, bytes_left, max_bd_bytes); + if (n_bytes) + dmaflags |= n_bytes << DMADESC_LENGTH_SHIFT; + else + dmaflags |= (1 << DMADESC_LENGTH_SHIFT) | + DMADESC_USB_ZERO_MASK; + + dmaflags |= DMADESC_OWNER_MASK; + if (first_bd) { + dmaflags |= DMADESC_SOP_MASK; + first_bd = 0; + } + + /* + * extra_zero_pkt forces one more iteration through the loop + * after all data is queued up, to send the zero packet + */ + if (extra_zero_pkt && !bytes_left) + extra_zero_pkt = 0; + + if (!iudma->is_tx || iudma->n_bds_used == iudma->n_bds || + (n_bytes == bytes_left && !extra_zero_pkt)) { + last_bd = 1; + dmaflags |= DMADESC_EOP_MASK; + } + + d->address = breq->req.dma + breq->offset; + mb(); + d->len_stat = dmaflags; + + breq->offset += n_bytes; + breq->bd_bytes += n_bytes; + bytes_left -= n_bytes; + } while (!last_bd); + + usb_dmac_writel(udc, ENETDMAC_CHANCFG_EN_MASK, + ENETDMAC_CHANCFG_REG(iudma->ch_idx)); +} + +/** + * iudma_read - Check for IUDMA buffer completion. + * @udc: Reference to the device controller. + * @iudma: IUDMA channel to use. + * + * This checks to see if ALL of the outstanding BDs on the DMA channel + * have been filled. If so, it returns the actual transfer length; + * otherwise it returns -EBUSY. + */ +static int iudma_read(struct bcm63xx_udc *udc, struct iudma_ch *iudma) +{ + int i, actual_len = 0; + struct bcm_enet_desc *d = iudma->read_bd; + + if (!iudma->n_bds_used) + return -EINVAL; + + for (i = 0; i < iudma->n_bds_used; i++) { + u32 dmaflags; + + dmaflags = d->len_stat; + + if (dmaflags & DMADESC_OWNER_MASK) + return -EBUSY; + + actual_len += (dmaflags & DMADESC_LENGTH_MASK) >> + DMADESC_LENGTH_SHIFT; + if (d == iudma->end_bd) + d = iudma->bd_ring; + else + d++; + } + + iudma->read_bd = d; + iudma->n_bds_used = 0; + return actual_len; +} + +/** + * iudma_reset_channel - Stop DMA on a single channel. + * @udc: Reference to the device controller. + * @iudma: IUDMA channel to reset. + */ +static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma) +{ + int timeout = IUDMA_RESET_TIMEOUT_US; + struct bcm_enet_desc *d; + int ch_idx = iudma->ch_idx; + + if (!iudma->is_tx) + bcm63xx_fifo_reset_ep(udc, max(0, iudma->ep_num)); + + /* stop DMA, then wait for the hardware to wrap up */ + usb_dmac_writel(udc, 0, ENETDMAC_CHANCFG_REG(ch_idx)); + + while (usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG(ch_idx)) & + ENETDMAC_CHANCFG_EN_MASK) { + udelay(1); + + /* repeatedly flush the FIFO data until the BD completes */ + if (iudma->is_tx && iudma->ep_num >= 0) + bcm63xx_fifo_reset_ep(udc, iudma->ep_num); + + if (!timeout--) { + dev_err(udc->dev, "can't reset IUDMA channel %d\n", + ch_idx); + break; + } + if (timeout == IUDMA_RESET_TIMEOUT_US / 2) { + dev_warn(udc->dev, "forcibly halting IUDMA channel %d\n", + ch_idx); + usb_dmac_writel(udc, ENETDMAC_CHANCFG_BUFHALT_MASK, + ENETDMAC_CHANCFG_REG(ch_idx)); + } + } + usb_dmac_writel(udc, ~0, ENETDMAC_IR_REG(ch_idx)); + + /* don't leave "live" HW-owned entries for the next guy to step on */ + for (d = iudma->bd_ring; d <= iudma->end_bd; d++) + d->len_stat = 0; + mb(); + + iudma->read_bd = iudma->write_bd = iudma->bd_ring; + iudma->n_bds_used = 0; + + /* set up IRQs, UBUS burst size, and BD base for this channel */ + usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, + ENETDMAC_IRMASK_REG(ch_idx)); + usb_dmac_writel(udc, 8, ENETDMAC_MAXBURST_REG(ch_idx)); + + usb_dmas_writel(udc, iudma->bd_ring_dma, ENETDMAS_RSTART_REG(ch_idx)); + usb_dmas_writel(udc, 0, ENETDMAS_SRAM2_REG(ch_idx)); +} + +/** + * iudma_init_channel - One-time IUDMA channel initialization. + * @udc: Reference to the device controller. + * @ch_idx: Channel to initialize. + */ +static int iudma_init_channel(struct bcm63xx_udc *udc, unsigned int ch_idx) +{ + struct iudma_ch *iudma = &udc->iudma[ch_idx]; + const struct iudma_ch_cfg *cfg = &iudma_defaults[ch_idx]; + unsigned int n_bds = cfg->n_bds; + struct bcm63xx_ep *bep = NULL; + + iudma->ep_num = cfg->ep_num; + iudma->ch_idx = ch_idx; + iudma->is_tx = !!(ch_idx & 0x01); + if (iudma->ep_num >= 0) { + bep = &udc->bep[iudma->ep_num]; + bep->iudma = iudma; + INIT_LIST_HEAD(&bep->queue); + } + + iudma->bep = bep; + iudma->udc = udc; + + /* ep0 is always active; others are controlled by the gadget driver */ + if (iudma->ep_num <= 0) + iudma->enabled = true; + + iudma->n_bds = n_bds; + iudma->bd_ring = dmam_alloc_coherent(udc->dev, + n_bds * sizeof(struct bcm_enet_desc), + &iudma->bd_ring_dma, GFP_KERNEL); + if (!iudma->bd_ring) + return -ENOMEM; + iudma->end_bd = &iudma->bd_ring[n_bds - 1]; + + return 0; +} + +/** + * iudma_init - One-time initialization of all IUDMA channels. + * @udc: Reference to the device controller. + * + * Enable DMA, flush channels, and enable global IUDMA IRQs. + */ +static int iudma_init(struct bcm63xx_udc *udc) +{ + int i, rc; + + usb_dma_writel(udc, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG); + + for (i = 0; i < BCM63XX_NUM_IUDMA; i++) { + rc = iudma_init_channel(udc, i); + if (rc) + return rc; + iudma_reset_channel(udc, &udc->iudma[i]); + } + + usb_dma_writel(udc, BIT(BCM63XX_NUM_IUDMA)-1, ENETDMA_GLB_IRQMASK_REG); + return 0; +} + +/** + * iudma_uninit - Uninitialize IUDMA channels. + * @udc: Reference to the device controller. + * + * Kill global IUDMA IRQs, flush channels, and kill DMA. + */ +static void iudma_uninit(struct bcm63xx_udc *udc) +{ + int i; + + usb_dma_writel(udc, 0, ENETDMA_GLB_IRQMASK_REG); + + for (i = 0; i < BCM63XX_NUM_IUDMA; i++) + iudma_reset_channel(udc, &udc->iudma[i]); + + usb_dma_writel(udc, 0, ENETDMA_CFG_REG); +} + +/*********************************************************************** + * Other low-level USBD operations + ***********************************************************************/ + +/** + * bcm63xx_set_ctrl_irqs - Mask/unmask control path interrupts. + * @udc: Reference to the device controller. + * @enable_irqs: true to enable, false to disable. + */ +static void bcm63xx_set_ctrl_irqs(struct bcm63xx_udc *udc, bool enable_irqs) +{ + u32 val; + + usbd_writel(udc, 0, USBD_STATUS_REG); + + val = BIT(USBD_EVENT_IRQ_USB_RESET) | + BIT(USBD_EVENT_IRQ_SETUP) | + BIT(USBD_EVENT_IRQ_SETCFG) | + BIT(USBD_EVENT_IRQ_SETINTF) | + BIT(USBD_EVENT_IRQ_USB_LINK); + usbd_writel(udc, enable_irqs ? val : 0, USBD_EVENT_IRQ_MASK_REG); + usbd_writel(udc, val, USBD_EVENT_IRQ_STATUS_REG); +} + +/** + * bcm63xx_select_phy_mode - Select between USB device and host mode. + * @udc: Reference to the device controller. + * @is_device: true for device, false for host. + * + * This should probably be reworked to use the drivers/usb/otg + * infrastructure. + * + * By default, the AFE/pullups are disabled in device mode, until + * bcm63xx_select_pullup() is called. + */ +static void bcm63xx_select_phy_mode(struct bcm63xx_udc *udc, bool is_device) +{ + u32 val, portmask = BIT(udc->pd->port_no); + + if (BCMCPU_IS_6328()) { + /* configure pinmux to sense VBUS signal */ + val = bcm_gpio_readl(GPIO_PINMUX_OTHR_REG); + val &= ~GPIO_PINMUX_OTHR_6328_USB_MASK; + val |= is_device ? GPIO_PINMUX_OTHR_6328_USB_DEV : + GPIO_PINMUX_OTHR_6328_USB_HOST; + bcm_gpio_writel(val, GPIO_PINMUX_OTHR_REG); + } + + val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_UTMI_CTL_6368_REG); + if (is_device) { + val |= (portmask << USBH_PRIV_UTMI_CTL_HOSTB_SHIFT); + val |= (portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT); + } else { + val &= ~(portmask << USBH_PRIV_UTMI_CTL_HOSTB_SHIFT); + val &= ~(portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT); + } + bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_UTMI_CTL_6368_REG); + + val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG); + if (is_device) + val |= USBH_PRIV_SWAP_USBD_MASK; + else + val &= ~USBH_PRIV_SWAP_USBD_MASK; + bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_SWAP_6368_REG); +} + +/** + * bcm63xx_select_pullup - Enable/disable the pullup on D+ + * @udc: Reference to the device controller. + * @is_on: true to enable the pullup, false to disable. + * + * If the pullup is active, the host will sense a FS/HS device connected to + * the port. If the pullup is inactive, the host will think the USB + * device has been disconnected. + */ +static void bcm63xx_select_pullup(struct bcm63xx_udc *udc, bool is_on) +{ + u32 val, portmask = BIT(udc->pd->port_no); + + val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_UTMI_CTL_6368_REG); + if (is_on) + val &= ~(portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT); + else + val |= (portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT); + bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_UTMI_CTL_6368_REG); +} + +/** + * bcm63xx_uninit_udc_hw - Shut down the hardware prior to driver removal. + * @udc: Reference to the device controller. + * + * This just masks the IUDMA IRQs and releases the clocks. It is assumed + * that bcm63xx_udc_stop() has already run, and the clocks are stopped. + */ +static void bcm63xx_uninit_udc_hw(struct bcm63xx_udc *udc) +{ + set_clocks(udc, true); + iudma_uninit(udc); + set_clocks(udc, false); + + clk_put(udc->usbd_clk); + clk_put(udc->usbh_clk); +} + +/** + * bcm63xx_init_udc_hw - Initialize the controller hardware and data structures. + * @udc: Reference to the device controller. + */ +static int bcm63xx_init_udc_hw(struct bcm63xx_udc *udc) +{ + int i, rc = 0; + u32 val; + + udc->ep0_ctrl_buf = devm_kzalloc(udc->dev, BCM63XX_MAX_CTRL_PKT, + GFP_KERNEL); + if (!udc->ep0_ctrl_buf) + return -ENOMEM; + + INIT_LIST_HEAD(&udc->gadget.ep_list); + for (i = 0; i < BCM63XX_NUM_EP; i++) { + struct bcm63xx_ep *bep = &udc->bep[i]; + + bep->ep.name = bcm63xx_ep_name[i]; + bep->ep_num = i; + bep->ep.ops = &bcm63xx_udc_ep_ops; + list_add_tail(&bep->ep.ep_list, &udc->gadget.ep_list); + bep->halted = 0; + bep->ep.maxpacket = BCM63XX_MAX_CTRL_PKT; + bep->udc = udc; + bep->ep.desc = NULL; + INIT_LIST_HEAD(&bep->queue); + } + + udc->gadget.ep0 = &udc->bep[0].ep; + list_del(&udc->bep[0].ep.ep_list); + + udc->gadget.speed = USB_SPEED_UNKNOWN; + udc->ep0state = EP0_SHUTDOWN; + + udc->usbh_clk = clk_get(udc->dev, "usbh"); + if (IS_ERR(udc->usbh_clk)) + return -EIO; + + udc->usbd_clk = clk_get(udc->dev, "usbd"); + if (IS_ERR(udc->usbd_clk)) { + clk_put(udc->usbh_clk); + return -EIO; + } + + set_clocks(udc, true); + + val = USBD_CONTROL_AUTO_CSRS_MASK | + USBD_CONTROL_DONE_CSRS_MASK | + (irq_coalesce ? USBD_CONTROL_RXZSCFG_MASK : 0); + usbd_writel(udc, val, USBD_CONTROL_REG); + + val = USBD_STRAPS_APP_SELF_PWR_MASK | + USBD_STRAPS_APP_RAM_IF_MASK | + USBD_STRAPS_APP_CSRPRGSUP_MASK | + USBD_STRAPS_APP_8BITPHY_MASK | + USBD_STRAPS_APP_RMTWKUP_MASK; + + if (udc->gadget.max_speed == USB_SPEED_HIGH) + val |= (BCM63XX_SPD_HIGH << USBD_STRAPS_SPEED_SHIFT); + else + val |= (BCM63XX_SPD_FULL << USBD_STRAPS_SPEED_SHIFT); + usbd_writel(udc, val, USBD_STRAPS_REG); + + bcm63xx_set_ctrl_irqs(udc, false); + + usbd_writel(udc, 0, USBD_EVENT_IRQ_CFG_LO_REG); + + val = USBD_EVENT_IRQ_CFG_FALLING(USBD_EVENT_IRQ_ENUM_ON) | + USBD_EVENT_IRQ_CFG_FALLING(USBD_EVENT_IRQ_SET_CSRS); + usbd_writel(udc, val, USBD_EVENT_IRQ_CFG_HI_REG); + + rc = iudma_init(udc); + set_clocks(udc, false); + if (rc) + bcm63xx_uninit_udc_hw(udc); + + return 0; +} + +/*********************************************************************** + * Standard EP gadget operations + ***********************************************************************/ + +/** + * bcm63xx_ep_enable - Enable one endpoint. + * @ep: Endpoint to enable. + * @desc: Contains max packet, direction, etc. + * + * Most of the endpoint parameters are fixed in this controller, so there + * isn't much for this function to do. + */ +static int bcm63xx_ep_enable(struct usb_ep *ep, + const struct usb_endpoint_descriptor *desc) +{ + struct bcm63xx_ep *bep = our_ep(ep); + struct bcm63xx_udc *udc = bep->udc; + struct iudma_ch *iudma = bep->iudma; + unsigned long flags; + + if (!ep || !desc || ep->name == bcm63xx_ep0name) + return -EINVAL; + + if (!udc->driver) + return -ESHUTDOWN; + + spin_lock_irqsave(&udc->lock, flags); + if (iudma->enabled) { + spin_unlock_irqrestore(&udc->lock, flags); + return -EINVAL; + } + + iudma->enabled = true; + BUG_ON(!list_empty(&bep->queue)); + + iudma_reset_channel(udc, iudma); + + bep->halted = 0; + bcm63xx_set_stall(udc, bep, false); + clear_bit(bep->ep_num, &udc->wedgemap); + + ep->desc = desc; + ep->maxpacket = usb_endpoint_maxp(desc); + + spin_unlock_irqrestore(&udc->lock, flags); + return 0; +} + +/** + * bcm63xx_ep_disable - Disable one endpoint. + * @ep: Endpoint to disable. + */ +static int bcm63xx_ep_disable(struct usb_ep *ep) +{ + struct bcm63xx_ep *bep = our_ep(ep); + struct bcm63xx_udc *udc = bep->udc; + struct iudma_ch *iudma = bep->iudma; + struct list_head *pos, *n; + unsigned long flags; + + if (!ep || !ep->desc) + return -EINVAL; + + spin_lock_irqsave(&udc->lock, flags); + if (!iudma->enabled) { + spin_unlock_irqrestore(&udc->lock, flags); + return -EINVAL; + } + iudma->enabled = false; + + iudma_reset_channel(udc, iudma); + + if (!list_empty(&bep->queue)) { + list_for_each_safe(pos, n, &bep->queue) { + struct bcm63xx_req *breq = + list_entry(pos, struct bcm63xx_req, queue); + + usb_gadget_unmap_request(&udc->gadget, &breq->req, + iudma->is_tx); + list_del(&breq->queue); + breq->req.status = -ESHUTDOWN; + + spin_unlock_irqrestore(&udc->lock, flags); + breq->req.complete(&iudma->bep->ep, &breq->req); + spin_lock_irqsave(&udc->lock, flags); + } + } + ep->desc = NULL; + + spin_unlock_irqrestore(&udc->lock, flags); + return 0; +} + +/** + * bcm63xx_udc_alloc_request - Allocate a new request. + * @ep: Endpoint associated with the request. + * @mem_flags: Flags to pass to kzalloc(). + */ +static struct usb_request *bcm63xx_udc_alloc_request(struct usb_ep *ep, + gfp_t mem_flags) +{ + struct bcm63xx_req *breq; + + breq = kzalloc(sizeof(*breq), mem_flags); + if (!breq) + return NULL; + return &breq->req; +} + +/** + * bcm63xx_udc_free_request - Free a request. + * @ep: Endpoint associated with the request. + * @req: Request to free. + */ +static void bcm63xx_udc_free_request(struct usb_ep *ep, + struct usb_request *req) +{ + struct bcm63xx_req *breq = our_req(req); + kfree(breq); +} + +/** + * bcm63xx_udc_queue - Queue up a new request. + * @ep: Endpoint associated with the request. + * @req: Request to add. + * @mem_flags: Unused. + * + * If the queue is empty, start this request immediately. Otherwise, add + * it to the list. + * + * ep0 replies are sent through this function from the gadget driver, but + * they are treated differently because they need to be handled by the ep0 + * state machine. (Sometimes they are replies to control requests that + * were spoofed by this driver, and so they shouldn't be transmitted at all.) + */ +static int bcm63xx_udc_queue(struct usb_ep *ep, struct usb_request *req, + gfp_t mem_flags) +{ + struct bcm63xx_ep *bep = our_ep(ep); + struct bcm63xx_udc *udc = bep->udc; + struct bcm63xx_req *breq = our_req(req); + unsigned long flags; + int rc = 0; + + if (unlikely(!req || !req->complete || !req->buf || !ep)) + return -EINVAL; + + req->actual = 0; + req->status = 0; + breq->offset = 0; + + if (bep == &udc->bep[0]) { + /* only one reply per request, please */ + if (udc->ep0_reply) + return -EINVAL; + + udc->ep0_reply = req; + schedule_work(&udc->ep0_wq); + return 0; + } + + spin_lock_irqsave(&udc->lock, flags); + if (!bep->iudma->enabled) { + rc = -ESHUTDOWN; + goto out; + } + + rc = usb_gadget_map_request(&udc->gadget, req, bep->iudma->is_tx); + if (rc == 0) { + list_add_tail(&breq->queue, &bep->queue); + if (list_is_singular(&bep->queue)) + iudma_write(udc, bep->iudma, breq); + } + +out: + spin_unlock_irqrestore(&udc->lock, flags); + return rc; +} + +/** + * bcm63xx_udc_dequeue - Remove a pending request from the queue. + * @ep: Endpoint associated with the request. + * @req: Request to remove. + * + * If the request is not at the head of the queue, this is easy - just nuke + * it. If the request is at the head of the queue, we'll need to stop the + * DMA transaction and then queue up the successor. + */ +static int bcm63xx_udc_dequeue(struct usb_ep *ep, struct usb_request *req) +{ + struct bcm63xx_ep *bep = our_ep(ep); + struct bcm63xx_udc *udc = bep->udc; + struct bcm63xx_req *breq = our_req(req), *cur; + unsigned long flags; + int rc = 0; + + spin_lock_irqsave(&udc->lock, flags); + if (list_empty(&bep->queue)) { + rc = -EINVAL; + goto out; + } + + cur = list_first_entry(&bep->queue, struct bcm63xx_req, queue); + usb_gadget_unmap_request(&udc->gadget, &breq->req, bep->iudma->is_tx); + + if (breq == cur) { + iudma_reset_channel(udc, bep->iudma); + list_del(&breq->queue); + + if (!list_empty(&bep->queue)) { + struct bcm63xx_req *next; + + next = list_first_entry(&bep->queue, + struct bcm63xx_req, queue); + iudma_write(udc, bep->iudma, next); + } + } else { + list_del(&breq->queue); + } + +out: + spin_unlock_irqrestore(&udc->lock, flags); + + req->status = -ESHUTDOWN; + req->complete(ep, req); + + return rc; +} + +/** + * bcm63xx_udc_set_halt - Enable/disable STALL flag in the hardware. + * @ep: Endpoint to halt. + * @value: Zero to clear halt; nonzero to set halt. + * + * See comments in bcm63xx_update_wedge(). + */ +static int bcm63xx_udc_set_halt(struct usb_ep *ep, int value) +{ + struct bcm63xx_ep *bep = our_ep(ep); + struct bcm63xx_udc *udc = bep->udc; + unsigned long flags; + + spin_lock_irqsave(&udc->lock, flags); + bcm63xx_set_stall(udc, bep, !!value); + bep->halted = value; + spin_unlock_irqrestore(&udc->lock, flags); + + return 0; +} + +/** + * bcm63xx_udc_set_wedge - Stall the endpoint until the next reset. + * @ep: Endpoint to wedge. + * + * See comments in bcm63xx_update_wedge(). + */ +static int bcm63xx_udc_set_wedge(struct usb_ep *ep) +{ + struct bcm63xx_ep *bep = our_ep(ep); + struct bcm63xx_udc *udc = bep->udc; + unsigned long flags; + + spin_lock_irqsave(&udc->lock, flags); + set_bit(bep->ep_num, &udc->wedgemap); + bcm63xx_set_stall(udc, bep, true); + spin_unlock_irqrestore(&udc->lock, flags); + + return 0; +} + +static const struct usb_ep_ops bcm63xx_udc_ep_ops = { + .enable = bcm63xx_ep_enable, + .disable = bcm63xx_ep_disable, + + .alloc_request = bcm63xx_udc_alloc_request, + .free_request = bcm63xx_udc_free_request, + + .queue = bcm63xx_udc_queue, + .dequeue = bcm63xx_udc_dequeue, + + .set_halt = bcm63xx_udc_set_halt, + .set_wedge = bcm63xx_udc_set_wedge, +}; + +/*********************************************************************** + * EP0 handling + ***********************************************************************/ + +/** + * bcm63xx_ep0_setup_callback - Drop spinlock to invoke ->setup callback. + * @udc: Reference to the device controller. + * @ctrl: 8-byte SETUP request. + */ +static int bcm63xx_ep0_setup_callback(struct bcm63xx_udc *udc, + struct usb_ctrlrequest *ctrl) +{ + int rc; + + spin_unlock_irq(&udc->lock); + rc = udc->driver->setup(&udc->gadget, ctrl); + spin_lock_irq(&udc->lock); + return rc; +} + +/** + * bcm63xx_ep0_spoof_set_cfg - Synthesize a SET_CONFIGURATION request. + * @udc: Reference to the device controller. + * + * Many standard requests are handled automatically in the hardware, but + * we still need to pass them to the gadget driver so that it can + * reconfigure the interfaces/endpoints if necessary. + * + * Unfortunately we are not able to send a STALL response if the host + * requests an invalid configuration. If this happens, we'll have to be + * content with printing a warning. + */ +static int bcm63xx_ep0_spoof_set_cfg(struct bcm63xx_udc *udc) +{ + struct usb_ctrlrequest ctrl; + int rc; + + ctrl.bRequestType = USB_DIR_OUT | USB_RECIP_DEVICE; + ctrl.bRequest = USB_REQ_SET_CONFIGURATION; + ctrl.wValue = cpu_to_le16(udc->cfg); + ctrl.wIndex = 0; + ctrl.wLength = 0; + + rc = bcm63xx_ep0_setup_callback(udc, &ctrl); + if (rc < 0) { + dev_warn_ratelimited(udc->dev, + "hardware auto-acked bad SET_CONFIGURATION(%d) request\n", + udc->cfg); + } + return rc; +} + +/** + * bcm63xx_ep0_spoof_set_iface - Synthesize a SET_INTERFACE request. + * @udc: Reference to the device controller. + */ +static int bcm63xx_ep0_spoof_set_iface(struct bcm63xx_udc *udc) +{ + struct usb_ctrlrequest ctrl; + int rc; + + ctrl.bRequestType = USB_DIR_OUT | USB_RECIP_INTERFACE; + ctrl.bRequest = USB_REQ_SET_INTERFACE; + ctrl.wValue = cpu_to_le16(udc->alt_iface); + ctrl.wIndex = cpu_to_le16(udc->iface); + ctrl.wLength = 0; + + rc = bcm63xx_ep0_setup_callback(udc, &ctrl); + if (rc < 0) { + dev_warn_ratelimited(udc->dev, + "hardware auto-acked bad SET_INTERFACE(%d,%d) request\n", + udc->iface, udc->alt_iface); + } + return rc; +} + +/** + * bcm63xx_ep0_map_write - dma_map and iudma_write a single request. + * @udc: Reference to the device controller. + * @ch_idx: IUDMA channel number. + * @req: USB gadget layer representation of the request. + */ +static void bcm63xx_ep0_map_write(struct bcm63xx_udc *udc, int ch_idx, + struct usb_request *req) +{ + struct bcm63xx_req *breq = our_req(req); + struct iudma_ch *iudma = &udc->iudma[ch_idx]; + + BUG_ON(udc->ep0_request); + udc->ep0_request = req; + + req->actual = 0; + breq->offset = 0; + usb_gadget_map_request(&udc->gadget, req, iudma->is_tx); + iudma_write(udc, iudma, breq); +} + +/** + * bcm63xx_ep0_complete - Set completion status and "stage" the callback. + * @udc: Reference to the device controller. + * @req: USB gadget layer representation of the request. + * @status: Status to return to the gadget driver. + */ +static void bcm63xx_ep0_complete(struct bcm63xx_udc *udc, + struct usb_request *req, int status) +{ + req->status = status; + if (status) + req->actual = 0; + if (req->complete) { + spin_unlock_irq(&udc->lock); + req->complete(&udc->bep[0].ep, req); + spin_lock_irq(&udc->lock); + } +} + +/** + * bcm63xx_ep0_nuke_reply - Abort request from the gadget driver due to + * reset/shutdown. + * @udc: Reference to the device controller. + * @is_tx: Nonzero for TX (IN), zero for RX (OUT). + */ +static void bcm63xx_ep0_nuke_reply(struct bcm63xx_udc *udc, int is_tx) +{ + struct usb_request *req = udc->ep0_reply; + + udc->ep0_reply = NULL; + usb_gadget_unmap_request(&udc->gadget, req, is_tx); + if (udc->ep0_request == req) { + udc->ep0_req_completed = 0; + udc->ep0_request = NULL; + } + bcm63xx_ep0_complete(udc, req, -ESHUTDOWN); +} + +/** + * bcm63xx_ep0_read_complete - Close out the pending ep0 request; return + * transfer len. + * @udc: Reference to the device controller. + */ +static int bcm63xx_ep0_read_complete(struct bcm63xx_udc *udc) +{ + struct usb_request *req = udc->ep0_request; + + udc->ep0_req_completed = 0; + udc->ep0_request = NULL; + + return req->actual; +} + +/** + * bcm63xx_ep0_internal_request - Helper function to submit an ep0 request. + * @udc: Reference to the device controller. + * @ch_idx: IUDMA channel number. + * @length: Number of bytes to TX/RX. + * + * Used for simple transfers performed by the ep0 worker. This will always + * use ep0_ctrl_req / ep0_ctrl_buf. + */ +static void bcm63xx_ep0_internal_request(struct bcm63xx_udc *udc, int ch_idx, + int length) +{ + struct usb_request *req = &udc->ep0_ctrl_req.req; + + req->buf = udc->ep0_ctrl_buf; + req->length = length; + req->complete = NULL; + + bcm63xx_ep0_map_write(udc, ch_idx, req); +} + +/** + * bcm63xx_ep0_do_setup - Parse new SETUP packet and decide how to handle it. + * @udc: Reference to the device controller. + * + * EP0_IDLE probably shouldn't ever happen. EP0_REQUEUE means we're ready + * for the next packet. Anything else means the transaction requires multiple + * stages of handling. + */ +static enum bcm63xx_ep0_state bcm63xx_ep0_do_setup(struct bcm63xx_udc *udc) +{ + int rc; + struct usb_ctrlrequest *ctrl = (void *)udc->ep0_ctrl_buf; + + rc = bcm63xx_ep0_read_complete(udc); + + if (rc < 0) { + dev_err(udc->dev, "missing SETUP packet\n"); + return EP0_IDLE; + } + + /* + * Handle 0-byte IN STATUS acknowledgement. The hardware doesn't + * ALWAYS deliver these 100% of the time, so if we happen to see one, + * just throw it away. + */ + if (rc == 0) + return EP0_REQUEUE; + + /* Drop malformed SETUP packets */ + if (rc != sizeof(*ctrl)) { + dev_warn_ratelimited(udc->dev, + "malformed SETUP packet (%d bytes)\n", rc); + return EP0_REQUEUE; + } + + /* Process new SETUP packet arriving on ep0 */ + rc = bcm63xx_ep0_setup_callback(udc, ctrl); + if (rc < 0) { + bcm63xx_set_stall(udc, &udc->bep[0], true); + return EP0_REQUEUE; + } + + if (!ctrl->wLength) + return EP0_REQUEUE; + else if (ctrl->bRequestType & USB_DIR_IN) + return EP0_IN_DATA_PHASE_SETUP; + else + return EP0_OUT_DATA_PHASE_SETUP; +} + +/** + * bcm63xx_ep0_do_idle - Check for outstanding requests if ep0 is idle. + * @udc: Reference to the device controller. + * + * In state EP0_IDLE, the RX descriptor is either pending, or has been + * filled with a SETUP packet from the host. This function handles new + * SETUP packets, control IRQ events (which can generate fake SETUP packets), + * and reset/shutdown events. + * + * Returns 0 if work was done; -EAGAIN if nothing to do. + */ +static int bcm63xx_ep0_do_idle(struct bcm63xx_udc *udc) +{ + if (udc->ep0_req_reset) { + udc->ep0_req_reset = 0; + } else if (udc->ep0_req_set_cfg) { + udc->ep0_req_set_cfg = 0; + if (bcm63xx_ep0_spoof_set_cfg(udc) >= 0) + udc->ep0state = EP0_IN_FAKE_STATUS_PHASE; + } else if (udc->ep0_req_set_iface) { + udc->ep0_req_set_iface = 0; + if (bcm63xx_ep0_spoof_set_iface(udc) >= 0) + udc->ep0state = EP0_IN_FAKE_STATUS_PHASE; + } else if (udc->ep0_req_completed) { + udc->ep0state = bcm63xx_ep0_do_setup(udc); + return udc->ep0state == EP0_IDLE ? -EAGAIN : 0; + } else if (udc->ep0_req_shutdown) { + udc->ep0_req_shutdown = 0; + udc->ep0_req_completed = 0; + udc->ep0_request = NULL; + iudma_reset_channel(udc, &udc->iudma[IUDMA_EP0_RXCHAN]); + usb_gadget_unmap_request(&udc->gadget, + &udc->ep0_ctrl_req.req, 0); + + /* bcm63xx_udc_pullup() is waiting for this */ + mb(); + udc->ep0state = EP0_SHUTDOWN; + } else if (udc->ep0_reply) { + /* + * This could happen if a USB RESET shows up during an ep0 + * transaction (especially if a laggy driver like gadgetfs + * is in use). + */ + dev_warn(udc->dev, "nuking unexpected reply\n"); + bcm63xx_ep0_nuke_reply(udc, 0); + } else { + return -EAGAIN; + } + + return 0; +} + +/** + * bcm63xx_ep0_one_round - Handle the current ep0 state. + * @udc: Reference to the device controller. + * + * Returns 0 if work was done; -EAGAIN if nothing to do. + */ +static int bcm63xx_ep0_one_round(struct bcm63xx_udc *udc) +{ + enum bcm63xx_ep0_state ep0state = udc->ep0state; + bool shutdown = udc->ep0_req_reset || udc->ep0_req_shutdown; + + switch (udc->ep0state) { + case EP0_REQUEUE: + /* set up descriptor to receive SETUP packet */ + bcm63xx_ep0_internal_request(udc, IUDMA_EP0_RXCHAN, + BCM63XX_MAX_CTRL_PKT); + ep0state = EP0_IDLE; + break; + case EP0_IDLE: + return bcm63xx_ep0_do_idle(udc); + case EP0_IN_DATA_PHASE_SETUP: + /* + * Normal case: TX request is in ep0_reply (queued by the + * callback), or will be queued shortly. When it's here, + * send it to the HW and go to EP0_IN_DATA_PHASE_COMPLETE. + * + * Shutdown case: Stop waiting for the reply. Just + * REQUEUE->IDLE. The gadget driver is NOT expected to + * queue anything else now. + */ + if (udc->ep0_reply) { + bcm63xx_ep0_map_write(udc, IUDMA_EP0_TXCHAN, + udc->ep0_reply); + ep0state = EP0_IN_DATA_PHASE_COMPLETE; + } else if (shutdown) { + ep0state = EP0_REQUEUE; + } + break; + case EP0_IN_DATA_PHASE_COMPLETE: { + /* + * Normal case: TX packet (ep0_reply) is in flight; wait for + * it to finish, then go back to REQUEUE->IDLE. + * + * Shutdown case: Reset the TX channel, send -ESHUTDOWN + * completion to the gadget driver, then REQUEUE->IDLE. + */ + if (udc->ep0_req_completed) { + udc->ep0_reply = NULL; + bcm63xx_ep0_read_complete(udc); + /* + * the "ack" sometimes gets eaten (see + * bcm63xx_ep0_do_idle) + */ + ep0state = EP0_REQUEUE; + } else if (shutdown) { + iudma_reset_channel(udc, &udc->iudma[IUDMA_EP0_TXCHAN]); + bcm63xx_ep0_nuke_reply(udc, 1); + ep0state = EP0_REQUEUE; + } + break; + } + case EP0_OUT_DATA_PHASE_SETUP: + /* Similar behavior to EP0_IN_DATA_PHASE_SETUP */ + if (udc->ep0_reply) { + bcm63xx_ep0_map_write(udc, IUDMA_EP0_RXCHAN, + udc->ep0_reply); + ep0state = EP0_OUT_DATA_PHASE_COMPLETE; + } else if (shutdown) { + ep0state = EP0_REQUEUE; + } + break; + case EP0_OUT_DATA_PHASE_COMPLETE: { + /* Similar behavior to EP0_IN_DATA_PHASE_COMPLETE */ + if (udc->ep0_req_completed) { + udc->ep0_reply = NULL; + bcm63xx_ep0_read_complete(udc); + + /* send 0-byte ack to host */ + bcm63xx_ep0_internal_request(udc, IUDMA_EP0_TXCHAN, 0); + ep0state = EP0_OUT_STATUS_PHASE; + } else if (shutdown) { + iudma_reset_channel(udc, &udc->iudma[IUDMA_EP0_RXCHAN]); + bcm63xx_ep0_nuke_reply(udc, 0); + ep0state = EP0_REQUEUE; + } + break; + } + case EP0_OUT_STATUS_PHASE: + /* + * Normal case: 0-byte OUT ack packet is in flight; wait + * for it to finish, then go back to REQUEUE->IDLE. + * + * Shutdown case: just cancel the transmission. Don't bother + * calling the completion, because it originated from this + * function anyway. Then go back to REQUEUE->IDLE. + */ + if (udc->ep0_req_completed) { + bcm63xx_ep0_read_complete(udc); + ep0state = EP0_REQUEUE; + } else if (shutdown) { + iudma_reset_channel(udc, &udc->iudma[IUDMA_EP0_TXCHAN]); + udc->ep0_request = NULL; + ep0state = EP0_REQUEUE; + } + break; + case EP0_IN_FAKE_STATUS_PHASE: { + /* + * Normal case: we spoofed a SETUP packet and are now + * waiting for the gadget driver to send a 0-byte reply. + * This doesn't actually get sent to the HW because the + * HW has already sent its own reply. Once we get the + * response, return to IDLE. + * + * Shutdown case: return to IDLE immediately. + * + * Note that the ep0 RX descriptor has remained queued + * (and possibly unfilled) during this entire transaction. + * The HW datapath (IUDMA) never even sees SET_CONFIGURATION + * or SET_INTERFACE transactions. + */ + struct usb_request *r = udc->ep0_reply; + + if (!r) { + if (shutdown) + ep0state = EP0_IDLE; + break; + } + + bcm63xx_ep0_complete(udc, r, 0); + udc->ep0_reply = NULL; + ep0state = EP0_IDLE; + break; + } + case EP0_SHUTDOWN: + break; + } + + if (udc->ep0state == ep0state) + return -EAGAIN; + + udc->ep0state = ep0state; + return 0; +} + +/** + * bcm63xx_ep0_process - ep0 worker thread / state machine. + * @w: Workqueue struct. + * + * bcm63xx_ep0_process is triggered any time an event occurs on ep0. It + * is used to synchronize ep0 events and ensure that both HW and SW events + * occur in a well-defined order. When the ep0 IUDMA queues are idle, it may + * synthesize SET_CONFIGURATION / SET_INTERFACE requests that were consumed + * by the USBD hardware. + * + * The worker function will continue iterating around the state machine + * until there is nothing left to do. Usually "nothing left to do" means + * that we're waiting for a new event from the hardware. + */ +static void bcm63xx_ep0_process(struct work_struct *w) +{ + struct bcm63xx_udc *udc = container_of(w, struct bcm63xx_udc, ep0_wq); + spin_lock_irq(&udc->lock); + while (bcm63xx_ep0_one_round(udc) == 0) + ; + spin_unlock_irq(&udc->lock); +} + +/*********************************************************************** + * Standard UDC gadget operations + ***********************************************************************/ + +/** + * bcm63xx_udc_get_frame - Read current SOF frame number from the HW. + * @gadget: USB slave device. + */ +static int bcm63xx_udc_get_frame(struct usb_gadget *gadget) +{ + struct bcm63xx_udc *udc = gadget_to_udc(gadget); + + return (usbd_readl(udc, USBD_STATUS_REG) & + USBD_STATUS_SOF_MASK) >> USBD_STATUS_SOF_SHIFT; +} + +/** + * bcm63xx_udc_pullup - Enable/disable pullup on D+ line. + * @gadget: USB slave device. + * @is_on: 0 to disable pullup, 1 to enable. + * + * See notes in bcm63xx_select_pullup(). + */ +static int bcm63xx_udc_pullup(struct usb_gadget *gadget, int is_on) +{ + struct bcm63xx_udc *udc = gadget_to_udc(gadget); + unsigned long flags; + int i, rc = -EINVAL; + + spin_lock_irqsave(&udc->lock, flags); + if (is_on && udc->ep0state == EP0_SHUTDOWN) { + udc->gadget.speed = USB_SPEED_UNKNOWN; + udc->ep0state = EP0_REQUEUE; + bcm63xx_fifo_setup(udc); + bcm63xx_fifo_reset(udc); + bcm63xx_ep_setup(udc); + + bitmap_zero(&udc->wedgemap, BCM63XX_NUM_EP); + for (i = 0; i < BCM63XX_NUM_EP; i++) + bcm63xx_set_stall(udc, &udc->bep[i], false); + + bcm63xx_set_ctrl_irqs(udc, true); + bcm63xx_select_pullup(gadget_to_udc(gadget), true); + rc = 0; + } else if (!is_on && udc->ep0state != EP0_SHUTDOWN) { + bcm63xx_select_pullup(gadget_to_udc(gadget), false); + + udc->ep0_req_shutdown = 1; + spin_unlock_irqrestore(&udc->lock, flags); + + while (1) { + schedule_work(&udc->ep0_wq); + if (udc->ep0state == EP0_SHUTDOWN) + break; + msleep(50); + } + bcm63xx_set_ctrl_irqs(udc, false); + cancel_work_sync(&udc->ep0_wq); + return 0; + } + + spin_unlock_irqrestore(&udc->lock, flags); + return rc; +} + +/** + * bcm63xx_udc_start - Start the controller. + * @gadget: USB slave device. + * @driver: Driver for USB slave devices. + */ +static int bcm63xx_udc_start(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) +{ + struct bcm63xx_udc *udc = gadget_to_udc(gadget); + unsigned long flags; + + if (!driver || driver->max_speed < USB_SPEED_HIGH || + !driver->setup) + return -EINVAL; + if (!udc) + return -ENODEV; + if (udc->driver) + return -EBUSY; + + spin_lock_irqsave(&udc->lock, flags); + + set_clocks(udc, true); + bcm63xx_fifo_setup(udc); + bcm63xx_ep_init(udc); + bcm63xx_ep_setup(udc); + bcm63xx_fifo_reset(udc); + bcm63xx_select_phy_mode(udc, true); + + udc->driver = driver; + driver->driver.bus = NULL; + udc->gadget.dev.driver = &driver->driver; + udc->gadget.dev.of_node = udc->dev->of_node; + + spin_unlock_irqrestore(&udc->lock, flags); + + return 0; +} + +/** + * bcm63xx_udc_stop - Shut down the controller. + * @gadget: USB slave device. + * @driver: Driver for USB slave devices. + */ +static int bcm63xx_udc_stop(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) +{ + struct bcm63xx_udc *udc = gadget_to_udc(gadget); + unsigned long flags; + + spin_lock_irqsave(&udc->lock, flags); + + udc->driver = NULL; + udc->gadget.dev.driver = NULL; + + /* + * If we switch the PHY too abruptly after dropping D+, the host + * will often complain: + * + * hub 1-0:1.0: port 1 disabled by hub (EMI?), re-enabling... + */ + msleep(100); + + bcm63xx_select_phy_mode(udc, false); + set_clocks(udc, false); + + spin_unlock_irqrestore(&udc->lock, flags); + + return 0; +} + +static const struct usb_gadget_ops bcm63xx_udc_ops = { + .get_frame = bcm63xx_udc_get_frame, + .pullup = bcm63xx_udc_pullup, + .udc_start = bcm63xx_udc_start, + .udc_stop = bcm63xx_udc_stop, +}; + +/*********************************************************************** + * IRQ handling + ***********************************************************************/ + +/** + * bcm63xx_update_cfg_iface - Read current configuration/interface settings. + * @udc: Reference to the device controller. + * + * This controller intercepts SET_CONFIGURATION and SET_INTERFACE messages. + * The driver never sees the raw control packets coming in on the ep0 + * IUDMA channel, but at least we get an interrupt event to tell us that + * new values are waiting in the USBD_STATUS register. + */ +static void bcm63xx_update_cfg_iface(struct bcm63xx_udc *udc) +{ + u32 reg = usbd_readl(udc, USBD_STATUS_REG); + + udc->cfg = (reg & USBD_STATUS_CFG_MASK) >> USBD_STATUS_CFG_SHIFT; + udc->iface = (reg & USBD_STATUS_INTF_MASK) >> USBD_STATUS_INTF_SHIFT; + udc->alt_iface = (reg & USBD_STATUS_ALTINTF_MASK) >> + USBD_STATUS_ALTINTF_SHIFT; + bcm63xx_ep_setup(udc); +} + +/** + * bcm63xx_update_link_speed - Check to see if the link speed has changed. + * @udc: Reference to the device controller. + * + * The link speed update coincides with a SETUP IRQ. Returns 1 if the + * speed has changed, so that the caller can update the endpoint settings. + */ +static int bcm63xx_update_link_speed(struct bcm63xx_udc *udc) +{ + u32 reg = usbd_readl(udc, USBD_STATUS_REG); + enum usb_device_speed oldspeed = udc->gadget.speed; + + switch ((reg & USBD_STATUS_SPD_MASK) >> USBD_STATUS_SPD_SHIFT) { + case BCM63XX_SPD_HIGH: + udc->gadget.speed = USB_SPEED_HIGH; + break; + case BCM63XX_SPD_FULL: + udc->gadget.speed = USB_SPEED_FULL; + break; + default: + /* this should never happen */ + udc->gadget.speed = USB_SPEED_UNKNOWN; + dev_err(udc->dev, + "received SETUP packet with invalid link speed\n"); + return 0; + } + + if (udc->gadget.speed != oldspeed) { + dev_info(udc->dev, "link up, %s-speed mode\n", + udc->gadget.speed == USB_SPEED_HIGH ? "high" : "full"); + return 1; + } else { + return 0; + } +} + +/** + * bcm63xx_update_wedge - Iterate through wedged endpoints. + * @udc: Reference to the device controller. + * @new_status: true to "refresh" wedge status; false to clear it. + * + * On a SETUP interrupt, we need to manually "refresh" the wedge status + * because the controller hardware is designed to automatically clear + * stalls in response to a CLEAR_FEATURE request from the host. + * + * On a RESET interrupt, we do want to restore all wedged endpoints. + */ +static void bcm63xx_update_wedge(struct bcm63xx_udc *udc, bool new_status) +{ + int i; + + for_each_set_bit(i, &udc->wedgemap, BCM63XX_NUM_EP) { + bcm63xx_set_stall(udc, &udc->bep[i], new_status); + if (!new_status) + clear_bit(i, &udc->wedgemap); + } +} + +/** + * bcm63xx_udc_ctrl_isr - ISR for control path events (USBD). + * @irq: IRQ number (unused). + * @dev_id: Reference to the device controller. + * + * This is where we handle link (VBUS) down, USB reset, speed changes, + * SET_CONFIGURATION, and SET_INTERFACE events. + */ +static irqreturn_t bcm63xx_udc_ctrl_isr(int irq, void *dev_id) +{ + struct bcm63xx_udc *udc = dev_id; + u32 stat; + bool disconnected = false; + + stat = usbd_readl(udc, USBD_EVENT_IRQ_STATUS_REG) & + usbd_readl(udc, USBD_EVENT_IRQ_MASK_REG); + + usbd_writel(udc, stat, USBD_EVENT_IRQ_STATUS_REG); + + spin_lock(&udc->lock); + if (stat & BIT(USBD_EVENT_IRQ_USB_LINK)) { + /* VBUS toggled */ + + if (!(usbd_readl(udc, USBD_EVENTS_REG) & + USBD_EVENTS_USB_LINK_MASK) && + udc->gadget.speed != USB_SPEED_UNKNOWN) + dev_info(udc->dev, "link down\n"); + + udc->gadget.speed = USB_SPEED_UNKNOWN; + disconnected = true; + } + if (stat & BIT(USBD_EVENT_IRQ_USB_RESET)) { + bcm63xx_fifo_setup(udc); + bcm63xx_fifo_reset(udc); + bcm63xx_ep_setup(udc); + + bcm63xx_update_wedge(udc, false); + + udc->ep0_req_reset = 1; + schedule_work(&udc->ep0_wq); + disconnected = true; + } + if (stat & BIT(USBD_EVENT_IRQ_SETUP)) { + if (bcm63xx_update_link_speed(udc)) { + bcm63xx_fifo_setup(udc); + bcm63xx_ep_setup(udc); + } + bcm63xx_update_wedge(udc, true); + } + if (stat & BIT(USBD_EVENT_IRQ_SETCFG)) { + bcm63xx_update_cfg_iface(udc); + udc->ep0_req_set_cfg = 1; + schedule_work(&udc->ep0_wq); + } + if (stat & BIT(USBD_EVENT_IRQ_SETINTF)) { + bcm63xx_update_cfg_iface(udc); + udc->ep0_req_set_iface = 1; + schedule_work(&udc->ep0_wq); + } + spin_unlock(&udc->lock); + + if (disconnected && udc->driver) + udc->driver->disconnect(&udc->gadget); + + return IRQ_HANDLED; +} + +/** + * bcm63xx_udc_data_isr - ISR for data path events (IUDMA). + * @irq: IRQ number (unused). + * @dev_id: Reference to the IUDMA channel that generated the interrupt. + * + * For the two ep0 channels, we have special handling that triggers the + * ep0 worker thread. For normal bulk/intr channels, either queue up + * the next buffer descriptor for the transaction (incomplete transaction), + * or invoke the completion callback (complete transactions). + */ +static irqreturn_t bcm63xx_udc_data_isr(int irq, void *dev_id) +{ + struct iudma_ch *iudma = dev_id; + struct bcm63xx_udc *udc = iudma->udc; + struct bcm63xx_ep *bep; + struct usb_request *req = NULL; + struct bcm63xx_req *breq = NULL; + int rc; + bool is_done = false; + + spin_lock(&udc->lock); + + usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, + ENETDMAC_IR_REG(iudma->ch_idx)); + bep = iudma->bep; + rc = iudma_read(udc, iudma); + + /* special handling for EP0 RX (0) and TX (1) */ + if (iudma->ch_idx == IUDMA_EP0_RXCHAN || + iudma->ch_idx == IUDMA_EP0_TXCHAN) { + req = udc->ep0_request; + breq = our_req(req); + + /* a single request could require multiple submissions */ + if (rc >= 0) { + req->actual += rc; + + if (req->actual >= req->length || breq->bd_bytes > rc) { + udc->ep0_req_completed = 1; + is_done = true; + schedule_work(&udc->ep0_wq); + + /* "actual" on a ZLP is 1 byte */ + req->actual = min(req->actual, req->length); + } else { + /* queue up the next BD (same request) */ + iudma_write(udc, iudma, breq); + } + } + } else if (!list_empty(&bep->queue)) { + breq = list_first_entry(&bep->queue, struct bcm63xx_req, queue); + req = &breq->req; + + if (rc >= 0) { + req->actual += rc; + + if (req->actual >= req->length || breq->bd_bytes > rc) { + is_done = true; + list_del(&breq->queue); + + req->actual = min(req->actual, req->length); + + if (!list_empty(&bep->queue)) { + struct bcm63xx_req *next; + + next = list_first_entry(&bep->queue, + struct bcm63xx_req, queue); + iudma_write(udc, iudma, next); + } + } else { + iudma_write(udc, iudma, breq); + } + } + } + spin_unlock(&udc->lock); + + if (is_done) { + usb_gadget_unmap_request(&udc->gadget, req, iudma->is_tx); + if (req->complete) + req->complete(&bep->ep, req); + } + + return IRQ_HANDLED; +} + +/*********************************************************************** + * Debug filesystem + ***********************************************************************/ + +/* + * bcm63xx_usbd_dbg_show - Show USBD controller state. + * @s: seq_file to which the information will be written. + * @p: Unused. + * + * This file nominally shows up as /sys/kernel/debug/bcm63xx_udc/usbd + */ +static int bcm63xx_usbd_dbg_show(struct seq_file *s, void *p) +{ + struct bcm63xx_udc *udc = s->private; + + if (!udc->driver) + return -ENODEV; + + seq_printf(s, "ep0 state: %s\n", + bcm63xx_ep0_state_names[udc->ep0state]); + seq_printf(s, " pending requests: %s%s%s%s%s%s%s\n", + udc->ep0_req_reset ? "reset " : "", + udc->ep0_req_set_cfg ? "set_cfg " : "", + udc->ep0_req_set_iface ? "set_iface " : "", + udc->ep0_req_shutdown ? "shutdown " : "", + udc->ep0_request ? "pending " : "", + udc->ep0_req_completed ? "completed " : "", + udc->ep0_reply ? "reply " : ""); + seq_printf(s, "cfg: %d; iface: %d; alt_iface: %d\n", + udc->cfg, udc->iface, udc->alt_iface); + seq_printf(s, "regs:\n"); + seq_printf(s, " control: %08x; straps: %08x; status: %08x\n", + usbd_readl(udc, USBD_CONTROL_REG), + usbd_readl(udc, USBD_STRAPS_REG), + usbd_readl(udc, USBD_STATUS_REG)); + seq_printf(s, " events: %08x; stall: %08x\n", + usbd_readl(udc, USBD_EVENTS_REG), + usbd_readl(udc, USBD_STALL_REG)); + + return 0; +} + +/* + * bcm63xx_iudma_dbg_show - Show IUDMA status and descriptors. + * @s: seq_file to which the information will be written. + * @p: Unused. + * + * This file nominally shows up as /sys/kernel/debug/bcm63xx_udc/iudma + */ +static int bcm63xx_iudma_dbg_show(struct seq_file *s, void *p) +{ + struct bcm63xx_udc *udc = s->private; + int ch_idx, i; + u32 sram2, sram3; + + if (!udc->driver) + return -ENODEV; + + for (ch_idx = 0; ch_idx < BCM63XX_NUM_IUDMA; ch_idx++) { + struct iudma_ch *iudma = &udc->iudma[ch_idx]; + struct list_head *pos; + + seq_printf(s, "IUDMA channel %d -- ", ch_idx); + switch (iudma_defaults[ch_idx].ep_type) { + case BCMEP_CTRL: + seq_printf(s, "control"); + break; + case BCMEP_BULK: + seq_printf(s, "bulk"); + break; + case BCMEP_INTR: + seq_printf(s, "interrupt"); + break; + } + seq_printf(s, ch_idx & 0x01 ? " tx" : " rx"); + seq_printf(s, " [ep%d]:\n", + max_t(int, iudma_defaults[ch_idx].ep_num, 0)); + seq_printf(s, " cfg: %08x; irqstat: %08x; irqmask: %08x; maxburst: %08x\n", + usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG(ch_idx)), + usb_dmac_readl(udc, ENETDMAC_IR_REG(ch_idx)), + usb_dmac_readl(udc, ENETDMAC_IRMASK_REG(ch_idx)), + usb_dmac_readl(udc, ENETDMAC_MAXBURST_REG(ch_idx))); + + sram2 = usb_dmas_readl(udc, ENETDMAS_SRAM2_REG(ch_idx)); + sram3 = usb_dmas_readl(udc, ENETDMAS_SRAM3_REG(ch_idx)); + seq_printf(s, " base: %08x; index: %04x_%04x; desc: %04x_%04x %08x\n", + usb_dmas_readl(udc, ENETDMAS_RSTART_REG(ch_idx)), + sram2 >> 16, sram2 & 0xffff, + sram3 >> 16, sram3 & 0xffff, + usb_dmas_readl(udc, ENETDMAS_SRAM4_REG(ch_idx))); + seq_printf(s, " desc: %d/%d used", iudma->n_bds_used, + iudma->n_bds); + + if (iudma->bep) { + i = 0; + list_for_each(pos, &iudma->bep->queue) + i++; + seq_printf(s, "; %d queued\n", i); + } else { + seq_printf(s, "\n"); + } + + for (i = 0; i < iudma->n_bds; i++) { + struct bcm_enet_desc *d = &iudma->bd_ring[i]; + + seq_printf(s, " %03x (%02x): len_stat: %04x_%04x; pa %08x", + i * sizeof(*d), i, + d->len_stat >> 16, d->len_stat & 0xffff, + d->address); + if (d == iudma->read_bd) + seq_printf(s, " <write_bd) + seq_printf(s, " <i_private); +} + +static int bcm63xx_iudma_dbg_open(struct inode *inode, struct file *file) +{ + return single_open(file, bcm63xx_iudma_dbg_show, inode->i_private); +} + +static const struct file_operations usbd_dbg_fops = { + .owner = THIS_MODULE, + .open = bcm63xx_usbd_dbg_open, + .llseek = seq_lseek, + .read = seq_read, + .release = single_release, +}; + +static const struct file_operations iudma_dbg_fops = { + .owner = THIS_MODULE, + .open = bcm63xx_iudma_dbg_open, + .llseek = seq_lseek, + .read = seq_read, + .release = single_release, +}; + + +/** + * bcm63xx_udc_init_debugfs - Create debugfs entries. + * @udc: Reference to the device controller. + */ +static void bcm63xx_udc_init_debugfs(struct bcm63xx_udc *udc) +{ + struct dentry *root, *usbd, *iudma; + + if (!IS_ENABLED(CONFIG_USB_GADGET_DEBUG_FS)) + return; + + root = debugfs_create_dir(udc->gadget.name, NULL); + if (IS_ERR(root) || !root) + goto err_root; + + usbd = debugfs_create_file("usbd", 0400, root, udc, + &usbd_dbg_fops); + if (!usbd) + goto err_usbd; + iudma = debugfs_create_file("iudma", 0400, root, udc, + &iudma_dbg_fops); + if (!iudma) + goto err_iudma; + + udc->debugfs_root = root; + udc->debugfs_usbd = usbd; + udc->debugfs_iudma = iudma; + return; +err_iudma: + debugfs_remove(usbd); +err_usbd: + debugfs_remove(root); +err_root: + dev_err(udc->dev, "debugfs is not available\n"); +} + +/** + * bcm63xx_udc_cleanup_debugfs - Remove debugfs entries. + * @udc: Reference to the device controller. + * + * debugfs_remove() is safe to call with a NULL argument. + */ +static void bcm63xx_udc_cleanup_debugfs(struct bcm63xx_udc *udc) +{ + debugfs_remove(udc->debugfs_iudma); + debugfs_remove(udc->debugfs_usbd); + debugfs_remove(udc->debugfs_root); + udc->debugfs_iudma = NULL; + udc->debugfs_usbd = NULL; + udc->debugfs_root = NULL; +} + +/*********************************************************************** + * Driver init/exit + ***********************************************************************/ + +/** + * bcm63xx_udc_gadget_release - Called from device_release(). + * @dev: Unused. + * + * We get a warning if this function doesn't exist, but it's empty because + * we don't have to free any of the memory allocated with the devm_* APIs. + */ +static void bcm63xx_udc_gadget_release(struct device *dev) +{ +} + +/** + * bcm63xx_udc_probe - Initialize a new instance of the UDC. + * @pdev: Platform device struct from the bcm63xx BSP code. + * + * Note that platform data is required, because pd.port_no varies from chip + * to chip and is used to switch the correct USB port to device mode. + */ +static int __devinit bcm63xx_udc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct bcm63xx_usbd_platform_data *pd = dev->platform_data; + struct bcm63xx_udc *udc; + struct resource *res; + int rc = -ENOMEM, i, irq; + + udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL); + if (!udc) { + dev_err(dev, "cannot allocate memory\n"); + return -ENOMEM; + } + + platform_set_drvdata(pdev, udc); + udc->dev = dev; + udc->pd = pd; + + if (!pd) { + dev_err(dev, "missing platform data\n"); + return -EINVAL; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "error finding USBD resource\n"); + return -ENXIO; + } + udc->usbd_regs = devm_request_and_ioremap(dev, res); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(dev, "error finding IUDMA resource\n"); + return -ENXIO; + } + udc->iudma_regs = devm_request_and_ioremap(dev, res); + + if (!udc->usbd_regs || !udc->iudma_regs) { + dev_err(dev, "error requesting resources\n"); + return -ENXIO; + } + + spin_lock_init(&udc->lock); + INIT_WORK(&udc->ep0_wq, bcm63xx_ep0_process); + dev_set_name(&udc->gadget.dev, "gadget"); + + udc->gadget.ops = &bcm63xx_udc_ops; + udc->gadget.name = dev_name(dev); + udc->gadget.dev.parent = dev; + udc->gadget.dev.release = bcm63xx_udc_gadget_release; + udc->gadget.dev.dma_mask = dev->dma_mask; + + if (!pd->use_fullspeed && !use_fullspeed) + udc->gadget.max_speed = USB_SPEED_HIGH; + else + udc->gadget.max_speed = USB_SPEED_FULL; + + /* request clocks, allocate buffers, and clear any pending IRQs */ + rc = bcm63xx_init_udc_hw(udc); + if (rc) + return rc; + + rc = -ENXIO; + + /* IRQ resource #0: control interrupt (VBUS, speed, etc.) */ + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(dev, "missing IRQ resource #0\n"); + goto out_uninit; + } + if (devm_request_irq(dev, irq, &bcm63xx_udc_ctrl_isr, 0, + dev_name(dev), udc) < 0) { + dev_err(dev, "error requesting IRQ #%d\n", irq); + goto out_uninit; + } + + /* IRQ resources #1-6: data interrupts for IUDMA channels 0-5 */ + for (i = 0; i < BCM63XX_NUM_IUDMA; i++) { + irq = platform_get_irq(pdev, i + 1); + if (irq < 0) { + dev_err(dev, "missing IRQ resource #%d\n", i + 1); + goto out_uninit; + } + if (devm_request_irq(dev, irq, &bcm63xx_udc_data_isr, 0, + dev_name(dev), &udc->iudma[i]) < 0) { + dev_err(dev, "error requesting IRQ #%d\n", irq); + goto out_uninit; + } + } + + rc = device_register(&udc->gadget.dev); + if (rc) + goto out_uninit; + + bcm63xx_udc_init_debugfs(udc); + rc = usb_add_gadget_udc(dev, &udc->gadget); + if (!rc) + return 0; + + bcm63xx_udc_cleanup_debugfs(udc); + device_unregister(&udc->gadget.dev); +out_uninit: + bcm63xx_uninit_udc_hw(udc); + return rc; +} + +/** + * bcm63xx_udc_remove - Remove the device from the system. + * @pdev: Platform device struct from the bcm63xx BSP code. + */ +static int __devexit bcm63xx_udc_remove(struct platform_device *pdev) +{ + struct bcm63xx_udc *udc = platform_get_drvdata(pdev); + + bcm63xx_udc_cleanup_debugfs(udc); + usb_del_gadget_udc(&udc->gadget); + device_unregister(&udc->gadget.dev); + BUG_ON(udc->driver); + + platform_set_drvdata(pdev, NULL); + bcm63xx_uninit_udc_hw(udc); + + return 0; +} + +static struct platform_driver bcm63xx_udc_driver = { + .probe = bcm63xx_udc_probe, + .remove = __devexit_p(bcm63xx_udc_remove), + .driver = { + .name = DRV_MODULE_NAME, + .owner = THIS_MODULE, + }, +}; +module_platform_driver(bcm63xx_udc_driver); + +MODULE_DESCRIPTION("BCM63xx USB Peripheral Controller"); +MODULE_AUTHOR("Kevin Cernekee "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_MODULE_NAME); diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index b8b3a3411218..0ccca58e7a8f 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -28,6 +28,7 @@ #define gadget_is_amd5536udc(g) (!strcmp("amd5536udc", (g)->name)) #define gadget_is_at91(g) (!strcmp("at91_udc", (g)->name)) #define gadget_is_atmel_usba(g) (!strcmp("atmel_usba_udc", (g)->name)) +#define gadget_is_bcm63xx(g) (!strcmp("bcm63xx_udc", (g)->name)) #define gadget_is_ci13xxx_msm(g) (!strcmp("ci13xxx_msm", (g)->name)) #define gadget_is_ci13xxx_pci(g) (!strcmp("ci13xxx_pci", (g)->name)) #define gadget_is_dummy(g) (!strcmp("dummy_udc", (g)->name)) @@ -121,6 +122,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x32; else if (gadget_is_lpc32xx(gadget)) return 0x33; + else if (gadget_is_bcm63xx(gadget)) + return 0x34; return -ENOENT; } -- cgit v1.2.3-59-g8ed1b From fac3a43e0ab20dbf5e845c6221ead0d073984f41 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:01 +0200 Subject: usb: gadget: move bind callback into driver struct usb_composite_driver It was moved to be an argument in 07a18bd716ed5 ("usb gadget: don't save bind callback in struct usb_composite_driver"). The reason was to avoid the section missmatch. The warning was shown because ->bind is marked as __init becuase it is a one time init. The warning can be also suppresed by whitelisting the variable i.e. rename it to lets say _probe. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 10 ++++++---- include/linux/usb/composite.h | 13 +++++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 91411a6d741b..402e5bd8b3e5 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -32,7 +32,6 @@ #define USB_BUFSIZ 1024 static struct usb_composite_driver *composite; -static int (*composite_gadget_bind)(struct usb_composite_dev *cdev); /* Some systems will need runtime overrides for the product identifiers * published in the device descriptor, either numbers or strings or both. @@ -1468,7 +1467,7 @@ static int composite_bind(struct usb_gadget *gadget) * serial number), register function drivers, potentially update * power state and consumption, etc */ - status = composite_gadget_bind(cdev); + status = composite->bind(cdev); if (status < 0) goto fail; @@ -1621,7 +1620,9 @@ static struct usb_gadget_driver composite_driver = { int usb_composite_probe(struct usb_composite_driver *driver, int (*bind)(struct usb_composite_dev *cdev)) { - if (!driver || !driver->dev || !bind || composite) + if (!driver || !driver->dev || composite) + return -EINVAL; + if (!bind && !driver->bind) return -EINVAL; if (!driver->name) @@ -1632,7 +1633,8 @@ int usb_composite_probe(struct usb_composite_driver *driver, composite_driver.driver.name = driver->name; composite_driver.max_speed = driver->max_speed; composite = driver; - composite_gadget_bind = bind; + if (!driver->bind) + driver->bind = bind; return usb_gadget_probe_driver(&composite_driver, composite_bind); } diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 9d8c3b634493..3153f73ae083 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -257,12 +257,16 @@ void usb_remove_config(struct usb_composite_dev *, * not set. * @dev: Template descriptor for the device, including default device * identifiers. - * @strings: tables of strings, keyed by identifiers assigned during bind() + * @strings: tables of strings, keyed by identifiers assigned during @bind * and language IDs provided in control requests * @max_speed: Highest speed the driver supports. * @needs_serial: set to 1 if the gadget needs userspace to provide * a serial number. If one is not provided, warning will be printed. - * @unbind: Reverses bind; called as a side effect of unregistering + * @bind: (REQUIRED) Used to allocate resources that are shared across the + * whole device, such as string IDs, and add its configurations using + * @usb_add_config(). This may fail by returning a negative errno + * value; it should return zero on successful initialization. + * @unbind: Reverses @bind; called as a side effect of unregistering * this driver. * @disconnect: optional driver disconnect method * @suspend: Notifies when the host stops sending USB traffic, @@ -271,9 +275,9 @@ void usb_remove_config(struct usb_composite_dev *, * before function notifications * * Devices default to reporting self powered operation. Devices which rely - * on bus powered operation should report this in their @bind() method. + * on bus powered operation should report this in their @bind method. * - * Before returning from bind, various fields in the template descriptor + * Before returning from @bind, various fields in the template descriptor * may be overridden. These include the idVendor/idProduct/bcdDevice values * normally to bind the appropriate host side driver, and the three strings * (iManufacturer, iProduct, iSerialNumber) normally used to provide user @@ -291,6 +295,7 @@ struct usb_composite_driver { enum usb_device_speed max_speed; unsigned needs_serial:1; + int (*bind)(struct usb_composite_dev *cdev); int (*unbind)(struct usb_composite_dev *); void (*disconnect)(struct usb_composite_dev *); -- cgit v1.2.3-59-g8ed1b From 1e1a27c3258c769ea175780bb28d0c8fead79ff8 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:02 +0200 Subject: usb: gadget: remove __devexit in f_uac2 avoids the following section missmatch |WARNING: drivers/usb/gadget/g_audio.o(.init.text+0x2e7): Section |mismatch in reference from the function afunc_bind() to the function |.devexit.text:snd_uac2_remove() |The function __init afunc_bind() references |a function __devexit snd_uac2_remove(). |This is often seen when error handling in the init function |uses functionality in the exit path. |The fix is often to remove the __devexit annotation of |snd_uac2_remove() so it may be used outside an exit section. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uac2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index e7cc4de93e33..d3c6cffccb72 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c @@ -463,7 +463,7 @@ snd_fail: return err; } -static int __devexit snd_uac2_remove(struct platform_device *pdev) +static int snd_uac2_remove(struct platform_device *pdev) { struct snd_card *card = platform_get_drvdata(pdev); -- cgit v1.2.3-59-g8ed1b From c2ec75c25112c9e0d9053f55ba8cf0a358d4a354 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:03 +0200 Subject: usb: gadget: push all usb_composite_driver structs into __refdata As it turns out, Sam's comment was better than I initially assumed. This patch pushes as struct usb_composite_driver data structures into __refdata section to avoid a section missmatch report from modpost because the ->bind() can be marked __init. The only downside is that modpost does not check between ->bind() and other member. However, it is temporary. Cc: Sam Ravnborg Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/acm_ms.c | 2 +- drivers/usb/gadget/audio.c | 2 +- drivers/usb/gadget/cdc2.c | 2 +- drivers/usb/gadget/dbgp.c | 2 +- drivers/usb/gadget/ether.c | 2 +- drivers/usb/gadget/file_storage.c | 2 +- drivers/usb/gadget/g_ffs.c | 2 +- drivers/usb/gadget/gmidi.c | 2 +- drivers/usb/gadget/hid.c | 2 +- drivers/usb/gadget/mass_storage.c | 2 +- drivers/usb/gadget/multi.c | 2 +- drivers/usb/gadget/ncm.c | 2 +- drivers/usb/gadget/nokia.c | 2 +- drivers/usb/gadget/printer.c | 2 +- drivers/usb/gadget/serial.c | 2 +- drivers/usb/gadget/tcm_usb_gadget.c | 2 +- drivers/usb/gadget/webcam.c | 2 +- drivers/usb/gadget/zero.c | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 75b8a691fd00..dc5cd51de7d4 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -232,7 +232,7 @@ static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) return 0; } -static struct usb_composite_driver acm_ms_driver = { +static __refdata struct usb_composite_driver acm_ms_driver = { .name = "g_acm_ms", .dev = &device_desc, .max_speed = USB_SPEED_SUPER, diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 98899244860e..e539490e7733 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -198,7 +198,7 @@ static int __exit audio_unbind(struct usb_composite_dev *cdev) return 0; } -static struct usb_composite_driver audio_driver = { +static __refdata struct usb_composite_driver audio_driver = { .name = "g_audio", .dev = &device_desc, .strings = audio_strings, diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 725550f06fab..00b65ac7a2ef 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -232,7 +232,7 @@ static int __exit cdc_unbind(struct usb_composite_dev *cdev) return 0; } -static struct usb_composite_driver cdc_driver = { +static __refdata struct usb_composite_driver cdc_driver = { .name = "g_cdc", .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index 19d7bb0df75a..2d2cff3e454c 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c @@ -402,7 +402,7 @@ fail: return err; } -static struct usb_gadget_driver dbgp_driver = { +static __refdata struct usb_gadget_driver dbgp_driver = { .function = "dbgp", .max_speed = USB_SPEED_HIGH, .unbind = dbgp_unbind, diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index a28f6ffcd0f3..49a7dac06b1d 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -388,7 +388,7 @@ static int __exit eth_unbind(struct usb_composite_dev *cdev) return 0; } -static struct usb_composite_driver eth_driver = { +static __refdata struct usb_composite_driver eth_driver = { .name = "g_ether", .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a896d73f7a93..683234bcdced 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -3603,7 +3603,7 @@ static void fsg_resume(struct usb_gadget *gadget) /*-------------------------------------------------------------------------*/ -static struct usb_gadget_driver fsg_driver = { +static __refdata struct usb_gadget_driver fsg_driver = { .max_speed = USB_SPEED_SUPER, .function = (char *) fsg_string_product, .unbind = fsg_unbind, diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index d3ace9002a6a..d1312c404afa 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -163,7 +163,7 @@ static int gfs_bind(struct usb_composite_dev *cdev); static int gfs_unbind(struct usb_composite_dev *cdev); static int gfs_do_config(struct usb_configuration *c); -static struct usb_composite_driver gfs_driver = { +static __refdata struct usb_composite_driver gfs_driver = { .name = DRIVER_NAME, .dev = &gfs_dev_desc, .strings = gfs_dev_strings, diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 681bd038b1d8..ae46f69b718a 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -184,7 +184,7 @@ static int __init midi_bind(struct usb_composite_dev *cdev) return 0; } -static struct usb_composite_driver midi_driver = { +static __refdata struct usb_composite_driver midi_driver = { .name = (char *) longname, .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 3493adf064f5..34e139e700b4 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -242,7 +242,7 @@ static int __devexit hidg_plat_driver_remove(struct platform_device *pdev) /****************************** Some noise ******************************/ -static struct usb_composite_driver hidg_driver = { +static __refdata struct usb_composite_driver hidg_driver = { .name = "g_hid", .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 1f376eba31f6..5df117e3f78d 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -156,7 +156,7 @@ static int __init msg_bind(struct usb_composite_dev *cdev) /****************************** Some noise ******************************/ -static struct usb_composite_driver msg_driver = { +static __refdata struct usb_composite_driver msg_driver = { .name = "g_mass_storage", .dev = &msg_device_desc, .iProduct = DRIVER_DESC, diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index c37fb33a3d1b..7e5852a28a93 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -338,7 +338,7 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev) /****************************** Some noise ******************************/ -static struct usb_composite_driver multi_driver = { +static __refdata struct usb_composite_driver multi_driver = { .name = "g_multi", .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index 89530034dff1..5079bf659e31 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -215,7 +215,7 @@ static int __exit gncm_unbind(struct usb_composite_dev *cdev) return 0; } -static struct usb_composite_driver ncm_driver = { +static __refdata struct usb_composite_driver ncm_driver = { .name = "g_ncm", .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index c7fb7723c014..936d0afc4527 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -237,7 +237,7 @@ static int __exit nokia_unbind(struct usb_composite_dev *cdev) return 0; } -static struct usb_composite_driver nokia_driver = { +static __refdata struct usb_composite_driver nokia_driver = { .name = "g_nokia", .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index f1f9290a2f47..0aab51766ce6 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -1269,7 +1269,7 @@ static int __init printer_bind(struct usb_composite_dev *cdev) return usb_add_config(cdev, &printer_cfg_driver, printer_bind_config); } -static struct usb_composite_driver printer_driver = { +static __refdata struct usb_composite_driver printer_driver = { .name = shortname, .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 665c07422c26..7b0b6f40ed07 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -238,7 +238,7 @@ fail: return status; } -static struct usb_composite_driver gserial_driver = { +static __refdata struct usb_composite_driver gserial_driver = { .name = "g_serial", .dev = &device_desc, .strings = dev_strings, diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 5444866e13ef..28fef844a06a 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -2436,7 +2436,7 @@ static int usb_target_bind(struct usb_composite_dev *cdev) return 0; } -static struct usb_composite_driver usbg_driver = { +static __refdata struct usb_composite_driver usbg_driver = { .name = "g_target", .dev = &usbg_device_desc, .strings = usbg_strings, diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index 120e134e805e..d946f19482e8 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -390,7 +390,7 @@ error: * Driver */ -static struct usb_composite_driver webcam_driver = { +static __refdata struct usb_composite_driver webcam_driver = { .name = "g_webcam", .dev = &webcam_device_descriptor, .strings = webcam_device_strings, diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 12ad516ada77..5db33cbe755b 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -334,7 +334,7 @@ static int zero_unbind(struct usb_composite_dev *cdev) return 0; } -static struct usb_composite_driver zero_driver = { +static __refdata struct usb_composite_driver zero_driver = { .name = "zero", .dev = &device_desc, .strings = dev_strings, -- cgit v1.2.3-59-g8ed1b From 03e42bd5937c4c24e411690ab165627e93c258b5 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:04 +0200 Subject: usb: gadget: move bind() callback back to struct usb_composite_driver This partly reverts 07a18bd7 ("usb gadget: don't save bind callback in struct usb_composite_driver") and fixes new drivers. The section missmatch problems was solved by whitelisting structs in question via __ref. Cc: devel@driverdev.osuosl.org Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/staging/ccg/ccg.c | 3 ++- drivers/usb/gadget/acm_ms.c | 3 ++- drivers/usb/gadget/audio.c | 3 ++- drivers/usb/gadget/cdc2.c | 3 ++- drivers/usb/gadget/composite.c | 9 ++------- drivers/usb/gadget/ether.c | 3 ++- drivers/usb/gadget/g_ffs.c | 3 ++- drivers/usb/gadget/gmidi.c | 3 ++- drivers/usb/gadget/hid.c | 3 ++- drivers/usb/gadget/mass_storage.c | 3 ++- drivers/usb/gadget/multi.c | 3 ++- drivers/usb/gadget/ncm.c | 3 ++- drivers/usb/gadget/nokia.c | 3 ++- drivers/usb/gadget/printer.c | 3 ++- drivers/usb/gadget/serial.c | 3 ++- drivers/usb/gadget/tcm_usb_gadget.c | 3 ++- drivers/usb/gadget/webcam.c | 3 ++- drivers/usb/gadget/zero.c | 3 ++- include/linux/usb/composite.h | 3 +-- 19 files changed, 37 insertions(+), 26 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/staging/ccg/ccg.c b/drivers/staging/ccg/ccg.c index 6a7aab8d9bf5..eadda5574b2a 100644 --- a/drivers/staging/ccg/ccg.c +++ b/drivers/staging/ccg/ccg.c @@ -1162,6 +1162,7 @@ static int ccg_usb_unbind(struct usb_composite_dev *cdev) static struct usb_composite_driver ccg_usb_driver = { .name = "configurable_usb", .dev = &device_desc, + .bind = ccg_bind, .unbind = ccg_usb_unbind, .needs_serial = true, .iManufacturer = "Linux Foundation", @@ -1275,7 +1276,7 @@ static int __init init(void) composite_driver.setup = ccg_setup; composite_driver.disconnect = ccg_disconnect; - err = usb_composite_probe(&ccg_usb_driver, ccg_bind); + err = usb_composite_probe(&ccg_usb_driver); if (err) { class_destroy(ccg_class); kfree(dev); diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index dc5cd51de7d4..65a2f3cbcde3 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -237,6 +237,7 @@ static __refdata struct usb_composite_driver acm_ms_driver = { .dev = &device_desc, .max_speed = USB_SPEED_SUPER, .strings = dev_strings, + .bind = acm_ms_bind, .unbind = __exit_p(acm_ms_unbind), }; @@ -246,7 +247,7 @@ MODULE_LICENSE("GPL v2"); static int __init init(void) { - return usb_composite_probe(&acm_ms_driver, acm_ms_bind); + return usb_composite_probe(&acm_ms_driver); } module_init(init); diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index e539490e7733..dd339bc5b40c 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -203,12 +203,13 @@ static __refdata struct usb_composite_driver audio_driver = { .dev = &device_desc, .strings = audio_strings, .max_speed = USB_SPEED_HIGH, + .bind = audio_bind, .unbind = __exit_p(audio_unbind), }; static int __init init(void) { - return usb_composite_probe(&audio_driver, audio_bind); + return usb_composite_probe(&audio_driver); } module_init(init); diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 00b65ac7a2ef..b7d984b54ca9 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -237,6 +237,7 @@ static __refdata struct usb_composite_driver cdc_driver = { .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, + .bind = cdc_bind, .unbind = __exit_p(cdc_unbind), }; @@ -246,7 +247,7 @@ MODULE_LICENSE("GPL"); static int __init init(void) { - return usb_composite_probe(&cdc_driver, cdc_bind); + return usb_composite_probe(&cdc_driver); } module_init(init); diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 402e5bd8b3e5..071d15c44116 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1617,12 +1617,9 @@ static struct usb_gadget_driver composite_driver = { * while it was binding. That would usually be done in order to wait for * some userspace participation. */ -int usb_composite_probe(struct usb_composite_driver *driver, - int (*bind)(struct usb_composite_dev *cdev)) +int usb_composite_probe(struct usb_composite_driver *driver) { - if (!driver || !driver->dev || composite) - return -EINVAL; - if (!bind && !driver->bind) + if (!driver || !driver->dev || composite || !driver->bind) return -EINVAL; if (!driver->name) @@ -1633,8 +1630,6 @@ int usb_composite_probe(struct usb_composite_driver *driver, composite_driver.driver.name = driver->name; composite_driver.max_speed = driver->max_speed; composite = driver; - if (!driver->bind) - driver->bind = bind; return usb_gadget_probe_driver(&composite_driver, composite_bind); } diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 49a7dac06b1d..4580ec09cc53 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -393,6 +393,7 @@ static __refdata struct usb_composite_driver eth_driver = { .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_SUPER, + .bind = eth_bind, .unbind = __exit_p(eth_unbind), }; @@ -402,7 +403,7 @@ MODULE_LICENSE("GPL"); static int __init init(void) { - return usb_composite_probe(ð_driver, eth_bind); + return usb_composite_probe(ð_driver); } module_init(init); diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index d1312c404afa..da9809f55cb5 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -168,6 +168,7 @@ static __refdata struct usb_composite_driver gfs_driver = { .dev = &gfs_dev_desc, .strings = gfs_dev_strings, .max_speed = USB_SPEED_HIGH, + .bind = gfs_bind, .unbind = gfs_unbind, .iProduct = DRIVER_DESC, }; @@ -268,7 +269,7 @@ static int functionfs_ready_callback(struct ffs_data *ffs) } gfs_registered = true; - ret = usb_composite_probe(&gfs_driver, gfs_bind); + ret = usb_composite_probe(&gfs_driver); if (unlikely(ret < 0)) gfs_registered = false; diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index ae46f69b718a..1e3cd378a2d7 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -189,12 +189,13 @@ static __refdata struct usb_composite_driver midi_driver = { .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, + .bind = midi_bind, .unbind = __exit_p(midi_unbind), }; static int __init midi_init(void) { - return usb_composite_probe(&midi_driver, midi_bind); + return usb_composite_probe(&midi_driver); } module_init(midi_init); diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 34e139e700b4..8502e56d73bc 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -247,6 +247,7 @@ static __refdata struct usb_composite_driver hidg_driver = { .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, + .bind = hid_bind, .unbind = __exit_p(hid_unbind), }; @@ -272,7 +273,7 @@ static int __init hidg_init(void) if (status < 0) return status; - status = usb_composite_probe(&hidg_driver, hid_bind); + status = usb_composite_probe(&hidg_driver); if (status < 0) platform_driver_unregister(&hidg_plat_driver); diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 5df117e3f78d..480edbc368e5 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -162,6 +162,7 @@ static __refdata struct usb_composite_driver msg_driver = { .iProduct = DRIVER_DESC, .max_speed = USB_SPEED_SUPER, .needs_serial = 1, + .bind = msg_bind, }; MODULE_DESCRIPTION(DRIVER_DESC); @@ -170,7 +171,7 @@ MODULE_LICENSE("GPL"); static int __init msg_init(void) { - return usb_composite_probe(&msg_driver, msg_bind); + return usb_composite_probe(&msg_driver); } module_init(msg_init); diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 7e5852a28a93..13db7ccb9571 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -343,6 +343,7 @@ static __refdata struct usb_composite_driver multi_driver = { .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, + .bind = multi_bind, .unbind = __exit_p(multi_unbind), .iProduct = DRIVER_DESC, .needs_serial = 1, @@ -351,7 +352,7 @@ static __refdata struct usb_composite_driver multi_driver = { static int __init multi_init(void) { - return usb_composite_probe(&multi_driver, multi_bind); + return usb_composite_probe(&multi_driver); } module_init(multi_init); diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index 5079bf659e31..9a20057896cd 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -220,6 +220,7 @@ static __refdata struct usb_composite_driver ncm_driver = { .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, + .bind = gncm_bind, .unbind = __exit_p(gncm_unbind), }; @@ -229,7 +230,7 @@ MODULE_LICENSE("GPL"); static int __init init(void) { - return usb_composite_probe(&ncm_driver, gncm_bind); + return usb_composite_probe(&ncm_driver); } module_init(init); diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index 936d0afc4527..a5b5e7162fef 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -242,12 +242,13 @@ static __refdata struct usb_composite_driver nokia_driver = { .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, + .bind = nokia_bind, .unbind = __exit_p(nokia_unbind), }; static int __init nokia_init(void) { - return usb_composite_probe(&nokia_driver, nokia_bind); + return usb_composite_probe(&nokia_driver); } module_init(nokia_init); diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 0aab51766ce6..33c0c07493e8 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -1274,6 +1274,7 @@ static __refdata struct usb_composite_driver printer_driver = { .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, + .bind = printer_bind, .unbind = printer_unbind, }; @@ -1297,7 +1298,7 @@ init(void) return status; } - status = usb_composite_probe(&printer_driver, printer_bind); + status = usb_composite_probe(&printer_driver); if (status) { class_destroy(usb_gadget_class); unregister_chrdev_region(g_printer_devno, 1); diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 7b0b6f40ed07..ea3f8e9344ae 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -243,6 +243,7 @@ static __refdata struct usb_composite_driver gserial_driver = { .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_SUPER, + .bind = gs_bind, }; static int __init init(void) @@ -271,7 +272,7 @@ static int __init init(void) } strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label; - return usb_composite_probe(&gserial_driver, gs_bind); + return usb_composite_probe(&gserial_driver); } module_init(init); diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 28fef844a06a..35ca09af9b4a 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -2441,12 +2441,13 @@ static __refdata struct usb_composite_driver usbg_driver = { .dev = &usbg_device_desc, .strings = usbg_strings, .max_speed = USB_SPEED_SUPER, + .bind = usb_target_bind, .unbind = guas_unbind, }; static int usbg_attach(struct usbg_tpg *tpg) { - return usb_composite_probe(&usbg_driver, usb_target_bind); + return usb_composite_probe(&usbg_driver); } static void usbg_detach(struct usbg_tpg *tpg) diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index d946f19482e8..2a617c3f5a40 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -395,13 +395,14 @@ static __refdata struct usb_composite_driver webcam_driver = { .dev = &webcam_device_descriptor, .strings = webcam_device_strings, .max_speed = USB_SPEED_SUPER, + .bind = webcam_bind, .unbind = webcam_unbind, }; static int __init webcam_init(void) { - return usb_composite_probe(&webcam_driver, webcam_bind); + return usb_composite_probe(&webcam_driver); } static void __exit diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 5db33cbe755b..90df613cccc0 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -339,6 +339,7 @@ static __refdata struct usb_composite_driver zero_driver = { .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_SUPER, + .bind = zero_bind, .unbind = zero_unbind, .suspend = zero_suspend, .resume = zero_resume, @@ -349,7 +350,7 @@ MODULE_LICENSE("GPL"); static int __init init(void) { - return usb_composite_probe(&zero_driver, zero_bind); + return usb_composite_probe(&zero_driver); } module_init(init); diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 3153f73ae083..19a5adf18bf4 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -305,8 +305,7 @@ struct usb_composite_driver { void (*resume)(struct usb_composite_dev *); }; -extern int usb_composite_probe(struct usb_composite_driver *driver, - int (*bind)(struct usb_composite_dev *cdev)); +extern int usb_composite_probe(struct usb_composite_driver *driver); extern void usb_composite_unregister(struct usb_composite_driver *driver); extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); -- cgit v1.2.3-59-g8ed1b From 93952956c7078eb41058c5ccc5b34ae6cf59bb64 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:05 +0200 Subject: usb: gadget: move bind() callback back to struct usb_gadget_driver This partly reverts 07a18bd7 ("usb gadget: don't save bind callback in struct usb_composite_driver") and fixes new drivers. The section missmatch problems was solved by whitelisting bind callback in modpost. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 3 ++- drivers/usb/gadget/dbgp.c | 3 ++- drivers/usb/gadget/file_storage.c | 4 +++- drivers/usb/gadget/inode.c | 7 +++++-- drivers/usb/gadget/udc-core.c | 9 ++++----- include/linux/usb/gadget.h | 6 +++--- 6 files changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 071d15c44116..2a345f28b9ae 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1585,6 +1585,7 @@ composite_resume(struct usb_gadget *gadget) /*-------------------------------------------------------------------------*/ static struct usb_gadget_driver composite_driver = { + .bind = composite_bind, .unbind = composite_unbind, .setup = composite_setup, @@ -1631,7 +1632,7 @@ int usb_composite_probe(struct usb_composite_driver *driver) composite_driver.max_speed = driver->max_speed; composite = driver; - return usb_gadget_probe_driver(&composite_driver, composite_bind); + return usb_gadget_probe_driver(&composite_driver); } /** diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index 2d2cff3e454c..df9a0104bdf2 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c @@ -405,6 +405,7 @@ fail: static __refdata struct usb_gadget_driver dbgp_driver = { .function = "dbgp", .max_speed = USB_SPEED_HIGH, + .bind = dbgp_bind, .unbind = dbgp_unbind, .setup = dbgp_setup, .disconnect = dbgp_disconnect, @@ -416,7 +417,7 @@ static __refdata struct usb_gadget_driver dbgp_driver = { static int __init dbgp_init(void) { - return usb_gadget_probe_driver(&dbgp_driver, dbgp_bind); + return usb_gadget_probe_driver(&dbgp_driver); } static void __exit dbgp_exit(void) diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 683234bcdced..ce186fa7e7b2 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -3606,6 +3606,7 @@ static void fsg_resume(struct usb_gadget *gadget) static __refdata struct usb_gadget_driver fsg_driver = { .max_speed = USB_SPEED_SUPER, .function = (char *) fsg_string_product, + .bind = fsg_bind, .unbind = fsg_unbind, .disconnect = fsg_disconnect, .setup = fsg_setup, @@ -3653,7 +3654,8 @@ static int __init fsg_init(void) if ((rc = fsg_alloc()) != 0) return rc; fsg = the_fsg; - if ((rc = usb_gadget_probe_driver(&fsg_driver, fsg_bind)) != 0) + rc = usb_gadget_probe_driver(&fsg_driver); + if (rc != 0) kref_put(&fsg->ref, fsg_release); return rc; } diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index ae13a106fb96..2521804ba4ee 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1758,6 +1758,7 @@ gadgetfs_suspend (struct usb_gadget *gadget) static struct usb_gadget_driver gadgetfs_driver = { .function = (char *) driver_desc, + .bind = gadgetfs_bind, .unbind = gadgetfs_unbind, .setup = gadgetfs_setup, .disconnect = gadgetfs_disconnect, @@ -1780,6 +1781,7 @@ static int gadgetfs_probe (struct usb_gadget *gadget) static struct usb_gadget_driver probe_driver = { .max_speed = USB_SPEED_HIGH, + .bind = gadgetfs_probe, .unbind = gadgetfs_nop, .setup = (void *)gadgetfs_nop, .disconnect = gadgetfs_nop, @@ -1893,7 +1895,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) gadgetfs_driver.max_speed = USB_SPEED_HIGH; else gadgetfs_driver.max_speed = USB_SPEED_FULL; - value = usb_gadget_probe_driver(&gadgetfs_driver, gadgetfs_bind); + + value = usb_gadget_probe_driver(&gadgetfs_driver); if (value != 0) { kfree (dev->buf); dev->buf = NULL; @@ -2032,7 +2035,7 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) return -ESRCH; /* fake probe to determine $CHIP */ - (void) usb_gadget_probe_driver(&probe_driver, gadgetfs_probe); + usb_gadget_probe_driver(&probe_driver); if (!CHIP) return -ENODEV; diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index bae243c23141..85e1e2fdd403 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -311,13 +311,12 @@ EXPORT_SYMBOL_GPL(usb_del_gadget_udc); /* ------------------------------------------------------------------------- */ -int usb_gadget_probe_driver(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) +int usb_gadget_probe_driver(struct usb_gadget_driver *driver) { struct usb_udc *udc = NULL; int ret; - if (!driver || !bind || !driver->setup) + if (!driver || !driver->bind || !driver->setup) return -EINVAL; mutex_lock(&udc_lock); @@ -339,7 +338,7 @@ found: udc->dev.driver = &driver->driver; if (udc_is_newstyle(udc)) { - ret = bind(udc->gadget); + ret = driver->bind(udc->gadget); if (ret) goto err1; ret = usb_gadget_udc_start(udc->gadget, driver); @@ -350,7 +349,7 @@ found: usb_gadget_connect(udc->gadget); } else { - ret = usb_gadget_start(udc->gadget, driver, bind); + ret = usb_gadget_start(udc->gadget, driver, driver->bind); if (ret) goto err1; diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index d05b220f0fd3..9eb4e712168f 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -766,6 +766,7 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget) * when the host is disconnected. May be called in_interrupt; this * may not sleep. Some devices can't detect disconnect, so this might * not be called except as part of controller shutdown. + * @bind: the driver's bind callback * @unbind: Invoked when the driver is unbound from a gadget, * usually from rmmod (after a disconnect is reported). * Called in a context that permits sleeping. @@ -820,6 +821,7 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget) struct usb_gadget_driver { char *function; enum usb_device_speed max_speed; + int (*bind)(struct usb_gadget *gadget); void (*unbind)(struct usb_gadget *); int (*setup)(struct usb_gadget *, const struct usb_ctrlrequest *); @@ -845,7 +847,6 @@ struct usb_gadget_driver { /** * usb_gadget_probe_driver - probe a gadget driver * @driver: the driver being registered - * @bind: the driver's bind callback * Context: can sleep * * Call this in your gadget driver's module initialization function, @@ -854,8 +855,7 @@ struct usb_gadget_driver { * registration call returns. It's expected that the @bind() function will * be in init sections. */ -int usb_gadget_probe_driver(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); +int usb_gadget_probe_driver(struct usb_gadget_driver *driver); /** * usb_gadget_unregister_driver - unregister a gadget driver -- cgit v1.2.3-59-g8ed1b From ffe0b335062505a98d7296dae2c2a197713f87e0 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 7 Sep 2012 09:53:17 +0200 Subject: usb: gadget: remove global variable composite in composite.c This patch removes the global variable composite in composite.c. The private data which was saved there is now passed via an additional argument to the bind() function in struct usb_gadget_driver. Only the "old-style" UDC drivers have to be touched here, new style are doing it right because this change is made in udc-core. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/staging/ccg/composite.c | 3 ++- drivers/usb/gadget/amd5536udc.c | 6 ++--- drivers/usb/gadget/composite.c | 52 ++++++++++++++++++++++----------------- drivers/usb/gadget/dbgp.c | 3 ++- drivers/usb/gadget/file_storage.c | 3 ++- drivers/usb/gadget/fsl_udc_core.c | 6 ++--- drivers/usb/gadget/fusb300_udc.c | 4 +-- drivers/usb/gadget/goku_udc.c | 6 ++--- drivers/usb/gadget/inode.c | 7 +++--- drivers/usb/gadget/m66592-udc.c | 4 +-- drivers/usb/gadget/mv_udc_core.c | 6 ++--- drivers/usb/gadget/omap_udc.c | 6 ++--- drivers/usb/gadget/pch_udc.c | 6 ++--- drivers/usb/gadget/pxa25x_udc.c | 6 ++--- drivers/usb/gadget/pxa27x_udc.c | 6 ++--- drivers/usb/gadget/s3c2410_udc.c | 6 ++--- drivers/usb/gadget/udc-core.c | 4 +-- include/linux/usb/composite.h | 1 + include/linux/usb/gadget.h | 6 +++-- 19 files changed, 78 insertions(+), 63 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/staging/ccg/composite.c b/drivers/staging/ccg/composite.c index 2a345f28b9ae..228b4574f228 100644 --- a/drivers/staging/ccg/composite.c +++ b/drivers/staging/ccg/composite.c @@ -1422,7 +1422,8 @@ static u8 override_id(struct usb_composite_dev *cdev, u8 *desc) return *desc; } -static int composite_bind(struct usb_gadget *gadget) +static int composite_bind(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { struct usb_composite_dev *cdev; int status = -ENOMEM; diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 187d21181cd5..fc0ec5e0d58e 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -1401,7 +1401,7 @@ static int udc_wakeup(struct usb_gadget *gadget) } static int amd5536_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); static int amd5536_stop(struct usb_gadget_driver *driver); /* gadget operations */ static const struct usb_gadget_ops udc_ops = { @@ -1914,7 +1914,7 @@ static int setup_ep0(struct udc *dev) /* Called by gadget driver to register itself */ static int amd5536_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { struct udc *dev = udc; int retval; @@ -1932,7 +1932,7 @@ static int amd5536_start(struct usb_gadget_driver *driver, dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - retval = bind(&dev->gadget); + retval = bind(&dev->gadget, driver); /* Some gadget drivers use both ep0 directions. * NOTE: to gadget driver, ep0 is just one endpoint... diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 2a345f28b9ae..0b6ee2012af1 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -31,8 +31,6 @@ /* big enough to hold our biggest descriptor */ #define USB_BUFSIZ 1024 -static struct usb_composite_driver *composite; - /* Some systems will need runtime overrides for the product identifiers * published in the device descriptor, either numbers or strings or both. * String parameters are in UTF-8 (superset of ASCII's 7 bit characters). @@ -889,6 +887,7 @@ static int lookup_string( static int get_string(struct usb_composite_dev *cdev, void *buf, u16 language, int id) { + struct usb_composite_driver *composite = cdev->driver; struct usb_configuration *c; struct usb_function *f; int len; @@ -1359,8 +1358,8 @@ static void composite_disconnect(struct usb_gadget *gadget) spin_lock_irqsave(&cdev->lock, flags); if (cdev->config) reset_config(cdev); - if (composite->disconnect) - composite->disconnect(cdev); + if (cdev->driver->disconnect) + cdev->driver->disconnect(cdev); spin_unlock_irqrestore(&cdev->lock, flags); } @@ -1396,8 +1395,8 @@ composite_unbind(struct usb_gadget *gadget) struct usb_configuration, list); remove_config(cdev, c); } - if (composite->unbind) - composite->unbind(cdev); + if (cdev->driver->unbind) + cdev->driver->unbind(cdev); if (cdev->req) { kfree(cdev->req->buf); @@ -1406,7 +1405,6 @@ composite_unbind(struct usb_gadget *gadget) device_remove_file(&gadget->dev, &dev_attr_suspended); kfree(cdev); set_gadget_data(gadget, NULL); - composite = NULL; } static u8 override_id(struct usb_composite_dev *cdev, u8 *desc) @@ -1422,9 +1420,16 @@ static u8 override_id(struct usb_composite_dev *cdev, u8 *desc) return *desc; } -static int composite_bind(struct usb_gadget *gadget) +static struct usb_composite_driver *to_cdriver(struct usb_gadget_driver *gdrv) +{ + return container_of(gdrv, struct usb_composite_driver, gadget_driver); +} + +static int composite_bind(struct usb_gadget *gadget, + struct usb_gadget_driver *gdriver) { struct usb_composite_dev *cdev; + struct usb_composite_driver *composite = to_cdriver(gdriver); int status = -ENOMEM; cdev = kzalloc(sizeof *cdev, GFP_KERNEL); @@ -1546,8 +1551,8 @@ composite_suspend(struct usb_gadget *gadget) f->suspend(f); } } - if (composite->suspend) - composite->suspend(cdev); + if (cdev->driver->suspend) + cdev->driver->suspend(cdev); cdev->suspended = 1; @@ -1565,8 +1570,8 @@ composite_resume(struct usb_gadget *gadget) * suspend/resume callbacks? */ DBG(cdev, "resume\n"); - if (composite->resume) - composite->resume(cdev); + if (cdev->driver->resume) + cdev->driver->resume(cdev); if (cdev->config) { list_for_each_entry(f, &cdev->config->functions, list) { if (f->resume) @@ -1584,7 +1589,7 @@ composite_resume(struct usb_gadget *gadget) /*-------------------------------------------------------------------------*/ -static struct usb_gadget_driver composite_driver = { +static const struct usb_gadget_driver composite_driver_template = { .bind = composite_bind, .unbind = composite_unbind, @@ -1620,19 +1625,24 @@ static struct usb_gadget_driver composite_driver = { */ int usb_composite_probe(struct usb_composite_driver *driver) { - if (!driver || !driver->dev || composite || !driver->bind) + struct usb_gadget_driver *gadget_driver; + + if (!driver || !driver->dev || !driver->bind) return -EINVAL; if (!driver->name) driver->name = "composite"; if (!driver->iProduct) driver->iProduct = driver->name; - composite_driver.function = (char *) driver->name; - composite_driver.driver.name = driver->name; - composite_driver.max_speed = driver->max_speed; - composite = driver; - return usb_gadget_probe_driver(&composite_driver); + driver->gadget_driver = composite_driver_template; + gadget_driver = &driver->gadget_driver; + + gadget_driver->function = (char *) driver->name; + gadget_driver->driver.name = driver->name; + gadget_driver->max_speed = driver->max_speed; + + return usb_gadget_probe_driver(gadget_driver); } /** @@ -1644,9 +1654,7 @@ int usb_composite_probe(struct usb_composite_driver *driver) */ void usb_composite_unregister(struct usb_composite_driver *driver) { - if (composite != driver) - return; - usb_gadget_unregister_driver(&composite_driver); + usb_gadget_unregister_driver(&driver->gadget_driver); } /** diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index df9a0104bdf2..cc1746597aab 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c @@ -292,7 +292,8 @@ fail_1: return -ENODEV; } -static int __init dbgp_bind(struct usb_gadget *gadget) +static int __init dbgp_bind(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { int err, stp; diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index ce186fa7e7b2..cdacae706b70 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -3331,7 +3331,8 @@ static int __init check_parameters(struct fsg_dev *fsg) } -static int __init fsg_bind(struct usb_gadget *gadget) +static int __init fsg_bind(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { struct fsg_dev *fsg = the_fsg; int rc; diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 3def828f85e7..6ae70cba0c4a 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -1255,7 +1255,7 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) } static int fsl_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); static int fsl_stop(struct usb_gadget_driver *driver); /* defined in gadget.h */ static struct usb_gadget_ops fsl_gadget_ops = { @@ -1951,7 +1951,7 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) * Called by initialization code of gadget drivers *----------------------------------------------------------------*/ static int fsl_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { int retval = -ENODEV; unsigned long flags = 0; @@ -1976,7 +1976,7 @@ static int fsl_start(struct usb_gadget_driver *driver, spin_unlock_irqrestore(&udc_controller->lock, flags); /* bind udc driver to gadget driver */ - retval = bind(&udc_controller->gadget); + retval = bind(&udc_controller->gadget, driver); if (retval) { VDBG("bind to %s --> %d", driver->driver.name, retval); udc_controller->gadget.dev.driver = NULL; diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index cdd94540e1cd..72cd5e6719db 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -1311,7 +1311,7 @@ static void init_controller(struct fusb300 *fusb300) static struct fusb300 *the_controller; static int fusb300_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { struct fusb300 *fusb300 = the_controller; int retval; @@ -1339,7 +1339,7 @@ static int fusb300_udc_start(struct usb_gadget_driver *driver, goto error; } - retval = bind(&fusb300->gadget); + retval = bind(&fusb300->gadget, driver); if (retval) { pr_err("bind to driver error (%d)\n", retval); device_del(&fusb300->gadget.dev); diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 9fd7886cfa9a..51037cb78604 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -994,7 +994,7 @@ static int goku_get_frame(struct usb_gadget *_gadget) } static int goku_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); static int goku_stop(struct usb_gadget_driver *driver); static const struct usb_gadget_ops goku_ops = { @@ -1348,7 +1348,7 @@ static struct goku_udc *the_controller; * the driver might get unbound. */ static int goku_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { struct goku_udc *dev = the_controller; int retval; @@ -1368,7 +1368,7 @@ static int goku_start(struct usb_gadget_driver *driver, driver->driver.bus = NULL; dev->driver = driver; dev->gadget.dev.driver = &driver->driver; - retval = bind(&dev->gadget); + retval = bind(&dev->gadget, driver); if (retval) { DBG(dev, "bind to driver %s --> error %d\n", driver->driver.name, retval); diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 2521804ba4ee..4bb6d53f2de3 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1679,8 +1679,8 @@ gadgetfs_unbind (struct usb_gadget *gadget) static struct dev_data *the_device; -static int -gadgetfs_bind (struct usb_gadget *gadget) +static int gadgetfs_bind(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { struct dev_data *dev = the_device; @@ -1773,7 +1773,8 @@ static struct usb_gadget_driver gadgetfs_driver = { static void gadgetfs_nop(struct usb_gadget *arg) { } -static int gadgetfs_probe (struct usb_gadget *gadget) +static int gadgetfs_probe(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { CHIP = gadget->name; return -EISNAM; diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index cf6bd626f3fe..b6401f1b56ce 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1466,7 +1466,7 @@ static struct usb_ep_ops m66592_ep_ops = { static struct m66592 *the_controller; static int m66592_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { struct m66592 *m66592 = the_controller; int retval; @@ -1492,7 +1492,7 @@ static int m66592_start(struct usb_gadget_driver *driver, goto error; } - retval = bind(&m66592->gadget); + retval = bind(&m66592->gadget, driver); if (retval) { pr_err("bind to driver error (%d)\n", retval); device_del(&m66592->gadget.dev); diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index ad91de4d60d8..ea45224f78c8 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -1269,7 +1269,7 @@ static int mv_udc_pullup(struct usb_gadget *gadget, int is_on) } static int mv_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); static int mv_udc_stop(struct usb_gadget_driver *driver); /* device controller usb_gadget_ops structure */ static const struct usb_gadget_ops mv_ops = { @@ -1374,7 +1374,7 @@ static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver) } static int mv_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { struct mv_udc *udc = the_controller; int retval = 0; @@ -1399,7 +1399,7 @@ static int mv_udc_start(struct usb_gadget_driver *driver, spin_unlock_irqrestore(&udc->lock, flags); - retval = bind(&udc->gadget); + retval = bind(&udc->gadget, driver); if (retval) { dev_err(&udc->dev->dev, "bind to driver %s --> %d\n", driver->driver.name, retval); diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index f9132ada53b5..2a4749c3eb3f 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -1308,7 +1308,7 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on) } static int omap_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); static int omap_udc_stop(struct usb_gadget_driver *driver); static struct usb_gadget_ops omap_gadget_ops = { @@ -2040,7 +2040,7 @@ static inline int machine_without_vbus_sense(void) } static int omap_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { int status = -ENODEV; struct omap_ep *ep; @@ -2082,7 +2082,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, if (udc->dc_clk != NULL) omap_udc_enable_clock(1); - status = bind(&udc->gadget); + status = bind(&udc->gadget, driver); if (status) { DBG("bind to %s --> %d\n", driver->driver.name, status); udc->gadget.dev.driver = NULL; diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index f4fb71c9ae08..6490c0040e3a 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -1236,7 +1236,7 @@ static int pch_udc_pcd_vbus_draw(struct usb_gadget *gadget, unsigned int mA) } static int pch_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); static int pch_udc_stop(struct usb_gadget_driver *driver); static const struct usb_gadget_ops pch_udc_ops = { .get_frame = pch_udc_pcd_get_frame, @@ -2982,7 +2982,7 @@ static int init_dma_pools(struct pch_udc_dev *dev) } static int pch_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { struct pch_udc_dev *dev = pch_udc; int retval; @@ -3006,7 +3006,7 @@ static int pch_udc_start(struct usb_gadget_driver *driver, dev->gadget.dev.driver = &driver->driver; /* Invoke the bind routine of the gadget driver */ - retval = bind(&dev->gadget); + retval = bind(&dev->gadget, driver); if (retval) { dev_err(&dev->pdev->dev, "%s: binding to %s returning %d\n", diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index c246c08a242d..8efbf08c3561 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -999,7 +999,7 @@ static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) } static int pxa25x_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); static int pxa25x_stop(struct usb_gadget_driver *driver); static const struct usb_gadget_ops pxa25x_udc_ops = { @@ -1257,7 +1257,7 @@ static void udc_enable (struct pxa25x_udc *dev) * the driver might get unbound. */ static int pxa25x_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { struct pxa25x_udc *dev = the_controller; int retval; @@ -1285,7 +1285,7 @@ fail: dev->gadget.dev.driver = NULL; return retval; } - retval = bind(&dev->gadget); + retval = bind(&dev->gadget, driver); if (retval) { DMSG("bind to driver %s --> error %d\n", driver->driver.name, retval); diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 644b4305cb99..979ddaddb0f8 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -1672,7 +1672,7 @@ static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) } static int pxa27x_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); static int pxa27x_udc_stop(struct usb_gadget_driver *driver); static const struct usb_gadget_ops pxa_udc_ops = { @@ -1803,7 +1803,7 @@ static void udc_enable(struct pxa_udc *udc) * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise */ static int pxa27x_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { struct pxa_udc *udc = the_controller; int retval; @@ -1826,7 +1826,7 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver, dev_err(udc->dev, "device_add error %d\n", retval); goto add_fail; } - retval = bind(&udc->gadget); + retval = bind(&udc->gadget, driver); if (retval) { dev_err(udc->dev, "bind to driver %s --> error %d\n", driver->driver.name, retval); diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index b627c9b51fda..c33e942d119c 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1539,7 +1539,7 @@ static int s3c2410_vbus_draw(struct usb_gadget *_gadget, unsigned ma) } static int s3c2410_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); static int s3c2410_udc_stop(struct usb_gadget_driver *driver); static const struct usb_gadget_ops s3c2410_ops = { @@ -1665,7 +1665,7 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev) } static int s3c2410_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { struct s3c2410_udc *udc = the_controller; int retval; @@ -1705,7 +1705,7 @@ static int s3c2410_udc_start(struct usb_gadget_driver *driver, dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n", driver->driver.name); - retval = bind(&udc->gadget); + retval = bind(&udc->gadget, driver); if (retval) { device_del(&udc->gadget.dev); goto register_error; diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 85e1e2fdd403..f3cd9690b101 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); */ static inline int usb_gadget_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) + int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) { return gadget->ops->start(driver, bind); } @@ -338,7 +338,7 @@ found: udc->dev.driver = &driver->driver; if (udc_is_newstyle(udc)) { - ret = driver->bind(udc->gadget); + ret = driver->bind(udc->gadget, driver); if (ret) goto err1; ret = usb_gadget_udc_start(udc->gadget, driver); diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 19a5adf18bf4..43d6b9ca51b7 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -303,6 +303,7 @@ struct usb_composite_driver { /* global suspend hooks */ void (*suspend)(struct usb_composite_dev *); void (*resume)(struct usb_composite_dev *); + struct usb_gadget_driver gadget_driver; }; extern int usb_composite_probe(struct usb_composite_driver *driver); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 9eb4e712168f..822c1b88f95a 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -474,7 +474,8 @@ struct usb_gadget_ops { /* Those two are deprecated */ int (*start)(struct usb_gadget_driver *, - int (*bind)(struct usb_gadget *)); + int (*bind)(struct usb_gadget *, + struct usb_gadget_driver *driver)); int (*stop)(struct usb_gadget_driver *); }; @@ -821,7 +822,8 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget) struct usb_gadget_driver { char *function; enum usb_device_speed max_speed; - int (*bind)(struct usb_gadget *gadget); + int (*bind)(struct usb_gadget *gadget, + struct usb_gadget_driver *driver); void (*unbind)(struct usb_gadget *); int (*setup)(struct usb_gadget *, const struct usb_ctrlrequest *); -- cgit v1.2.3-59-g8ed1b From 4001a7a163d8e49eb9baf294527ad2ed50202e22 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:08 +0200 Subject: usb: gadget: pxa25x: make it compile with debug again |drivers/usb/gadget/pxa25x_udc.h: In function 'dump_state': |drivers/usb/gadget/pxa25x_udc.h:228:20: error: invalid type argument of '->' (have 'struct usb_ep') Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa25x_udc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/pxa25x_udc.h b/drivers/usb/gadget/pxa25x_udc.h index 861f4df6ea22..2eca1e71fecd 100644 --- a/drivers/usb/gadget/pxa25x_udc.h +++ b/drivers/usb/gadget/pxa25x_udc.h @@ -225,7 +225,7 @@ dump_state(struct pxa25x_udc *dev) dev->stats.read.bytes, dev->stats.read.ops); for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) { - if (dev->ep [i].desc == NULL) + if (dev->ep[i].ep.desc == NULL) continue; DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs); } -- cgit v1.2.3-59-g8ed1b From a84d9e5361bcfbff1c84481bd9c04fc58a56d83b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:09 +0200 Subject: usb: gadget: start with libcomposite This patch aims to be simple. It removes #include usbstribgs.c line from each gadget and creates libcomposite.ko which has only one member, that is usbstribgs.c. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 25 +++++++++++++++++++++++++ drivers/usb/gadget/Makefile | 2 ++ drivers/usb/gadget/acm_ms.c | 1 - drivers/usb/gadget/audio.c | 1 - drivers/usb/gadget/cdc2.c | 1 - drivers/usb/gadget/ether.c | 1 - drivers/usb/gadget/file_storage.c | 1 - drivers/usb/gadget/g_ffs.c | 1 - drivers/usb/gadget/gmidi.c | 1 - drivers/usb/gadget/hid.c | 1 - drivers/usb/gadget/mass_storage.c | 1 - drivers/usb/gadget/multi.c | 1 - drivers/usb/gadget/ncm.c | 1 - drivers/usb/gadget/nokia.c | 1 - drivers/usb/gadget/printer.c | 1 - drivers/usb/gadget/serial.c | 1 - drivers/usb/gadget/tcm_usb_gadget.c | 1 - drivers/usb/gadget/usbstring.c | 4 +++- drivers/usb/gadget/webcam.c | 1 - drivers/usb/gadget/zero.c | 1 - 20 files changed, 30 insertions(+), 18 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 75b76d5a0fe9..a53be32c22cf 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -494,6 +494,12 @@ endmenu # # USB Gadget Drivers # + +# composite based drivers +config USB_LIBCOMPOSITE + tristate + depends on USB_GADGET + choice tristate "USB Gadget Drivers" default USB_ETH @@ -517,6 +523,7 @@ choice config USB_ZERO tristate "Gadget Zero (DEVELOPMENT)" + select USB_LIBCOMPOSITE help Gadget Zero is a two-configuration device. It either sinks and sources bulk data; or it loops back a configurable number of @@ -552,6 +559,7 @@ config USB_ZERO_HNPTEST config USB_AUDIO tristate "Audio Gadget (EXPERIMENTAL)" depends on SND + select USB_LIBCOMPOSITE select SND_PCM help This Gadget Audio driver is compatible with USB Audio Class @@ -580,6 +588,7 @@ config GADGET_UAC1 config USB_ETH tristate "Ethernet Gadget (with CDC Ethernet support)" depends on NET + select USB_LIBCOMPOSITE select CRC32 help This driver implements Ethernet style communication, in one of @@ -615,6 +624,7 @@ config USB_ETH config USB_ETH_RNDIS bool "RNDIS support" depends on USB_ETH + select USB_LIBCOMPOSITE default y help Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol, @@ -633,6 +643,7 @@ config USB_ETH_RNDIS config USB_ETH_EEM bool "Ethernet Emulation Model (EEM) support" depends on USB_ETH + select USB_LIBCOMPOSITE default n help CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM @@ -649,6 +660,7 @@ config USB_ETH_EEM config USB_G_NCM tristate "Network Control Model (NCM) support" depends on NET + select USB_LIBCOMPOSITE select CRC32 help This driver implements USB CDC NCM subclass standard. NCM is @@ -678,6 +690,7 @@ config USB_GADGETFS config USB_FUNCTIONFS tristate "Function Filesystem (EXPERIMENTAL)" depends on EXPERIMENTAL + select USB_LIBCOMPOSITE select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS) help The Function Filesystem (FunctionFS) lets one create USB @@ -741,6 +754,7 @@ config USB_FILE_STORAGE_TEST config USB_MASS_STORAGE tristate "Mass Storage Gadget" depends on BLOCK + select USB_LIBCOMPOSITE help The Mass Storage Gadget acts as a USB Mass Storage disk drive. As its storage repository it can use a regular file or a block @@ -756,6 +770,7 @@ config USB_MASS_STORAGE config USB_GADGET_TARGET tristate "USB Gadget Target Fabric Module" depends on TARGET_CORE + select USB_LIBCOMPOSITE help This fabric is an USB gadget. Two USB protocols are supported that is BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is @@ -765,6 +780,7 @@ config USB_GADGET_TARGET config USB_G_SERIAL tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" + select USB_LIBCOMPOSITE help The Serial Gadget talks to the Linux-USB generic serial driver. This driver supports a CDC-ACM module option, which can be used @@ -785,6 +801,7 @@ config USB_G_SERIAL config USB_MIDI_GADGET tristate "MIDI Gadget (EXPERIMENTAL)" depends on SND && EXPERIMENTAL + select USB_LIBCOMPOSITE select SND_RAWMIDI help The MIDI Gadget acts as a USB Audio device, with one MIDI @@ -798,6 +815,7 @@ config USB_MIDI_GADGET config USB_G_PRINTER tristate "Printer Gadget" + select USB_LIBCOMPOSITE help The Printer Gadget channels data between the USB host and a userspace program driving the print engine. The user space @@ -814,6 +832,7 @@ config USB_G_PRINTER config USB_CDC_COMPOSITE tristate "CDC Composite Device (Ethernet and ACM)" depends on NET + select USB_LIBCOMPOSITE help This driver provides two functions in one configuration: a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link. @@ -828,6 +847,7 @@ config USB_CDC_COMPOSITE config USB_G_NOKIA tristate "Nokia composite gadget" depends on PHONET + select USB_LIBCOMPOSITE help The Nokia composite gadget provides support for acm, obex and phonet in only one composite gadget driver. @@ -838,6 +858,7 @@ config USB_G_NOKIA config USB_G_ACM_MS tristate "CDC Composite Device (ACM and mass storage)" depends on BLOCK + select USB_LIBCOMPOSITE help This driver provides two functions in one configuration: a mass storage, and a CDC ACM (serial port) link. @@ -849,6 +870,7 @@ config USB_G_MULTI tristate "Multifunction Composite Gadget (EXPERIMENTAL)" depends on BLOCK && NET select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS + select USB_LIBCOMPOSITE help The Multifunction Composite Gadget provides Ethernet (RNDIS and/or CDC Ethernet), mass storage and ACM serial link @@ -889,6 +911,7 @@ config USB_G_MULTI_CDC config USB_G_HID tristate "HID Gadget" + select USB_LIBCOMPOSITE help The HID gadget driver provides generic emulation of USB Human Interface Devices (HID). @@ -899,8 +922,10 @@ config USB_G_HID Say "y" to link the driver statically, or "m" to build a dynamically linked module called "g_hid". +# Standalone / single function gadgets config USB_G_DBGP tristate "EHCI Debug Device Gadget" + select USB_LIBCOMPOSITE help This gadget emulates an EHCI Debug device. This is useful when you want to interact with an EHCI Debug Port. diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index d84f92325a74..eadbc86333f6 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -4,6 +4,8 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG obj-$(CONFIG_USB_GADGET) += udc-core.o +obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o +libcomposite-y := usbstring.o obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2272) += net2272.o obj-$(CONFIG_USB_NET2280) += net2280.o diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 65a2f3cbcde3..9820960dfc5c 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -42,7 +42,6 @@ */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" #include "u_serial.c" diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index dd339bc5b40c..76e54b44c27a 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -27,7 +27,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index b7d984b54ca9..74a9c7f65ec8 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -44,7 +44,6 @@ */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" #include "u_serial.c" diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 4580ec09cc53..e16094e5d1d2 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -103,7 +103,6 @@ static inline bool has_rndis(void) * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index cdacae706b70..8d0166b76d40 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -265,7 +265,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index da9809f55cb5..407b5ccc64a4 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -24,7 +24,6 @@ */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 1e3cd378a2d7..135b3900eaa3 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -38,7 +38,6 @@ #include "gadget_chips.h" #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" #include "f_midi.c" diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 8502e56d73bc..effda2e0742b 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -35,7 +35,6 @@ */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 480edbc368e5..a7f32c312a6b 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -49,7 +49,6 @@ */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" #include "f_mass_storage.c" diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 13db7ccb9571..71c1fabdbb78 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -44,7 +44,6 @@ MODULE_LICENSE("GPL"); */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index 9a20057896cd..d7e6b1ee8664 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -37,7 +37,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index a5b5e7162fef..474c77ca58c0 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -39,7 +39,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 33c0c07493e8..c55e7d99b810 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -52,7 +52,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index ea3f8e9344ae..88baa9e3f827 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -38,7 +38,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 35ca09af9b4a..327af6883715 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -25,7 +25,6 @@ #include #include -#include "usbstring.c" #include "epautoconf.c" #include "config.c" #include "composite.c" diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index 4d25b9009edf..24e9bbd255a7 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -68,4 +69,5 @@ usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf) buf [1] = USB_DT_STRING; return buf [0]; } - +EXPORT_SYMBOL_GPL(usb_gadget_get_string); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index 2a617c3f5a40..dc8fd5cc4f92 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -24,7 +24,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 90df613cccc0..4469be8fcee3 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -59,7 +59,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "usbstring.c" #include "config.c" #include "epautoconf.c" -- cgit v1.2.3-59-g8ed1b From 0ba16dea72a457bf65fc06ef60165c994e2f7420 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:10 +0200 Subject: usb: gadget: libcomposite: move config.c into libcomposite This patch moves config.c into libcomposite and updates all gadgets. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Makefile | 2 +- drivers/usb/gadget/acm_ms.c | 1 - drivers/usb/gadget/audio.c | 1 - drivers/usb/gadget/cdc2.c | 1 - drivers/usb/gadget/config.c | 6 ++++-- drivers/usb/gadget/ether.c | 1 - drivers/usb/gadget/file_storage.c | 1 - drivers/usb/gadget/g_ffs.c | 1 - drivers/usb/gadget/gmidi.c | 1 - drivers/usb/gadget/hid.c | 1 - drivers/usb/gadget/mass_storage.c | 1 - drivers/usb/gadget/multi.c | 1 - drivers/usb/gadget/ncm.c | 1 - drivers/usb/gadget/nokia.c | 1 - drivers/usb/gadget/printer.c | 1 - drivers/usb/gadget/serial.c | 1 - drivers/usb/gadget/tcm_usb_gadget.c | 1 - drivers/usb/gadget/webcam.c | 1 - drivers/usb/gadget/zero.c | 1 - 19 files changed, 5 insertions(+), 20 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index eadbc86333f6..9515ed0163b7 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -5,7 +5,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG obj-$(CONFIG_USB_GADGET) += udc-core.o obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o -libcomposite-y := usbstring.o +libcomposite-y := usbstring.o config.o obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2272) += net2272.o obj-$(CONFIG_USB_NET2280) += net2280.o diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 9820960dfc5c..3078d797f634 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -42,7 +42,6 @@ */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "u_serial.c" #include "f_acm.c" diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 76e54b44c27a..9e85df22e796 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -27,7 +27,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "config.c" #include "epautoconf.c" /* string IDs are assigned dynamically */ diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 74a9c7f65ec8..d06d0791c70e 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -44,7 +44,6 @@ */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "u_serial.c" #include "f_acm.c" diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index 7542a72ce51a..e3a98929d346 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,7 @@ usb_descriptor_fillbuf(void *buf, unsigned buflen, } return dest - (u8 *)buf; } - +EXPORT_SYMBOL_GPL(usb_descriptor_fillbuf); /** * usb_gadget_config_buf - builts a complete configuration descriptor @@ -106,6 +107,7 @@ int usb_gadget_config_buf( cp->bmAttributes |= USB_CONFIG_ATT_ONE; return len; } +EXPORT_SYMBOL_GPL(usb_gadget_config_buf); /** * usb_copy_descriptors - copy a vector of USB descriptors @@ -155,4 +157,4 @@ usb_copy_descriptors(struct usb_descriptor_header **src) return ret; } - +EXPORT_SYMBOL_GPL(usb_copy_descriptors); diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index e16094e5d1d2..557021e267ee 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -103,7 +103,6 @@ static inline bool has_rndis(void) * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "f_ecm.c" diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 8d0166b76d40..77cf1083099f 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -265,7 +265,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "config.c" #include "epautoconf.c" /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 407b5ccc64a4..240957048d3f 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -24,7 +24,6 @@ */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 135b3900eaa3..68a79b42c5a8 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -38,7 +38,6 @@ #include "gadget_chips.h" #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "f_midi.c" diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index effda2e0742b..917c6eda916a 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -35,7 +35,6 @@ */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "f_hid.c" diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index a7f32c312a6b..9675e61c9a8d 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -49,7 +49,6 @@ */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "f_mass_storage.c" diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 71c1fabdbb78..6b6c12802afc 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -44,7 +44,6 @@ MODULE_LICENSE("GPL"); */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "f_mass_storage.c" diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index d7e6b1ee8664..ce8d08e44602 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -37,7 +37,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "f_ncm.c" diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index 474c77ca58c0..e2f4b9bdebc3 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -39,7 +39,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "u_serial.c" diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index c55e7d99b810..310b22d423a7 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -52,7 +52,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "config.c" #include "epautoconf.c" /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 88baa9e3f827..39990bed0905 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -38,7 +38,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "f_acm.c" diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 327af6883715..926e0facfba5 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -26,7 +26,6 @@ #include #include "epautoconf.c" -#include "config.c" #include "composite.c" #include "tcm_usb_gadget.h" diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index dc8fd5cc4f92..5e500e8403fd 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -24,7 +24,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "uvc_queue.c" diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 4469be8fcee3..e39a3b5da101 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -59,7 +59,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "config.c" #include "epautoconf.c" #include "f_sourcesink.c" -- cgit v1.2.3-59-g8ed1b From e87bb7118c4f752de4616a7ab56c51ed3e7f6f53 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:11 +0200 Subject: usb: gadget: move global vars from epautoconf into struct usb_gadget epautoconf has two global variables which count the endpoint number of last assigned endpoint. This patch removes the global variable and keeps it as per (UDC) gadget. While here, the ifdef is removed and now the in and outpoint are enumerated unconditionally. The dwc3 for instance supports 32 endpoints in total. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/epautoconf.c | 27 ++++++--------------------- include/linux/usb/gadget.h | 4 ++++ 2 files changed, 10 insertions(+), 21 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 51f3d42f5a64..d5a905dbed00 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -22,17 +22,6 @@ #include "gadget_chips.h" - -/* we must assign addresses for configurable endpoints (like net2280) */ -static unsigned epnum; - -// #define MANY_ENDPOINTS -#ifdef MANY_ENDPOINTS -/* more than 15 configurable endpoints */ -static unsigned in_epnum; -#endif - - /* * This should work with endpoints from controller drivers sharing the * same endpoint naming convention. By example: @@ -176,16 +165,14 @@ ep_matches ( if (isdigit (ep->name [2])) { u8 num = simple_strtoul (&ep->name [2], NULL, 10); desc->bEndpointAddress |= num; -#ifdef MANY_ENDPOINTS } else if (desc->bEndpointAddress & USB_DIR_IN) { - if (++in_epnum > 15) + if (++gadget->in_epnum > 15) return 0; - desc->bEndpointAddress = USB_DIR_IN | in_epnum; -#endif + desc->bEndpointAddress = USB_DIR_IN | gadget->in_epnum; } else { - if (++epnum > 15) + if (++gadget->out_epnum > 15) return 0; - desc->bEndpointAddress |= epnum; + desc->bEndpointAddress |= gadget->out_epnum; } /* report (variable) full speed bulk maxpacket */ @@ -385,9 +372,7 @@ void usb_ep_autoconfig_reset (struct usb_gadget *gadget) list_for_each_entry (ep, &gadget->ep_list, ep_list) { ep->driver_data = NULL; } -#ifdef MANY_ENDPOINTS - in_epnum = 0; -#endif - epnum = 0; + gadget->in_epnum = 0; + gadget->out_epnum = 0; } diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 822c1b88f95a..5b6e50888248 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -503,6 +503,8 @@ struct usb_gadget_ops { * @name: Identifies the controller hardware type. Used in diagnostics * and sometimes configuration. * @dev: Driver model state for this abstract device. + * @out_epnum: last used out ep number + * @in_epnum: last used in ep number * * Gadgets have a mostly-portable "gadget driver" implementing device * functions, handling all usb configurations and interfaces. Gadget @@ -537,6 +539,8 @@ struct usb_gadget { unsigned a_alt_hnp_support:1; const char *name; struct device dev; + unsigned out_epnum; + unsigned in_epnum; }; static inline void set_gadget_data(struct usb_gadget *gadget, void *data) -- cgit v1.2.3-59-g8ed1b From dc995fc27c2e1c8edebfb2405ede23bd38153f7f Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:12 +0200 Subject: usb: gadget: libcomposite: add epautoconf.c to libcomposite This patch adds epautoconf.c into libcomposite and updates all gadgets. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Makefile | 2 +- drivers/usb/gadget/acm_ms.c | 1 - drivers/usb/gadget/audio.c | 2 +- drivers/usb/gadget/cdc2.c | 1 - drivers/usb/gadget/dbgp.c | 3 --- drivers/usb/gadget/epautoconf.c | 6 ++++-- drivers/usb/gadget/ether.c | 1 - drivers/usb/gadget/file_storage.c | 13 ------------- drivers/usb/gadget/g_ffs.c | 1 - drivers/usb/gadget/gadget_chips.h | 2 ++ drivers/usb/gadget/gmidi.c | 1 - drivers/usb/gadget/hid.c | 2 +- drivers/usb/gadget/mass_storage.c | 1 - drivers/usb/gadget/multi.c | 1 - drivers/usb/gadget/ncm.c | 1 - drivers/usb/gadget/nokia.c | 1 - drivers/usb/gadget/printer.c | 1 - drivers/usb/gadget/serial.c | 1 - drivers/usb/gadget/tcm_usb_gadget.c | 1 - drivers/usb/gadget/webcam.c | 1 - drivers/usb/gadget/zero.c | 1 - 21 files changed, 9 insertions(+), 35 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 9515ed0163b7..23d705f194ac 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -5,7 +5,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG obj-$(CONFIG_USB_GADGET) += udc-core.o obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o -libcomposite-y := usbstring.o config.o +libcomposite-y := usbstring.o config.o epautoconf.o obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2272) += net2272.o obj-$(CONFIG_USB_NET2280) += net2280.o diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 3078d797f634..5db661d8590b 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -42,7 +42,6 @@ */ #include "composite.c" -#include "epautoconf.c" #include "u_serial.c" #include "f_acm.c" #include "f_mass_storage.c" diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 9e85df22e796..689d1422a1c0 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -14,6 +14,7 @@ #include #include +#include "gadget_chips.h" #define DRIVER_DESC "Linux USB Audio Gadget" #define DRIVER_VERSION "Feb 2, 2012" @@ -27,7 +28,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "epautoconf.c" /* string IDs are assigned dynamically */ diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index d06d0791c70e..8e386cf377a5 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -44,7 +44,6 @@ */ #include "composite.c" -#include "epautoconf.c" #include "u_serial.c" #include "f_acm.c" #include "f_ecm.c" diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index cc1746597aab..87d165028162 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c @@ -13,9 +13,6 @@ #include #include -/* See comments in "zero.c" */ -#include "epautoconf.c" - #ifdef CONFIG_USB_G_DBGP_SERIAL #include "u_serial.c" #endif diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index d5a905dbed00..a777f7bd11b4 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -315,6 +316,7 @@ found_ep: ep->comp_desc = NULL; return ep; } +EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss); /** * usb_ep_autoconfig() - choose an endpoint matching the @@ -354,7 +356,7 @@ struct usb_ep *usb_ep_autoconfig( { return usb_ep_autoconfig_ss(gadget, desc, NULL); } - +EXPORT_SYMBOL_GPL(usb_ep_autoconfig); /** * usb_ep_autoconfig_reset - reset endpoint autoconfig state @@ -375,4 +377,4 @@ void usb_ep_autoconfig_reset (struct usb_gadget *gadget) gadget->in_epnum = 0; gadget->out_epnum = 0; } - +EXPORT_SYMBOL_GPL(usb_ep_autoconfig_reset); diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 557021e267ee..39eb718f796a 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -103,7 +103,6 @@ static inline bool has_rndis(void) * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "epautoconf.c" #include "f_ecm.c" #include "f_subset.c" diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 77cf1083099f..ce362f7e39d3 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -256,19 +256,6 @@ #include "gadget_chips.h" - - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "epautoconf.c" - -/*-------------------------------------------------------------------------*/ - #define DRIVER_DESC "File-backed Storage Gadget" #define DRIVER_NAME "g_file_storage" #define DRIVER_VERSION "1 September 2010" diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 240957048d3f..c3a583ea9938 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -24,7 +24,6 @@ */ #include "composite.c" -#include "epautoconf.c" #if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS # if defined USB_ETH_RNDIS diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 0ccca58e7a8f..ba4e302e77d7 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -15,6 +15,8 @@ #ifndef __GADGET_CHIPS_H #define __GADGET_CHIPS_H +#include + /* * NOTICE: the entries below are alphabetical and should be kept * that way. diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 68a79b42c5a8..0c70708ef80f 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -38,7 +38,6 @@ #include "gadget_chips.h" #include "composite.c" -#include "epautoconf.c" #include "f_midi.c" /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 917c6eda916a..4880cdd9de43 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -16,6 +16,7 @@ #include #include +#include "gadget_chips.h" #define DRIVER_DESC "HID Gadget" #define DRIVER_VERSION "2010/03/16" @@ -35,7 +36,6 @@ */ #include "composite.c" -#include "epautoconf.c" #include "f_hid.c" diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 9675e61c9a8d..0b0f008427ed 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -49,7 +49,6 @@ */ #include "composite.c" -#include "epautoconf.c" #include "f_mass_storage.c" /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 6b6c12802afc..72fb30141ff4 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -44,7 +44,6 @@ MODULE_LICENSE("GPL"); */ #include "composite.c" -#include "epautoconf.c" #include "f_mass_storage.c" diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index ce8d08e44602..69b660b79c09 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -37,7 +37,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "epautoconf.c" #include "f_ncm.c" #include "u_ether.c" diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index e2f4b9bdebc3..6834c6204df3 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -39,7 +39,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "epautoconf.c" #include "u_serial.c" #include "f_acm.c" diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 310b22d423a7..3d3d20d258f6 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -52,7 +52,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "epautoconf.c" /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 39990bed0905..098c3d03dedd 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -38,7 +38,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "epautoconf.c" #include "f_acm.c" #include "f_obex.c" diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 926e0facfba5..e64a759f100d 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -25,7 +25,6 @@ #include #include -#include "epautoconf.c" #include "composite.c" #include "tcm_usb_gadget.h" diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index 5e500e8403fd..66dfca86b215 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -24,7 +24,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "epautoconf.c" #include "uvc_queue.c" #include "uvc_video.c" diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index e39a3b5da101..9a9adee2911a 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -59,7 +59,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" -#include "epautoconf.c" #include "f_sourcesink.c" #include "f_loopback.c" -- cgit v1.2.3-59-g8ed1b From e13f17ff8854e04cfc6b9f981a974f55d8da9b92 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 15:01:51 +0200 Subject: usb: gadget: move USB_BUFSIZ into global composite.h This patch moves USB_BUFSIZ into global header file as USB_COMP_EP0_BUFSIZ. There is currently only one user (f_sourcesink) besides composite which need it. Ideally f_sourcesink would have its own ep0 buffer. Lets keep it that way it was for now. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 10 ++++------ drivers/usb/gadget/f_sourcesink.c | 2 +- include/linux/usb/composite.h | 3 +++ 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 0b6ee2012af1..52689ee9db12 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -28,9 +28,6 @@ * with the relevant device-wide data. */ -/* big enough to hold our biggest descriptor */ -#define USB_BUFSIZ 1024 - /* Some systems will need runtime overrides for the product identifiers * published in the device descriptor, either numbers or strings or both. * String parameters are in UTF-8 (superset of ASCII's 7 bit characters). @@ -355,10 +352,11 @@ static int config_buf(struct usb_configuration *config, { struct usb_config_descriptor *c = buf; void *next = buf + USB_DT_CONFIG_SIZE; - int len = USB_BUFSIZ - USB_DT_CONFIG_SIZE; + int len; struct usb_function *f; int status; + len = USB_COMP_EP0_BUFSIZ - USB_DT_CONFIG_SIZE; /* write the config descriptor */ c = buf; c->bLength = USB_DT_CONFIG_SIZE; @@ -1445,13 +1443,13 @@ static int composite_bind(struct usb_gadget *gadget, cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); if (!cdev->req) goto fail; - cdev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL); + cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); if (!cdev->req->buf) goto fail; cdev->req->complete = composite_setup_complete; gadget->ep0->driver_data = cdev; - cdev->bufsiz = USB_BUFSIZ; + cdev->bufsiz = USB_COMP_EP0_BUFSIZ; cdev->driver = composite; /* diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index 5c1b68b63c98..3c126fde6e7e 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c @@ -795,7 +795,7 @@ static int sourcesink_setup(struct usb_configuration *c, u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_length = le16_to_cpu(ctrl->wLength); - req->length = USB_BUFSIZ; + req->length = USB_COMP_EP0_BUFSIZ; /* composite driver infrastructure handles everything except * the two control test requests. diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 43d6b9ca51b7..89d91b671eb0 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -46,6 +46,9 @@ */ #define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */ +/* big enough to hold our biggest descriptor */ +#define USB_COMP_EP0_BUFSIZ 1024 + struct usb_configuration; /** -- cgit v1.2.3-59-g8ed1b From 40bfef0535e8a10486c9d81fd2f55e3b9dc71db6 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 15:01:52 +0200 Subject: usb: gadget: remove bufsiz from struct usb_composite_dev there is no read user of bufsiz, its content is available via USB_COMP_EP0_BUFSIZ. Remove it. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 1 - include/linux/usb/composite.h | 2 -- 2 files changed, 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 52689ee9db12..16b353fa160a 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1449,7 +1449,6 @@ static int composite_bind(struct usb_gadget *gadget, cdev->req->complete = composite_setup_complete; gadget->ep0->driver_data = cdev; - cdev->bufsiz = USB_COMP_EP0_BUFSIZ; cdev->driver = composite; /* diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 89d91b671eb0..e970fba6dbbb 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -318,7 +318,6 @@ extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); * struct usb_composite_device - represents one composite usb gadget * @gadget: read-only, abstracts the gadget's usb peripheral controller * @req: used for control responses; buffer is pre-allocated - * @bufsiz: size of buffer pre-allocated in @req * @config: the currently active configuration * * One of these devices is allocated and initialized before the @@ -349,7 +348,6 @@ extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); struct usb_composite_dev { struct usb_gadget *gadget; struct usb_request *req; - unsigned bufsiz; struct usb_configuration *config; -- cgit v1.2.3-59-g8ed1b From 72258493ec4f77a772d05a8df5ee663e1e24154b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:15 +0200 Subject: usb: gadget: make composite module options readonly only This is a partly revert of 4fffd6e5 ("usb: gadget: composite: make module parameters accessible at runtime"). It is not possible to change the VID or other property for a gadget right now. This change has been made for Anrdoid gadget which has this functionality in its copy of the file. This function is executed currently only once and most caller in tree are __init. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 16b353fa160a..8d81a5ccfa03 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -34,27 +34,27 @@ */ static ushort idVendor; -module_param(idVendor, ushort, 0644); +module_param(idVendor, ushort, S_IRUGO); MODULE_PARM_DESC(idVendor, "USB Vendor ID"); static ushort idProduct; -module_param(idProduct, ushort, 0644); +module_param(idProduct, ushort, S_IRUGO); MODULE_PARM_DESC(idProduct, "USB Product ID"); static ushort bcdDevice; -module_param(bcdDevice, ushort, 0644); +module_param(bcdDevice, ushort, S_IRUGO); MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); static char *iManufacturer; -module_param(iManufacturer, charp, 0644); +module_param(iManufacturer, charp, S_IRUGO); MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); static char *iProduct; -module_param(iProduct, charp, 0644); +module_param(iProduct, charp, S_IRUGO); MODULE_PARM_DESC(iProduct, "USB Product string"); static char *iSerialNumber; -module_param(iSerialNumber, charp, 0644); +module_param(iSerialNumber, charp, S_IRUGO); MODULE_PARM_DESC(iSerialNumber, "SerialNumber string"); static char composite_manufacturer[50]; @@ -1478,16 +1478,12 @@ static int composite_bind(struct usb_gadget *gadget, /* standardized runtime overrides for device ID data */ if (idVendor) cdev->desc.idVendor = cpu_to_le16(idVendor); - else - idVendor = le16_to_cpu(cdev->desc.idVendor); + if (idProduct) cdev->desc.idProduct = cpu_to_le16(idProduct); - else - idProduct = le16_to_cpu(cdev->desc.idProduct); + if (bcdDevice) cdev->desc.bcdDevice = cpu_to_le16(bcdDevice); - else - bcdDevice = le16_to_cpu(cdev->desc.bcdDevice); /* string overrides */ if (iManufacturer || !cdev->desc.iManufacturer) { -- cgit v1.2.3-59-g8ed1b From e1f15ccbae40b55a4e2591373ea5f1808cf29855 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:16 +0200 Subject: usb: gadget: use usb_string_ids_tab instead multiple usb_string_id() Using usb_string_ids_tab() instead multiple calls of usb_string_id() seems to be handy. It also allows to add string without many checks. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/acm_ms.c | 12 +++--------- drivers/usb/gadget/audio.c | 12 +++--------- drivers/usb/gadget/cdc2.c | 12 +++--------- drivers/usb/gadget/ether.c | 12 +++--------- drivers/usb/gadget/gmidi.c | 21 ++++----------------- drivers/usb/gadget/hid.c | 11 +++-------- drivers/usb/gadget/ncm.c | 12 +++--------- drivers/usb/gadget/nokia.c | 22 ++++------------------ drivers/usb/gadget/serial.c | 22 ++++------------------ drivers/usb/gadget/webcam.c | 21 ++++++++------------- drivers/usb/gadget/zero.c | 26 ++++++++------------------ 11 files changed, 46 insertions(+), 137 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 5db661d8590b..ea349bab7f15 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -192,17 +192,11 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); - status = usb_string_id(cdev); + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail1; - strings_dev[STRING_MANUFACTURER_IDX].id = status; - device_desc.iManufacturer = status; - - status = usb_string_id(cdev); - if (status < 0) - goto fail1; - strings_dev[STRING_PRODUCT_IDX].id = status; - device_desc.iProduct = status; + device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; /* register our configuration */ status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config); diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 689d1422a1c0..5702ce3777fb 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -165,17 +165,11 @@ static int __init audio_bind(struct usb_composite_dev *cdev) snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, cdev->gadget->name); - status = usb_string_id(cdev); + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; - strings_dev[STRING_MANUFACTURER_IDX].id = status; - device_desc.iManufacturer = status; - - status = usb_string_id(cdev); - if (status < 0) - goto fail; - strings_dev[STRING_PRODUCT_IDX].id = status; - device_desc.iProduct = status; + device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; status = usb_add_config(cdev, &audio_config_driver, audio_do_config); if (status < 0) diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 8e386cf377a5..3b89fe2bd0b8 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -193,17 +193,11 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); - status = usb_string_id(cdev); + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail1; - strings_dev[STRING_MANUFACTURER_IDX].id = status; - device_desc.iManufacturer = status; - - status = usb_string_id(cdev); - if (status < 0) - goto fail1; - strings_dev[STRING_PRODUCT_IDX].id = status; - device_desc.iProduct = status; + device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; /* register our configuration */ status = usb_add_config(cdev, &cdc_config_driver, cdc_do_config); diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 39eb718f796a..004c6ed79e3b 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -345,17 +345,11 @@ static int __init eth_bind(struct usb_composite_dev *cdev) snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); - status = usb_string_id(cdev); + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; - strings_dev[STRING_MANUFACTURER_IDX].id = status; - device_desc.iManufacturer = status; - - status = usb_string_id(cdev); - if (status < 0) - goto fail; - strings_dev[STRING_PRODUCT_IDX].id = status; - device_desc.iProduct = status; + device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; /* register our configuration(s); RNDIS first, if it's used */ if (has_rndis()) { diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 0c70708ef80f..68f8c032ba6b 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -140,25 +140,12 @@ static int __init midi_bind(struct usb_composite_dev *cdev) struct usb_gadget *gadget = cdev->gadget; int gcnum, status; - status = usb_string_id(cdev); + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) return status; - strings_dev[STRING_MANUFACTURER_IDX].id = status; - device_desc.iManufacturer = status; - - status = usb_string_id(cdev); - if (status < 0) - return status; - strings_dev[STRING_PRODUCT_IDX].id = status; - device_desc.iProduct = status; - - /* config description */ - status = usb_string_id(cdev); - if (status < 0) - return status; - strings_dev[STRING_DESCRIPTION_IDX].id = status; - - midi_config.iConfiguration = status; + device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + midi_config.iConfiguration = strings_dev[STRING_DESCRIPTION_IDX].id; gcnum = usb_gadget_controller_number(gadget); if (gcnum < 0) { diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 4880cdd9de43..1e3f03be94df 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -176,17 +176,12 @@ static int __init hid_bind(struct usb_composite_dev *cdev) snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); - status = usb_string_id(cdev); - if (status < 0) - return status; - strings_dev[STRING_MANUFACTURER_IDX].id = status; - device_desc.iManufacturer = status; - status = usb_string_id(cdev); + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) return status; - strings_dev[STRING_PRODUCT_IDX].id = status; - device_desc.iProduct = status; + device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; /* register our configuration */ status = usb_add_config(cdev, &config_driver, do_config); diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index 69b660b79c09..6c7e15984535 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -180,17 +180,11 @@ static int __init gncm_bind(struct usb_composite_dev *cdev) snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); - status = usb_string_id(cdev); + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; - strings_dev[STRING_MANUFACTURER_IDX].id = status; - device_desc.iManufacturer = status; - - status = usb_string_id(cdev); - if (status < 0) - goto fail; - strings_dev[STRING_PRODUCT_IDX].id = status; - device_desc.iProduct = status; + device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; status = usb_add_config(cdev, &ncm_config_driver, ncm_do_config); diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index 6834c6204df3..b0893136a05d 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -164,26 +164,12 @@ static int __init nokia_bind(struct usb_composite_dev *cdev) if (status < 0) goto err_ether; - status = usb_string_id(cdev); + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto err_usb; - strings_dev[STRING_MANUFACTURER_IDX].id = status; - - device_desc.iManufacturer = status; - - status = usb_string_id(cdev); - if (status < 0) - goto err_usb; - strings_dev[STRING_PRODUCT_IDX].id = status; - - device_desc.iProduct = status; - - /* config description */ - status = usb_string_id(cdev); - if (status < 0) - goto err_usb; - strings_dev[STRING_DESCRIPTION_IDX].id = status; - + device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + status = strings_dev[STRING_DESCRIPTION_IDX].id; nokia_config_500ma_driver.iConfiguration = status; nokia_config_100ma_driver.iConfiguration = status; diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 098c3d03dedd..9962504e14f1 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -175,26 +175,12 @@ static int __init gs_bind(struct usb_composite_dev *cdev) snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); - status = usb_string_id(cdev); + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; - strings_dev[STRING_MANUFACTURER_IDX].id = status; - - device_desc.iManufacturer = status; - - status = usb_string_id(cdev); - if (status < 0) - goto fail; - strings_dev[STRING_PRODUCT_IDX].id = status; - - device_desc.iProduct = status; - - /* config description */ - status = usb_string_id(cdev); - if (status < 0) - goto fail; - strings_dev[STRING_DESCRIPTION_IDX].id = status; - + device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + status = strings_dev[STRING_DESCRIPTION_IDX].id; serial_config_driver.iConfiguration = status; /* set up other descriptors */ diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index 66dfca86b215..d44a4510a65a 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -355,20 +355,15 @@ webcam_bind(struct usb_composite_dev *cdev) /* Allocate string descriptor numbers ... note that string contents * can be overridden by the composite_dev glue. */ - if ((ret = usb_string_id(cdev)) < 0) + ret = usb_string_ids_tab(cdev, webcam_strings); + if (ret < 0) goto error; - webcam_strings[STRING_MANUFACTURER_IDX].id = ret; - webcam_device_descriptor.iManufacturer = ret; - - if ((ret = usb_string_id(cdev)) < 0) - goto error; - webcam_strings[STRING_PRODUCT_IDX].id = ret; - webcam_device_descriptor.iProduct = ret; - - if ((ret = usb_string_id(cdev)) < 0) - goto error; - webcam_strings[STRING_DESCRIPTION_IDX].id = ret; - webcam_config_driver.iConfiguration = ret; + webcam_device_descriptor.iManufacturer = + webcam_strings[STRING_MANUFACTURER_IDX].id; + webcam_device_descriptor.iProduct = + webcam_strings[STRING_PRODUCT_IDX].id; + webcam_config_driver.iConfiguration = + webcam_strings[STRING_DESCRIPTION_IDX].id; /* Register our configuration. */ if ((ret = usb_add_config(cdev, &webcam_config_driver, diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 9a9adee2911a..dbc336e3ba98 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -264,28 +264,18 @@ static int __init zero_bind(struct usb_composite_dev *cdev) { int gcnum; struct usb_gadget *gadget = cdev->gadget; - int id; + int status; /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_dev[STRING_MANUFACTURER_IDX].id = id; - device_desc.iManufacturer = id; - - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_dev[STRING_PRODUCT_IDX].id = id; - device_desc.iProduct = id; - - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_dev[STRING_SERIAL_IDX].id = id; - device_desc.iSerialNumber = id; + status = usb_string_ids_tab(cdev, strings_dev); + if (status < 0) + return status; + + device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + device_desc.iSerialNumber = strings_dev[STRING_SERIAL_IDX].id; setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); -- cgit v1.2.3-59-g8ed1b From 5a175bb84d7344fbe5e26cf61b597129e7c80564 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:17 +0200 Subject: usb: gadget: make g_printer enumerate again This was broken in 2e87edf49 ("usb: gadget: make g_printer use composite"). The USB-strings were not setup properly and were not used. No function was added which results in an empty USB config. While fixing this, the interface number is now auto generated and not hard coded to 0. Cc: stable@vger.kernel.org # v3.5 Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/printer.c | 128 ++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 63 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 3d3d20d258f6..51b6e7bf413e 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -138,18 +138,14 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR); * descriptors are built on demand. */ -#define STRING_MANUFACTURER 1 -#define STRING_PRODUCT 2 -#define STRING_SERIALNUM 3 +#define STRING_MANUFACTURER 0 +#define STRING_PRODUCT 1 +#define STRING_SERIALNUM 2 /* holds our biggest descriptor */ #define USB_DESC_BUFSIZE 256 #define USB_BUFSIZE 8192 -/* This device advertises one configuration. */ -#define DEV_CONFIG_VALUE 1 -#define PRINTER_INTERFACE 0 - static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, @@ -159,16 +155,12 @@ static struct usb_device_descriptor device_desc = { .bDeviceProtocol = 0, .idVendor = cpu_to_le16(PRINTER_VENDOR_NUM), .idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM), - .iManufacturer = STRING_MANUFACTURER, - .iProduct = STRING_PRODUCT, - .iSerialNumber = STRING_SERIALNUM, .bNumConfigurations = 1 }; static struct usb_interface_descriptor intf_desc = { .bLength = sizeof intf_desc, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = PRINTER_INTERFACE, .bNumEndpoints = 2, .bInterfaceClass = USB_CLASS_PRINTER, .bInterfaceSubClass = 1, /* Printer Sub-Class */ @@ -257,9 +249,9 @@ static char pnp_string [1024] = /* static strings, in UTF-8 */ static struct usb_string strings [] = { - { STRING_MANUFACTURER, manufacturer, }, - { STRING_PRODUCT, product_desc, }, - { STRING_SERIALNUM, serial_num, }, + [STRING_MANUFACTURER].s = manufacturer, + [STRING_PRODUCT].s = product_desc, + [STRING_SERIALNUM].s = serial_num, { } /* end of list */ }; @@ -868,25 +860,13 @@ static int set_interface(struct printer_dev *dev, unsigned number) int result = 0; /* Free the current interface */ - switch (dev->interface) { - case PRINTER_INTERFACE: - printer_reset_interface(dev); - break; - } + printer_reset_interface(dev); - switch (number) { - case PRINTER_INTERFACE: - result = set_printer_interface(dev); - if (result) { - printer_reset_interface(dev); - } else { - dev->interface = PRINTER_INTERFACE; - } - break; - default: - result = -EINVAL; - /* FALL THROUGH */ - } + result = set_printer_interface(dev); + if (result) + printer_reset_interface(dev); + else + dev->interface = number; if (!result) INFO(dev, "Using interface %x\n", number); @@ -969,7 +949,7 @@ static int printer_func_setup(struct usb_function *f, switch (ctrl->bRequest) { case 0: /* Get the IEEE-1284 PNP String */ /* Only one printer interface is supported. */ - if ((wIndex>>8) != PRINTER_INTERFACE) + if ((wIndex>>8) != dev->interface) break; value = (pnp_string[0]<<8)|pnp_string[1]; @@ -980,7 +960,7 @@ static int printer_func_setup(struct usb_function *f, case 1: /* Get Port Status */ /* Only one printer interface is supported. */ - if (wIndex != PRINTER_INTERFACE) + if (wIndex != dev->interface) break; *(u8 *)req->buf = dev->printer_status; @@ -989,7 +969,7 @@ static int printer_func_setup(struct usb_function *f, case 2: /* Soft Reset */ /* Only one printer interface is supported. */ - if (wIndex != PRINTER_INTERFACE) + if (wIndex != dev->interface) break; printer_soft_reset(dev); @@ -1017,6 +997,37 @@ unknown: static int __init printer_func_bind(struct usb_configuration *c, struct usb_function *f) { + struct printer_dev *dev = container_of(f, struct printer_dev, function); + struct usb_composite_dev *cdev = c->cdev; + struct usb_ep *in_ep, *out_ep; + int id; + + id = usb_interface_id(c, f); + if (id < 0) + return id; + intf_desc.bInterfaceNumber = id; + + /* all we really need is bulk IN/OUT */ + in_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_in_desc); + if (!in_ep) { +autoconf_fail: + dev_err(&cdev->gadget->dev, "can't autoconfigure on %s\n", + cdev->gadget->name); + return -ENODEV; + } + in_ep->driver_data = in_ep; /* claim */ + + out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc); + if (!out_ep) + goto autoconf_fail; + out_ep->driver_data = out_ep; /* claim */ + + /* assumes that all endpoints are dual-speed */ + hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; + hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; + + dev->in_ep = in_ep; + dev->out_ep = out_ep; return 0; } @@ -1032,7 +1043,8 @@ static int printer_func_set_alt(struct usb_function *f, int ret = -ENOTSUPP; if (!alt) - ret = set_interface(dev, PRINTER_INTERFACE); + ret = set_interface(dev, intf); + return ret; } @@ -1104,13 +1116,14 @@ static int __init printer_bind_config(struct usb_configuration *c) { struct usb_gadget *gadget = c->cdev->gadget; struct printer_dev *dev; - struct usb_ep *in_ep, *out_ep; int status = -ENOMEM; int gcnum; size_t len; u32 i; struct usb_request *req; + usb_ep_autoconfig_reset(gadget); + dev = &usb_printer_gadget; dev->function.name = shortname; @@ -1122,6 +1135,10 @@ static int __init printer_bind_config(struct usb_configuration *c) dev->function.set_alt = printer_func_set_alt; dev->function.disable = printer_func_disable; + status = usb_add_function(c, &dev->function); + if (status) + return status; + /* Setup the sysfs files for the printer gadget. */ dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno, NULL, "g_printer"); @@ -1166,26 +1183,6 @@ static int __init printer_bind_config(struct usb_configuration *c) pnp_string[0] = (len >> 8) & 0xFF; pnp_string[1] = len & 0xFF; - /* all we really need is bulk IN/OUT */ - usb_ep_autoconfig_reset(gadget); - in_ep = usb_ep_autoconfig(gadget, &fs_ep_in_desc); - if (!in_ep) { -autoconf_fail: - dev_err(&gadget->dev, "can't autoconfigure on %s\n", - gadget->name); - return -ENODEV; - } - in_ep->driver_data = in_ep; /* claim */ - - out_ep = usb_ep_autoconfig(gadget, &fs_ep_out_desc); - if (!out_ep) - goto autoconf_fail; - out_ep->driver_data = out_ep; /* claim */ - - /* assumes that all endpoints are dual-speed */ - hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; - hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; - usb_gadget_set_selfpowered(gadget); if (gadget->is_otg) { @@ -1212,9 +1209,6 @@ autoconf_fail: dev->current_rx_bytes = 0; dev->current_rx_buf = NULL; - dev->in_ep = in_ep; - dev->out_ep = out_ep; - for (i = 0; i < QLEN; i++) { req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL); if (!req) { @@ -1247,8 +1241,6 @@ autoconf_fail: dev->gadget = gadget; INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc); - INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, out_ep->name, - in_ep->name); return 0; fail: @@ -1263,7 +1255,17 @@ static int printer_unbind(struct usb_composite_dev *cdev) static int __init printer_bind(struct usb_composite_dev *cdev) { - return usb_add_config(cdev, &printer_cfg_driver, printer_bind_config); + int ret; + + ret = usb_string_ids_tab(cdev, strings); + if (ret < 0) + return ret; + device_desc.iManufacturer = strings[STRING_MANUFACTURER].id; + device_desc.iProduct = strings[STRING_PRODUCT].id; + device_desc.iSerialNumber = strings[STRING_SERIALNUM].id; + + ret = usb_add_config(cdev, &printer_cfg_driver, printer_bind_config); + return ret; } static __refdata struct usb_composite_driver printer_driver = { -- cgit v1.2.3-59-g8ed1b From 18786da4853017d983ff6911648543ca617c12d1 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:18 +0200 Subject: usb: gadget: initialize the strings in tcm_usb_gadget properly I have no idea what I've been thinking while I was doing this in the first place. Now the strings are initialized properly and reported by lsusb. Cc: stable@vger.kernel.org # v3.5 Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/tcm_usb_gadget.c | 33 ++++++++++++++++++++------------- drivers/usb/gadget/tcm_usb_gadget.h | 14 ++++++++------ 2 files changed, 28 insertions(+), 19 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index e64a759f100d..2f4980881a80 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -1974,7 +1974,6 @@ static struct usb_interface_descriptor bot_intf_desc = { .bInterfaceClass = USB_CLASS_MASS_STORAGE, .bInterfaceSubClass = USB_SC_SCSI, .bInterfaceProtocol = USB_PR_BULK, - .iInterface = USB_G_STR_INT_UAS, }; static struct usb_interface_descriptor uasp_intf_desc = { @@ -1985,7 +1984,6 @@ static struct usb_interface_descriptor uasp_intf_desc = { .bInterfaceClass = USB_CLASS_MASS_STORAGE, .bInterfaceSubClass = USB_SC_SCSI, .bInterfaceProtocol = USB_PR_UAS, - .iInterface = USB_G_STR_INT_BBB, }; static struct usb_endpoint_descriptor uasp_bi_desc = { @@ -2206,20 +2204,16 @@ static struct usb_device_descriptor usbg_device_desc = { .bDeviceClass = USB_CLASS_PER_INTERFACE, .idVendor = cpu_to_le16(UAS_VENDOR_ID), .idProduct = cpu_to_le16(UAS_PRODUCT_ID), - .iManufacturer = USB_G_STR_MANUFACTOR, - .iProduct = USB_G_STR_PRODUCT, - .iSerialNumber = USB_G_STR_SERIAL, - .bNumConfigurations = 1, }; static struct usb_string usbg_us_strings[] = { - { USB_G_STR_MANUFACTOR, "Target Manufactor"}, - { USB_G_STR_PRODUCT, "Target Product"}, - { USB_G_STR_SERIAL, "000000000001"}, - { USB_G_STR_CONFIG, "default config"}, - { USB_G_STR_INT_UAS, "USB Attached SCSI"}, - { USB_G_STR_INT_BBB, "Bulk Only Transport"}, + [USB_G_STR_MANUFACTOR].s = "Target Manufactor", + [USB_G_STR_PRODUCT].s = "Target Product", + [USB_G_STR_SERIAL].s = "000000000001", + [USB_G_STR_CONFIG].s = "default config", + [USB_G_STR_INT_UAS].s = "USB Attached SCSI", + [USB_G_STR_INT_BBB].s = "Bulk Only Transport", { }, }; @@ -2241,7 +2235,6 @@ static int guas_unbind(struct usb_composite_dev *cdev) static struct usb_configuration usbg_config_driver = { .label = "Linux Target", .bConfigurationValue = 1, - .iConfiguration = USB_G_STR_CONFIG, .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; @@ -2414,6 +2407,9 @@ static int usbg_cfg_bind(struct usb_configuration *c) fu->function.disable = usbg_disable; fu->tpg = the_only_tpg_I_currently_have; + bot_intf_desc.iInterface = usbg_us_strings[USB_G_STR_INT_BBB].id; + uasp_intf_desc.iInterface = usbg_us_strings[USB_G_STR_INT_UAS].id; + ret = usb_add_function(c, &fu->function); if (ret) goto err; @@ -2428,6 +2424,17 @@ static int usb_target_bind(struct usb_composite_dev *cdev) { int ret; + ret = usb_string_ids_tab(cdev, usbg_us_strings); + if (ret) + return ret; + + usbg_device_desc.iManufacturer = + usbg_us_strings[USB_G_STR_MANUFACTOR].id; + usbg_device_desc.iProduct = usbg_us_strings[USB_G_STR_PRODUCT].id; + usbg_device_desc.iSerialNumber = usbg_us_strings[USB_G_STR_SERIAL].id; + usbg_config_driver.iConfiguration = + usbg_us_strings[USB_G_STR_CONFIG].id; + ret = usb_add_config(cdev, &usbg_config_driver, usbg_cfg_bind); return 0; diff --git a/drivers/usb/gadget/tcm_usb_gadget.h b/drivers/usb/gadget/tcm_usb_gadget.h index bb18999a9a8d..9d32ec30f4e4 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.h +++ b/drivers/usb/gadget/tcm_usb_gadget.h @@ -16,12 +16,14 @@ #define UASP_SS_EP_COMP_LOG_STREAMS 4 #define UASP_SS_EP_COMP_NUM_STREAMS (1 << UASP_SS_EP_COMP_LOG_STREAMS) -#define USB_G_STR_MANUFACTOR 1 -#define USB_G_STR_PRODUCT 2 -#define USB_G_STR_SERIAL 3 -#define USB_G_STR_CONFIG 4 -#define USB_G_STR_INT_UAS 5 -#define USB_G_STR_INT_BBB 6 +enum { + USB_G_STR_MANUFACTOR, + USB_G_STR_PRODUCT, + USB_G_STR_SERIAL, + USB_G_STR_CONFIG, + USB_G_STR_INT_UAS, + USB_G_STR_INT_BBB, +}; #define USB_G_ALT_INT_BBB 0 #define USB_G_ALT_INT_UAS 1 -- cgit v1.2.3-59-g8ed1b From 3b4a3fc0ba83265c0bfcfdfc3416e65e47441747 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:19 +0200 Subject: usb: gadget: move usb_gadget_controller_number() into a .c file and libcomposite After I moved the function from the header file to the c file I see: | $ size drivers/usb/gadget/gadget_chips.o | text data bss dec hex filename | 1048 0 0 1048 418 drivers/usb/gadget/gadget_chips.o That is almost a KiB which is removed from each user. As Felipe pointed out, the function / usage is very dumb actually. This is used for the following reasons: - epautoconf ep hint (could provide a per-gadget callback) - miss-features. currently the missing altsetting on pxa's and something ZLP related on musbhdrc (looks like an optimisation which could be implemented in musb itself if it is correct) - unique BCD accross all UDCs. Not sure how important this is. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Makefile | 2 +- drivers/usb/gadget/gadget_chips.c | 94 +++++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/gadget_chips.h | 76 +------------------------------ 3 files changed, 96 insertions(+), 76 deletions(-) create mode 100644 drivers/usb/gadget/gadget_chips.c (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 23d705f194ac..4fec0e8ee000 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -5,7 +5,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG obj-$(CONFIG_USB_GADGET) += udc-core.o obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o -libcomposite-y := usbstring.o config.o epautoconf.o +libcomposite-y := usbstring.o config.o epautoconf.o gadget_chips.o obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2272) += net2272.o obj-$(CONFIG_USB_NET2280) += net2280.o diff --git a/drivers/usb/gadget/gadget_chips.c b/drivers/usb/gadget/gadget_chips.c new file mode 100644 index 000000000000..6387d43d3f8c --- /dev/null +++ b/drivers/usb/gadget/gadget_chips.c @@ -0,0 +1,94 @@ +/* + * USB device controllers have lots of quirks. Use these macros in + * gadget drivers or other code that needs to deal with them, and which + * autoconfigures instead of using early binding to the hardware. + * + * This SHOULD eventually work like the ARM mach_is_*() stuff, driven by + * some config file that gets updated as new hardware is supported. + * (And avoiding all runtime comparisons in typical one-choice configs!) + * + * NOTE: some of these controller drivers may not be available yet. + * Some are available on 2.4 kernels; several are available, but not + * yet pushed in the 2.6 mainline tree. + */ + +#include +#include + +#include "gadget_chips.h" + +/** + * usb_gadget_controller_number - support bcdDevice id convention + * @gadget: the controller being driven + * + * Return a 2-digit BCD value associated with the peripheral controller, + * suitable for use as part of a bcdDevice value, or a negative error code. + * + * NOTE: this convention is purely optional, and has no meaning in terms of + * any USB specification. If you want to use a different convention in your + * gadget driver firmware -- maybe a more formal revision ID -- feel free. + * + * Hosts see these bcdDevice numbers, and are allowed (but not encouraged!) + * to change their behavior accordingly. For example it might help avoiding + * some chip bug. + */ +int usb_gadget_controller_number(struct usb_gadget *gadget) +{ + if (gadget_is_net2280(gadget)) + return 0x01; + else if (gadget_is_dummy(gadget)) + return 0x02; + else if (gadget_is_pxa(gadget)) + return 0x03; + else if (gadget_is_goku(gadget)) + return 0x06; + else if (gadget_is_omap(gadget)) + return 0x08; + else if (gadget_is_pxa27x(gadget)) + return 0x11; + else if (gadget_is_s3c2410(gadget)) + return 0x12; + else if (gadget_is_at91(gadget)) + return 0x13; + else if (gadget_is_imx(gadget)) + return 0x14; + else if (gadget_is_musbhdrc(gadget)) + return 0x16; + else if (gadget_is_atmel_usba(gadget)) + return 0x18; + else if (gadget_is_fsl_usb2(gadget)) + return 0x19; + else if (gadget_is_amd5536udc(gadget)) + return 0x20; + else if (gadget_is_m66592(gadget)) + return 0x21; + else if (gadget_is_fsl_qe(gadget)) + return 0x22; + else if (gadget_is_ci13xxx_pci(gadget)) + return 0x23; + else if (gadget_is_langwell(gadget)) + return 0x24; + else if (gadget_is_r8a66597(gadget)) + return 0x25; + else if (gadget_is_s3c_hsotg(gadget)) + return 0x26; + else if (gadget_is_pch(gadget)) + return 0x27; + else if (gadget_is_ci13xxx_msm(gadget)) + return 0x28; + else if (gadget_is_renesas_usbhs(gadget)) + return 0x29; + else if (gadget_is_s3c_hsudc(gadget)) + return 0x30; + else if (gadget_is_net2272(gadget)) + return 0x31; + else if (gadget_is_dwc3(gadget)) + return 0x32; + else if (gadget_is_lpc32xx(gadget)) + return 0x33; + else if (gadget_is_bcm63xx(gadget)) + return 0x34; + + return -ENOENT; +} +EXPORT_SYMBOL_GPL(usb_gadget_controller_number); diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index ba4e302e77d7..c7055cd1e92e 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -55,81 +55,7 @@ #define gadget_is_s3c_hsotg(g) (!strcmp("s3c-hsotg", (g)->name)) #define gadget_is_s3c_hsudc(g) (!strcmp("s3c-hsudc", (g)->name)) -/** - * usb_gadget_controller_number - support bcdDevice id convention - * @gadget: the controller being driven - * - * Return a 2-digit BCD value associated with the peripheral controller, - * suitable for use as part of a bcdDevice value, or a negative error code. - * - * NOTE: this convention is purely optional, and has no meaning in terms of - * any USB specification. If you want to use a different convention in your - * gadget driver firmware -- maybe a more formal revision ID -- feel free. - * - * Hosts see these bcdDevice numbers, and are allowed (but not encouraged!) - * to change their behavior accordingly. For example it might help avoiding - * some chip bug. - */ -static inline int usb_gadget_controller_number(struct usb_gadget *gadget) -{ - if (gadget_is_net2280(gadget)) - return 0x01; - else if (gadget_is_dummy(gadget)) - return 0x02; - else if (gadget_is_pxa(gadget)) - return 0x03; - else if (gadget_is_goku(gadget)) - return 0x06; - else if (gadget_is_omap(gadget)) - return 0x08; - else if (gadget_is_pxa27x(gadget)) - return 0x11; - else if (gadget_is_s3c2410(gadget)) - return 0x12; - else if (gadget_is_at91(gadget)) - return 0x13; - else if (gadget_is_imx(gadget)) - return 0x14; - else if (gadget_is_musbhdrc(gadget)) - return 0x16; - else if (gadget_is_atmel_usba(gadget)) - return 0x18; - else if (gadget_is_fsl_usb2(gadget)) - return 0x19; - else if (gadget_is_amd5536udc(gadget)) - return 0x20; - else if (gadget_is_m66592(gadget)) - return 0x21; - else if (gadget_is_fsl_qe(gadget)) - return 0x22; - else if (gadget_is_ci13xxx_pci(gadget)) - return 0x23; - else if (gadget_is_langwell(gadget)) - return 0x24; - else if (gadget_is_r8a66597(gadget)) - return 0x25; - else if (gadget_is_s3c_hsotg(gadget)) - return 0x26; - else if (gadget_is_pch(gadget)) - return 0x27; - else if (gadget_is_ci13xxx_msm(gadget)) - return 0x28; - else if (gadget_is_renesas_usbhs(gadget)) - return 0x29; - else if (gadget_is_s3c_hsudc(gadget)) - return 0x30; - else if (gadget_is_net2272(gadget)) - return 0x31; - else if (gadget_is_dwc3(gadget)) - return 0x32; - else if (gadget_is_lpc32xx(gadget)) - return 0x33; - else if (gadget_is_bcm63xx(gadget)) - return 0x34; - - return -ENOENT; -} - +int usb_gadget_controller_number(struct usb_gadget *gadget); /** * gadget_supports_altsettings - return true if altsettings work -- cgit v1.2.3-59-g8ed1b From 7d16e8d3eb704f5f6eb5a271d5758b495634e8e6 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 15:01:53 +0200 Subject: usb: gadget: push VID/PID/USB BCD module option into gadgets This patch moves the module options idVendor, idProduct and bcdDevice from composite.c into each gadgets. This ensures compatibility with current gadgets and removes the global variable which brings me step closer towards composite.c in libcomposite Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/acm_ms.c | 2 ++ drivers/usb/gadget/audio.c | 3 ++ drivers/usb/gadget/cdc2.c | 2 ++ drivers/usb/gadget/composite.c | 63 +++++++++++++++++++++++-------------- drivers/usb/gadget/ether.c | 2 ++ drivers/usb/gadget/g_ffs.c | 4 ++- drivers/usb/gadget/gmidi.c | 4 ++- drivers/usb/gadget/hid.c | 2 ++ drivers/usb/gadget/mass_storage.c | 3 +- drivers/usb/gadget/multi.c | 3 +- drivers/usb/gadget/ncm.c | 2 ++ drivers/usb/gadget/nokia.c | 2 ++ drivers/usb/gadget/printer.c | 4 +++ drivers/usb/gadget/serial.c | 2 ++ drivers/usb/gadget/tcm_usb_gadget.c | 5 +++ drivers/usb/gadget/webcam.c | 2 ++ drivers/usb/gadget/zero.c | 2 ++ include/linux/usb/composite.h | 24 ++++++++++++++ 18 files changed, 103 insertions(+), 28 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index ea349bab7f15..7bd6b71af5d3 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -47,6 +47,7 @@ #include "f_mass_storage.c" /*-------------------------------------------------------------------------*/ +USB_GADGET_COMPOSITE_OPTIONS(); static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, @@ -203,6 +204,7 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) if (status < 0) goto fail1; + usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC); fsg_common_put(&fsg_common); diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 5702ce3777fb..55b593c5a9c8 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -13,6 +13,7 @@ #include #include +#include #include "gadget_chips.h" #define DRIVER_DESC "Linux USB Audio Gadget" @@ -28,6 +29,7 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "composite.c" +USB_GADGET_COMPOSITE_OPTIONS(); /* string IDs are assigned dynamically */ @@ -174,6 +176,7 @@ static int __init audio_bind(struct usb_composite_dev *cdev) status = usb_add_config(cdev, &audio_config_driver, audio_do_config); if (status < 0) goto fail; + usb_composite_overwrite_options(cdev, &coverwrite); INFO(cdev, "%s, version: %s\n", DRIVER_DESC, DRIVER_VERSION); return 0; diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 3b89fe2bd0b8..93a75809b4de 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -34,6 +34,7 @@ #define CDC_PRODUCT_NUM 0xa4aa /* CDC Composite: ECM + ACM */ /*-------------------------------------------------------------------------*/ +USB_GADGET_COMPOSITE_OPTIONS(); /* * Kbuild is not very cooperative with respect to linking separately @@ -204,6 +205,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) if (status < 0) goto fail1; + usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC); diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 8d81a5ccfa03..317a5ece3bd2 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -32,19 +32,6 @@ * published in the device descriptor, either numbers or strings or both. * String parameters are in UTF-8 (superset of ASCII's 7 bit characters). */ - -static ushort idVendor; -module_param(idVendor, ushort, S_IRUGO); -MODULE_PARM_DESC(idVendor, "USB Vendor ID"); - -static ushort idProduct; -module_param(idProduct, ushort, S_IRUGO); -MODULE_PARM_DESC(idProduct, "USB Product ID"); - -static ushort bcdDevice; -module_param(bcdDevice, ushort, S_IRUGO); -MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); - static char *iManufacturer; module_param(iManufacturer, charp, S_IRUGO); MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); @@ -1418,6 +1405,30 @@ static u8 override_id(struct usb_composite_dev *cdev, u8 *desc) return *desc; } +static void update_unchanged_dev_desc(struct usb_device_descriptor *new, + const struct usb_device_descriptor *old) +{ + __le16 idVendor; + __le16 idProduct; + __le16 bcdDevice; + + /* + * these variables may have been set in + * usb_composite_overwrite_options() + */ + idVendor = new->idVendor; + idProduct = new->idProduct; + bcdDevice = new->bcdDevice; + + *new = *old; + if (idVendor) + new->idVendor = idVendor; + if (idProduct) + new->idProduct = idProduct; + if (bcdDevice) + new->bcdDevice = bcdDevice; +} + static struct usb_composite_driver *to_cdriver(struct usb_gadget_driver *gdrv) { return container_of(gdrv, struct usb_composite_driver, gadget_driver); @@ -1473,17 +1484,7 @@ static int composite_bind(struct usb_gadget *gadget, if (status < 0) goto fail; - cdev->desc = *composite->dev; - - /* standardized runtime overrides for device ID data */ - if (idVendor) - cdev->desc.idVendor = cpu_to_le16(idVendor); - - if (idProduct) - cdev->desc.idProduct = cpu_to_le16(idProduct); - - if (bcdDevice) - cdev->desc.bcdDevice = cpu_to_le16(bcdDevice); + update_unchanged_dev_desc(&cdev->desc, composite->dev); /* string overrides */ if (iManufacturer || !cdev->desc.iManufacturer) { @@ -1686,3 +1687,17 @@ void usb_composite_setup_continue(struct usb_composite_dev *cdev) spin_unlock_irqrestore(&cdev->lock, flags); } +void usb_composite_overwrite_options(struct usb_composite_dev *cdev, + struct usb_composite_overwrite *covr) +{ + struct usb_device_descriptor *desc = &cdev->desc; + + if (covr->idVendor) + desc->idVendor = cpu_to_le16(covr->idVendor); + + if (covr->idProduct) + desc->idProduct = cpu_to_le16(covr->idProduct); + + if (covr->bcdDevice) + desc->bcdDevice = cpu_to_le16(covr->bcdDevice); +} diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 004c6ed79e3b..709ef2265596 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -114,6 +114,7 @@ static inline bool has_rndis(void) #include "u_ether.c" /*-------------------------------------------------------------------------*/ +USB_GADGET_COMPOSITE_OPTIONS(); /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! * Instead: allocate your own, using normal USB-IF procedures. @@ -363,6 +364,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev) if (status < 0) goto fail; + usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC); diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index c3a583ea9938..a44ed661c16b 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -73,6 +73,8 @@ struct gfs_ffs_obj { struct ffs_data *ffs_data; }; +USB_GADGET_COMPOSITE_OPTIONS(); + static struct usb_device_descriptor gfs_dev_desc = { .bLength = sizeof gfs_dev_desc, .bDescriptorType = USB_DT_DEVICE, @@ -377,7 +379,7 @@ static int gfs_bind(struct usb_composite_dev *cdev) if (unlikely(ret < 0)) goto error_unbind; } - + usb_composite_overwrite_options(cdev, &coverwrite); return 0; error_unbind: diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 68f8c032ba6b..01b31e2d03af 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -48,6 +48,8 @@ MODULE_LICENSE("GPL v2"); static const char shortname[] = "g_midi"; static const char longname[] = "MIDI Gadget"; +USB_GADGET_COMPOSITE_OPTIONS(); + static int index = SNDRV_DEFAULT_IDX1; module_param(index, int, S_IRUGO); MODULE_PARM_DESC(index, "Index value for the USB MIDI Gadget adapter."); @@ -163,7 +165,7 @@ static int __init midi_bind(struct usb_composite_dev *cdev) status = usb_add_config(cdev, &midi_config, midi_bind_config); if (status < 0) return status; - + usb_composite_overwrite_options(cdev, &coverwrite); pr_info("%s\n", longname); return 0; } diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 1e3f03be94df..59fe7eef00da 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -48,6 +48,7 @@ struct hidg_func_node { static LIST_HEAD(hidg_func_list); /*-------------------------------------------------------------------------*/ +USB_GADGET_COMPOSITE_OPTIONS(); static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, @@ -188,6 +189,7 @@ static int __init hid_bind(struct usb_composite_dev *cdev) if (status < 0) return status; + usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); return 0; diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 0b0f008427ed..8ffbade383f2 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -52,6 +52,7 @@ #include "f_mass_storage.c" /*-------------------------------------------------------------------------*/ +USB_GADGET_COMPOSITE_OPTIONS(); static struct usb_device_descriptor msg_device_desc = { .bLength = sizeof msg_device_desc, @@ -143,7 +144,7 @@ static int __init msg_bind(struct usb_composite_dev *cdev) status = usb_add_config(cdev, &msg_config_driver, msg_do_config); if (status < 0) return status; - + usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&cdev->gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); set_bit(0, &msg_registered); diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 72fb30141ff4..60168877330a 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -58,7 +58,7 @@ MODULE_LICENSE("GPL"); #endif #include "u_ether.c" - +USB_GADGET_COMPOSITE_OPTIONS(); /***************************** Device Descriptor ****************************/ @@ -307,6 +307,7 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) status = cdc_config_register(cdev); if (unlikely(status < 0)) goto fail2; + usb_composite_overwrite_options(cdev, &coverwrite); /* we're done */ dev_info(&gadget->dev, DRIVER_DESC "\n"); diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index 6c7e15984535..8537cd9c6aff 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -54,6 +54,7 @@ #define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */ /*-------------------------------------------------------------------------*/ +USB_GADGET_COMPOSITE_OPTIONS(); static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, @@ -191,6 +192,7 @@ static int __init gncm_bind(struct usb_composite_dev *cdev) if (status < 0) goto fail; + usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, "%s\n", DRIVER_DESC); return 0; diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index b0893136a05d..5ed927b16c0e 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -49,6 +49,7 @@ #include "u_ether.c" /*-------------------------------------------------------------------------*/ +USB_GADGET_COMPOSITE_OPTIONS(); #define NOKIA_VENDOR_ID 0x0421 /* Nokia */ #define NOKIA_PRODUCT_ID 0x01c8 /* Nokia Gadget */ @@ -197,6 +198,7 @@ static int __init nokia_bind(struct usb_composite_dev *cdev) if (status < 0) goto err_usb; + usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME); return 0; diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 51b6e7bf413e..3fa4d80629cc 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -54,6 +54,7 @@ #include "composite.c" /*-------------------------------------------------------------------------*/ +USB_GADGET_COMPOSITE_OPTIONS(); #define DRIVER_DESC "Printer Gadget" #define DRIVER_VERSION "2007 OCT 06" @@ -1265,6 +1266,9 @@ static int __init printer_bind(struct usb_composite_dev *cdev) device_desc.iSerialNumber = strings[STRING_SERIALNUM].id; ret = usb_add_config(cdev, &printer_cfg_driver, printer_bind_config); + if (ret) + return ret; + usb_composite_overwrite_options(cdev, &coverwrite); return ret; } diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 9962504e14f1..27b5ce939bdb 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -45,6 +45,7 @@ #include "u_serial.c" /*-------------------------------------------------------------------------*/ +USB_GADGET_COMPOSITE_OPTIONS(); /* Thanks to NetChip Technologies for donating this product ID. * @@ -212,6 +213,7 @@ static int __init gs_bind(struct usb_composite_dev *cdev) if (status < 0) goto fail; + usb_composite_overwrite_options(cdev, &coverwrite); INFO(cdev, "%s\n", GS_VERSION_NAME); return 0; diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 2f4980881a80..fa3137ef228b 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -29,6 +29,8 @@ #include "tcm_usb_gadget.h" +USB_GADGET_COMPOSITE_OPTIONS(); + static struct target_fabric_configfs *usbg_fabric_configfs; static inline struct f_uas *to_f_uas(struct usb_function *f) @@ -2437,6 +2439,9 @@ static int usb_target_bind(struct usb_composite_dev *cdev) ret = usb_add_config(cdev, &usbg_config_driver, usbg_cfg_bind); + if (ret) + return ret; + usb_composite_overwrite_options(cdev, &coverwrite); return 0; } diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index d44a4510a65a..306006419f38 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -30,6 +30,7 @@ #include "uvc_v4l2.c" #include "f_uvc.c" +USB_GADGET_COMPOSITE_OPTIONS(); /* -------------------------------------------------------------------------- * Device descriptor */ @@ -370,6 +371,7 @@ webcam_bind(struct usb_composite_dev *cdev) webcam_config_bind)) < 0) goto error; + usb_composite_overwrite_options(cdev, &coverwrite); INFO(cdev, "Webcam Video Gadget\n"); return 0; diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index dbc336e3ba98..2b31a4ae26b9 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -64,6 +64,7 @@ #include "f_loopback.c" /*-------------------------------------------------------------------------*/ +USB_GADGET_COMPOSITE_OPTIONS(); #define DRIVER_VERSION "Cinco de Mayo 2008" @@ -305,6 +306,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev) longname, gadget->name); device_desc.bcdDevice = cpu_to_le16(0x9999); } + usb_composite_overwrite_options(cdev, &coverwrite); INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname); diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index e970fba6dbbb..7651e5bf7487 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -381,6 +381,30 @@ extern int usb_string_ids_tab(struct usb_composite_dev *c, struct usb_string *str); extern int usb_string_ids_n(struct usb_composite_dev *c, unsigned n); +/* + * Some systems will need runtime overrides for the product identifiers + * published in the device descriptor, either numbers or strings or both. + * String parameters are in UTF-8 (superset of ASCII's 7 bit characters). + */ +struct usb_composite_overwrite { + u16 idVendor; + u16 idProduct; + u16 bcdDevice; +}; +#define USB_GADGET_COMPOSITE_OPTIONS() \ + static struct usb_composite_overwrite coverwrite; \ + \ + module_param_named(idVendor, coverwrite.idVendor, ushort, S_IRUGO); \ + MODULE_PARM_DESC(idVendor, "USB Vendor ID"); \ + \ + module_param_named(idProduct, coverwrite.idProduct, ushort, S_IRUGO); \ + MODULE_PARM_DESC(idProduct, "USB Product ID"); \ + \ + module_param_named(bcdDevice, coverwrite.bcdDevice, ushort, S_IRUGO); \ + MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)") + +void usb_composite_overwrite_options(struct usb_composite_dev *cdev, + struct usb_composite_overwrite *covr); /* messaging utils */ #define DBG(d, fmt, args...) \ -- cgit v1.2.3-59-g8ed1b From 276e2e4f1f3e07a0ad891bf757dbcfd655ff5f91 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:21 +0200 Subject: usb: gadget: make sure each gadget is using same index for Product, Serial,… MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The index in usb_string array is defined by the gadget. The gadget can choose which index entry it assigns for the serial number and which the product name. The gadget has just to ensure that the descriptor contains the proper string id which is assigned by composite. If the composite layer knows the index of the "default" information which will be overwritten by module parameters, it can be used later to overwrite it. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/acm_ms.c | 12 +++++------- drivers/usb/gadget/audio.c | 12 +++++------- drivers/usb/gadget/cdc2.c | 13 +++++-------- drivers/usb/gadget/ether.c | 14 +++++--------- drivers/usb/gadget/g_ffs.c | 8 ++++++-- drivers/usb/gadget/gmidi.c | 13 ++++++------- drivers/usb/gadget/hid.c | 13 +++++-------- drivers/usb/gadget/multi.c | 13 ++++--------- drivers/usb/gadget/ncm.c | 13 +++++-------- drivers/usb/gadget/nokia.c | 13 ++++++------- drivers/usb/gadget/printer.c | 16 ++++++---------- drivers/usb/gadget/serial.c | 13 ++++++------- drivers/usb/gadget/tcm_usb_gadget.c | 13 +++++++------ drivers/usb/gadget/tcm_usb_gadget.h | 5 +---- drivers/usb/gadget/webcam.c | 13 ++++++------- drivers/usb/gadget/zero.c | 17 ++++++----------- include/linux/usb/composite.h | 12 +++++++++++- 17 files changed, 95 insertions(+), 118 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 7bd6b71af5d3..35db6aa57281 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -90,14 +90,12 @@ static const struct usb_descriptor_header *otg_desc[] = { /* string IDs are assigned dynamically */ -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 - static char manufacturer[50]; static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer, - [STRING_PRODUCT_IDX].s = DRIVER_DESC, + [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, + [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ }; @@ -196,8 +194,8 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail1; - device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; /* register our configuration */ status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config); diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 55b593c5a9c8..8857b6eeb6a2 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -33,14 +33,12 @@ USB_GADGET_COMPOSITE_OPTIONS(); /* string IDs are assigned dynamically */ -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 - static char manufacturer[50]; static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer, - [STRING_PRODUCT_IDX].s = DRIVER_DESC, + [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, + [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ }; @@ -170,8 +168,8 @@ static int __init audio_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; - device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; status = usb_add_config(cdev, &audio_config_driver, audio_do_config); if (status < 0) diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 93a75809b4de..8966bdec1534 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -90,15 +90,12 @@ static const struct usb_descriptor_header *otg_desc[] = { /* string IDs are assigned dynamically */ - -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 - static char manufacturer[50]; static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer, - [STRING_PRODUCT_IDX].s = DRIVER_DESC, + [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, + [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ }; @@ -197,8 +194,8 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail1; - device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; /* register our configuration */ status = usb_add_config(cdev, &cdc_config_driver, cdc_do_config); diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 709ef2265596..dd5e00d207fe 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -193,17 +193,13 @@ static const struct usb_descriptor_header *otg_desc[] = { NULL, }; - /* string IDs are assigned dynamically */ - -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 - static char manufacturer[50]; static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer, - [STRING_PRODUCT_IDX].s = PREFIX DRIVER_DESC, + [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_PRODUCT_IDX].s = PREFIX DRIVER_DESC, + [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ }; @@ -349,8 +345,8 @@ static int __init eth_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; - device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; /* register our configuration(s); RNDIS first, if it's used */ if (has_rndis()) { diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index a44ed661c16b..16d18873ebeb 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -116,6 +116,9 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = { /* String IDs are assigned dynamically */ static struct usb_string gfs_strings[] = { + [USB_GADGET_MANUFACTURER_IDX].s = "", + [USB_GADGET_PRODUCT_IDX].s = "", + [USB_GADGET_SERIAL_IDX].s = "", #ifdef CONFIG_USB_FUNCTIONFS_RNDIS { .s = "FunctionFS + RNDIS" }, #endif @@ -369,9 +372,10 @@ static int gfs_bind(struct usb_composite_dev *cdev) for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) { struct gfs_configuration *c = gfs_configurations + i; + int sid = USB_GADGET_FIRST_AVAIL_IDX + i; - c->c.label = gfs_strings[i].s; - c->c.iConfiguration = gfs_strings[i].id; + c->c.label = gfs_strings[sid].s; + c->c.iConfiguration = gfs_strings[sid].id; c->c.bConfigurationValue = 1 + i; c->c.bmAttributes = USB_CONFIG_ATT_SELFPOWER; diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 01b31e2d03af..2ee3a74056c9 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -84,9 +84,7 @@ MODULE_PARM_DESC(out_ports, "Number of MIDI output ports"); /* string IDs are assigned dynamically */ -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 -#define STRING_DESCRIPTION_IDX 2 +#define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX static struct usb_device_descriptor device_desc = { .bLength = USB_DT_DEVICE_SIZE, @@ -101,8 +99,9 @@ static struct usb_device_descriptor device_desc = { }; static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = "Grey Innovation", - [STRING_PRODUCT_IDX].s = "MIDI Gadget", + [USB_GADGET_MANUFACTURER_IDX].s = "Grey Innovation", + [USB_GADGET_PRODUCT_IDX].s = "MIDI Gadget", + [USB_GADGET_SERIAL_IDX].s = "", [STRING_DESCRIPTION_IDX].s = "MIDI", { } /* end of list */ }; @@ -145,8 +144,8 @@ static int __init midi_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) return status; - device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; midi_config.iConfiguration = strings_dev[STRING_DESCRIPTION_IDX].id; gcnum = usb_gadget_controller_number(gadget); diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 59fe7eef00da..16caf50e916d 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -91,15 +91,12 @@ static const struct usb_descriptor_header *otg_desc[] = { /* string IDs are assigned dynamically */ - -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 - static char manufacturer[50]; static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer, - [STRING_PRODUCT_IDX].s = DRIVER_DESC, + [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, + [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ }; @@ -181,8 +178,8 @@ static int __init hid_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) return status; - device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; /* register our configuration */ status = usb_add_config(cdev, &config_driver, do_config); diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 60168877330a..94b35e5539d7 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -109,21 +109,16 @@ static const struct usb_descriptor_header *otg_desc[] = { enum { -#ifdef CONFIG_USB_G_MULTI_RNDIS - MULTI_STRING_RNDIS_CONFIG_IDX, -#endif -#ifdef CONFIG_USB_G_MULTI_CDC + MULTI_STRING_RNDIS_CONFIG_IDX = USB_GADGET_FIRST_AVAIL_IDX, MULTI_STRING_CDC_CONFIG_IDX, -#endif }; static struct usb_string strings_dev[] = { -#ifdef CONFIG_USB_G_MULTI_RNDIS + [USB_GADGET_MANUFACTURER_IDX].s = "", + [USB_GADGET_PRODUCT_IDX].s = "", + [USB_GADGET_SERIAL_IDX].s = "", [MULTI_STRING_RNDIS_CONFIG_IDX].s = "Multifunction with RNDIS", -#endif -#ifdef CONFIG_USB_G_MULTI_CDC [MULTI_STRING_CDC_CONFIG_IDX].s = "Multifunction with CDC ECM", -#endif { } /* end of list */ }; diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index 8537cd9c6aff..1a26452ce4ca 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -97,15 +97,12 @@ static const struct usb_descriptor_header *otg_desc[] = { /* string IDs are assigned dynamically */ - -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 - static char manufacturer[50]; static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer, - [STRING_PRODUCT_IDX].s = DRIVER_DESC, + [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, + [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ }; @@ -184,8 +181,8 @@ static int __init gncm_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; - device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; status = usb_add_config(cdev, &ncm_config_driver, ncm_do_config); diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index 5ed927b16c0e..34b97f12b7da 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -56,17 +56,16 @@ USB_GADGET_COMPOSITE_OPTIONS(); /* string IDs are assigned dynamically */ -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 -#define STRING_DESCRIPTION_IDX 2 +#define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX static char manufacturer_nokia[] = "Nokia"; static const char product_nokia[] = NOKIA_LONG_NAME; static const char description_nokia[] = "PC-Suite Configuration"; static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer_nokia, - [STRING_PRODUCT_IDX].s = NOKIA_LONG_NAME, + [USB_GADGET_MANUFACTURER_IDX].s = manufacturer_nokia, + [USB_GADGET_PRODUCT_IDX].s = NOKIA_LONG_NAME, + [USB_GADGET_SERIAL_IDX].s = "", [STRING_DESCRIPTION_IDX].s = description_nokia, { } /* end of list */ }; @@ -168,8 +167,8 @@ static int __init nokia_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto err_usb; - device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; status = strings_dev[STRING_DESCRIPTION_IDX].id; nokia_config_500ma_driver.iConfiguration = status; nokia_config_100ma_driver.iConfiguration = status; diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 3fa4d80629cc..f02434a10dec 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -139,10 +139,6 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR); * descriptors are built on demand. */ -#define STRING_MANUFACTURER 0 -#define STRING_PRODUCT 1 -#define STRING_SERIALNUM 2 - /* holds our biggest descriptor */ #define USB_DESC_BUFSIZE 256 #define USB_BUFSIZE 8192 @@ -250,9 +246,9 @@ static char pnp_string [1024] = /* static strings, in UTF-8 */ static struct usb_string strings [] = { - [STRING_MANUFACTURER].s = manufacturer, - [STRING_PRODUCT].s = product_desc, - [STRING_SERIALNUM].s = serial_num, + [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_PRODUCT_IDX].s = product_desc, + [USB_GADGET_SERIAL_IDX].s = serial_num, { } /* end of list */ }; @@ -1261,9 +1257,9 @@ static int __init printer_bind(struct usb_composite_dev *cdev) ret = usb_string_ids_tab(cdev, strings); if (ret < 0) return ret; - device_desc.iManufacturer = strings[STRING_MANUFACTURER].id; - device_desc.iProduct = strings[STRING_PRODUCT].id; - device_desc.iSerialNumber = strings[STRING_SERIALNUM].id; + 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_bind_config); if (ret) diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 27b5ce939bdb..768a38e896f7 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -59,15 +59,14 @@ USB_GADGET_COMPOSITE_OPTIONS(); /* string IDs are assigned dynamically */ -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 -#define STRING_DESCRIPTION_IDX 2 +#define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX static char manufacturer[50]; static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer, - [STRING_PRODUCT_IDX].s = GS_VERSION_NAME, + [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_PRODUCT_IDX].s = GS_VERSION_NAME, + [USB_GADGET_SERIAL_IDX].s = "", [STRING_DESCRIPTION_IDX].s = NULL /* updated; f(use_acm) */, { } /* end of list */ }; @@ -179,8 +178,8 @@ static int __init gs_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; - device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; + device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; status = strings_dev[STRING_DESCRIPTION_IDX].id; serial_config_driver.iConfiguration = status; diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index fa3137ef228b..b56d57d59796 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -2210,9 +2210,9 @@ static struct usb_device_descriptor usbg_device_desc = { }; static struct usb_string usbg_us_strings[] = { - [USB_G_STR_MANUFACTOR].s = "Target Manufactor", - [USB_G_STR_PRODUCT].s = "Target Product", - [USB_G_STR_SERIAL].s = "000000000001", + [USB_GADGET_MANUFACTURER_IDX].s = "Target Manufactor", + [USB_GADGET_PRODUCT_IDX].s = "Target Product", + [USB_GADGET_SERIAL_IDX].s = "000000000001", [USB_G_STR_CONFIG].s = "default config", [USB_G_STR_INT_UAS].s = "USB Attached SCSI", [USB_G_STR_INT_BBB].s = "Bulk Only Transport", @@ -2431,9 +2431,10 @@ static int usb_target_bind(struct usb_composite_dev *cdev) return ret; usbg_device_desc.iManufacturer = - usbg_us_strings[USB_G_STR_MANUFACTOR].id; - usbg_device_desc.iProduct = usbg_us_strings[USB_G_STR_PRODUCT].id; - usbg_device_desc.iSerialNumber = usbg_us_strings[USB_G_STR_SERIAL].id; + usbg_us_strings[USB_GADGET_MANUFACTURER_IDX].id; + usbg_device_desc.iProduct = usbg_us_strings[USB_GADGET_PRODUCT_IDX].id; + usbg_device_desc.iSerialNumber = + usbg_us_strings[USB_GADGET_SERIAL_IDX].id; usbg_config_driver.iConfiguration = usbg_us_strings[USB_G_STR_CONFIG].id; diff --git a/drivers/usb/gadget/tcm_usb_gadget.h b/drivers/usb/gadget/tcm_usb_gadget.h index 9d32ec30f4e4..8289219925b8 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.h +++ b/drivers/usb/gadget/tcm_usb_gadget.h @@ -17,10 +17,7 @@ #define UASP_SS_EP_COMP_NUM_STREAMS (1 << UASP_SS_EP_COMP_LOG_STREAMS) enum { - USB_G_STR_MANUFACTOR, - USB_G_STR_PRODUCT, - USB_G_STR_SERIAL, - USB_G_STR_CONFIG, + USB_G_STR_CONFIG = USB_GADGET_FIRST_AVAIL_IDX, USB_G_STR_INT_UAS, USB_G_STR_INT_BBB, }; diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index 306006419f38..03591194b17a 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -45,13 +45,12 @@ static char webcam_config_label[] = "Video"; /* string IDs are assigned dynamically */ -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 -#define STRING_DESCRIPTION_IDX 2 +#define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX static struct usb_string webcam_strings[] = { - [STRING_MANUFACTURER_IDX].s = webcam_vendor_label, - [STRING_PRODUCT_IDX].s = webcam_product_label, + [USB_GADGET_MANUFACTURER_IDX].s = webcam_vendor_label, + [USB_GADGET_PRODUCT_IDX].s = webcam_product_label, + [USB_GADGET_SERIAL_IDX].s = "", [STRING_DESCRIPTION_IDX].s = webcam_config_label, { } }; @@ -360,9 +359,9 @@ webcam_bind(struct usb_composite_dev *cdev) if (ret < 0) goto error; webcam_device_descriptor.iManufacturer = - webcam_strings[STRING_MANUFACTURER_IDX].id; + webcam_strings[USB_GADGET_MANUFACTURER_IDX].id; webcam_device_descriptor.iProduct = - webcam_strings[STRING_PRODUCT_IDX].id; + webcam_strings[USB_GADGET_PRODUCT_IDX].id; webcam_config_driver.iConfiguration = webcam_strings[STRING_DESCRIPTION_IDX].id; diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 2b31a4ae26b9..ee769c45498b 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -139,20 +139,15 @@ const struct usb_descriptor_header *otg_desc[] = { #endif /* string IDs are assigned dynamically */ - -#define STRING_MANUFACTURER_IDX 0 -#define STRING_PRODUCT_IDX 1 -#define STRING_SERIAL_IDX 2 - static char manufacturer[50]; /* default serial number takes at least two packets */ static char serial[] = "0123456789.0123456789.0123456789"; static struct usb_string strings_dev[] = { - [STRING_MANUFACTURER_IDX].s = manufacturer, - [STRING_PRODUCT_IDX].s = longname, - [STRING_SERIAL_IDX].s = serial, + [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_PRODUCT_IDX].s = longname, + [USB_GADGET_SERIAL_IDX].s = serial, { } /* end of list */ }; @@ -274,9 +269,9 @@ static int __init zero_bind(struct usb_composite_dev *cdev) if (status < 0) return status; - device_desc.iManufacturer = strings_dev[STRING_MANUFACTURER_IDX].id; - device_desc.iProduct = strings_dev[STRING_PRODUCT_IDX].id; - device_desc.iSerialNumber = strings_dev[STRING_SERIAL_IDX].id; + device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; + device_desc.iSerialNumber = strings_dev[USB_GADGET_SERIAL_IDX].id; setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 7651e5bf7487..f821a3ad475d 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -248,6 +248,14 @@ int usb_add_config(struct usb_composite_dev *, void usb_remove_config(struct usb_composite_dev *, struct usb_configuration *); +/* predefined index for usb_composite_driver */ +enum { + USB_GADGET_MANUFACTURER_IDX = 0, + USB_GADGET_PRODUCT_IDX, + USB_GADGET_SERIAL_IDX, + USB_GADGET_FIRST_AVAIL_IDX, +}; + /** * struct usb_composite_driver - groups configurations into a gadget * @name: For diagnostics, identifies the driver. @@ -261,7 +269,9 @@ void usb_remove_config(struct usb_composite_dev *, * @dev: Template descriptor for the device, including default device * identifiers. * @strings: tables of strings, keyed by identifiers assigned during @bind - * and language IDs provided in control requests + * and language IDs provided in control requests. Note: The first entries + * are predefined. The first entry that may be used is + * USB_GADGET_FIRST_AVAIL_IDX * @max_speed: Highest speed the driver supports. * @needs_serial: set to 1 if the gadget needs userspace to provide * a serial number. If one is not provided, warning will be printed. -- cgit v1.2.3-59-g8ed1b From 1cf0d264088907038be560ba2dd472d5e432a3dc Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 15:01:54 +0200 Subject: usb: gadget: push iSerialNumber into gadgets This patch pushes the iSerialNumber module argument from composite into each gadget. Once the user uses the module paramter, the string is overwritten with the final value. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 20 +++++++++++++------- drivers/usb/gadget/mass_storage.c | 21 +++++++++++++++++++++ drivers/usb/gadget/printer.c | 6 +----- include/linux/usb/composite.h | 7 ++++++- 4 files changed, 41 insertions(+), 13 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 317a5ece3bd2..5642b2170541 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -40,10 +40,6 @@ static char *iProduct; module_param(iProduct, charp, S_IRUGO); MODULE_PARM_DESC(iProduct, "USB Product string"); -static char *iSerialNumber; -module_param(iSerialNumber, charp, S_IRUGO); -MODULE_PARM_DESC(iSerialNumber, "SerialNumber string"); - static char composite_manufacturer[50]; /*-------------------------------------------------------------------------*/ @@ -925,7 +921,7 @@ static int get_string(struct usb_composite_dev *cdev, else if (cdev->product_override == id) str = iProduct ?: composite->iProduct; else if (cdev->serial_override == id) - str = iSerialNumber ?: composite->iSerialNumber; + str = composite->iSerialNumber; else str = NULL; if (str) { @@ -1411,6 +1407,7 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, __le16 idVendor; __le16 idProduct; __le16 bcdDevice; + u8 iSerialNumber; /* * these variables may have been set in @@ -1419,6 +1416,7 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, idVendor = new->idVendor; idProduct = new->idProduct; bcdDevice = new->bcdDevice; + iSerialNumber = new->iSerialNumber; *new = *old; if (idVendor) @@ -1427,6 +1425,8 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, new->idProduct = idProduct; if (bcdDevice) new->bcdDevice = bcdDevice; + if (iSerialNumber) + new->iSerialNumber = iSerialNumber; } static struct usb_composite_driver *to_cdriver(struct usb_gadget_driver *gdrv) @@ -1505,8 +1505,7 @@ static int composite_bind(struct usb_gadget *gadget, cdev->product_override = override_id(cdev, &cdev->desc.iProduct); - if (iSerialNumber || - (!cdev->desc.iSerialNumber && composite->iSerialNumber)) + if (composite->iSerialNumber) cdev->serial_override = override_id(cdev, &cdev->desc.iSerialNumber); @@ -1691,6 +1690,8 @@ void usb_composite_overwrite_options(struct usb_composite_dev *cdev, struct usb_composite_overwrite *covr) { struct usb_device_descriptor *desc = &cdev->desc; + struct usb_gadget_strings *gstr = cdev->driver->strings[0]; + struct usb_string *dev_str = gstr->strings; if (covr->idVendor) desc->idVendor = cpu_to_le16(covr->idVendor); @@ -1700,4 +1701,9 @@ void usb_composite_overwrite_options(struct usb_composite_dev *cdev, if (covr->bcdDevice) desc->bcdDevice = cpu_to_le16(covr->bcdDevice); + + if (covr->serial_number) { + desc->iSerialNumber = dev_str[USB_GADGET_SERIAL_IDX].id; + dev_str[USB_GADGET_SERIAL_IDX].s = covr->serial_number; + } } diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 8ffbade383f2..6f5a3b232d81 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -83,6 +83,22 @@ static const struct usb_descriptor_header *otg_desc[] = { NULL, }; +static struct usb_string strings_dev[] = { + [USB_GADGET_MANUFACTURER_IDX].s = "", + [USB_GADGET_PRODUCT_IDX].s = "", + [USB_GADGET_SERIAL_IDX].s = "", + { } /* end of list */ +}; + +static struct usb_gadget_strings stringtab_dev = { + .language = 0x0409, /* en-us */ + .strings = strings_dev, +}; + +static struct usb_gadget_strings *dev_strings[] = { + &stringtab_dev, + NULL, +}; /****************************** Configurations ******************************/ @@ -141,6 +157,10 @@ static int __init msg_bind(struct usb_composite_dev *cdev) { int status; + status = usb_string_ids_tab(cdev, strings_dev); + if (status < 0) + return status; + status = usb_add_config(cdev, &msg_config_driver, msg_do_config); if (status < 0) return status; @@ -160,6 +180,7 @@ static __refdata struct usb_composite_driver msg_driver = { .iProduct = DRIVER_DESC, .max_speed = USB_SPEED_SUPER, .needs_serial = 1, + .strings = dev_strings, .bind = msg_bind, }; diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index f02434a10dec..3321a9df4862 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -118,8 +118,7 @@ static struct printer_dev usb_printer_gadget; * parameters are in UTF-8 (superset of ASCII's 7 bit characters). */ -static char *iSerialNum; -module_param(iSerialNum, charp, S_IRUGO); +module_param_named(iSerialNum, coverwrite.serial_number, charp, S_IRUGO); MODULE_PARM_DESC(iSerialNum, "1"); static char *iPNPstring; @@ -1170,9 +1169,6 @@ static int __init printer_bind_config(struct usb_configuration *c) init_utsname()->sysname, init_utsname()->release, gadget->name); - if (iSerialNum) - strlcpy(serial_num, iSerialNum, sizeof serial_num); - if (iPNPstring) strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2); diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index f821a3ad475d..9d068a4be778 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -400,6 +400,7 @@ struct usb_composite_overwrite { u16 idVendor; u16 idProduct; u16 bcdDevice; + char *serial_number; }; #define USB_GADGET_COMPOSITE_OPTIONS() \ static struct usb_composite_overwrite coverwrite; \ @@ -411,7 +412,11 @@ struct usb_composite_overwrite { MODULE_PARM_DESC(idProduct, "USB Product ID"); \ \ module_param_named(bcdDevice, coverwrite.bcdDevice, ushort, S_IRUGO); \ - MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)") + MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); \ + \ + module_param_named(iSerialNumber, coverwrite.serial_number, charp, \ + S_IRUGO); \ + MODULE_PARM_DESC(iSerialNumber, "SerialNumber string") void usb_composite_overwrite_options(struct usb_composite_dev *cdev, struct usb_composite_overwrite *covr); -- cgit v1.2.3-59-g8ed1b From 03de9bf69c589b71c43aa52b838690cb477903c9 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 15:01:55 +0200 Subject: usb: gadget: push iManufacturer into gadgets This patch pushes the iManufacturer module argument from composite into each gadget. Once the user uses the module paramter, the string is overwritten with the final value. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 20 +++++++++++--------- include/linux/usb/composite.h | 7 ++++++- 2 files changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 5642b2170541..482cf8cf301d 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -32,10 +32,6 @@ * published in the device descriptor, either numbers or strings or both. * String parameters are in UTF-8 (superset of ASCII's 7 bit characters). */ -static char *iManufacturer; -module_param(iManufacturer, charp, S_IRUGO); -MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); - static char *iProduct; module_param(iProduct, charp, S_IRUGO); MODULE_PARM_DESC(iProduct, "USB Product string"); @@ -916,8 +912,7 @@ static int get_string(struct usb_composite_dev *cdev, * check if the string has not been overridden. */ if (cdev->manufacturer_override == id) - str = iManufacturer ?: composite->iManufacturer ?: - composite_manufacturer; + str = composite->iManufacturer ?: composite_manufacturer; else if (cdev->product_override == id) str = iProduct ?: composite->iProduct; else if (cdev->serial_override == id) @@ -1408,6 +1403,7 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, __le16 idProduct; __le16 bcdDevice; u8 iSerialNumber; + u8 iManufacturer; /* * these variables may have been set in @@ -1417,6 +1413,7 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, idProduct = new->idProduct; bcdDevice = new->bcdDevice; iSerialNumber = new->iSerialNumber; + iManufacturer = new->iManufacturer; *new = *old; if (idVendor) @@ -1427,6 +1424,8 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, new->bcdDevice = bcdDevice; if (iSerialNumber) new->iSerialNumber = iSerialNumber; + if (iManufacturer) + new->iManufacturer = iManufacturer; } static struct usb_composite_driver *to_cdriver(struct usb_gadget_driver *gdrv) @@ -1487,9 +1486,8 @@ static int composite_bind(struct usb_gadget *gadget, update_unchanged_dev_desc(&cdev->desc, composite->dev); /* string overrides */ - if (iManufacturer || !cdev->desc.iManufacturer) { - if (!iManufacturer && !composite->iManufacturer && - !*composite_manufacturer) + if (!cdev->desc.iManufacturer) { + if (!composite->iManufacturer) snprintf(composite_manufacturer, sizeof composite_manufacturer, "%s %s with %s", @@ -1706,4 +1704,8 @@ void usb_composite_overwrite_options(struct usb_composite_dev *cdev, desc->iSerialNumber = dev_str[USB_GADGET_SERIAL_IDX].id; dev_str[USB_GADGET_SERIAL_IDX].s = covr->serial_number; } + if (covr->manufacturer) { + desc->iManufacturer = dev_str[USB_GADGET_MANUFACTURER_IDX].id; + dev_str[USB_GADGET_MANUFACTURER_IDX].s = covr->manufacturer; + } } diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 9d068a4be778..86553c8c3e8b 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -401,6 +401,7 @@ struct usb_composite_overwrite { u16 idProduct; u16 bcdDevice; char *serial_number; + char *manufacturer; }; #define USB_GADGET_COMPOSITE_OPTIONS() \ static struct usb_composite_overwrite coverwrite; \ @@ -416,7 +417,11 @@ struct usb_composite_overwrite { \ module_param_named(iSerialNumber, coverwrite.serial_number, charp, \ S_IRUGO); \ - MODULE_PARM_DESC(iSerialNumber, "SerialNumber string") + MODULE_PARM_DESC(iSerialNumber, "SerialNumber string"); \ + \ + module_param_named(iManufacturer, coverwrite.manufacturer, charp, \ + S_IRUGO); \ + MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string") void usb_composite_overwrite_options(struct usb_composite_dev *cdev, struct usb_composite_overwrite *covr); -- cgit v1.2.3-59-g8ed1b From 2d35ee47aaafac152bc4bc5020660ffa1753ab02 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 15:01:56 +0200 Subject: usb: gadget: push iProduct into gadgets This patch pushes the iProduct module argument from composite into each gadget. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 21 +++++++++++---------- include/linux/usb/composite.h | 6 +++++- 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 482cf8cf301d..47b9130968bc 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -28,14 +28,6 @@ * with the relevant device-wide data. */ -/* Some systems will need runtime overrides for the product identifiers - * published in the device descriptor, either numbers or strings or both. - * String parameters are in UTF-8 (superset of ASCII's 7 bit characters). - */ -static char *iProduct; -module_param(iProduct, charp, S_IRUGO); -MODULE_PARM_DESC(iProduct, "USB Product string"); - static char composite_manufacturer[50]; /*-------------------------------------------------------------------------*/ @@ -914,7 +906,7 @@ static int get_string(struct usb_composite_dev *cdev, if (cdev->manufacturer_override == id) str = composite->iManufacturer ?: composite_manufacturer; else if (cdev->product_override == id) - str = iProduct ?: composite->iProduct; + str = composite->iProduct; else if (cdev->serial_override == id) str = composite->iSerialNumber; else @@ -1404,6 +1396,7 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, __le16 bcdDevice; u8 iSerialNumber; u8 iManufacturer; + u8 iProduct; /* * these variables may have been set in @@ -1414,6 +1407,7 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, bcdDevice = new->bcdDevice; iSerialNumber = new->iSerialNumber; iManufacturer = new->iManufacturer; + iProduct = new->iProduct; *new = *old; if (idVendor) @@ -1426,6 +1420,8 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, new->iSerialNumber = iSerialNumber; if (iManufacturer) new->iManufacturer = iManufacturer; + if (iProduct) + new->iProduct = iProduct; } static struct usb_composite_driver *to_cdriver(struct usb_gadget_driver *gdrv) @@ -1499,7 +1495,7 @@ static int composite_bind(struct usb_gadget *gadget, override_id(cdev, &cdev->desc.iManufacturer); } - if (iProduct || (!cdev->desc.iProduct && composite->iProduct)) + if (!cdev->desc.iProduct && composite->iProduct) cdev->product_override = override_id(cdev, &cdev->desc.iProduct); @@ -1708,4 +1704,9 @@ void usb_composite_overwrite_options(struct usb_composite_dev *cdev, desc->iManufacturer = dev_str[USB_GADGET_MANUFACTURER_IDX].id; dev_str[USB_GADGET_MANUFACTURER_IDX].s = covr->manufacturer; } + + if (covr->product) { + desc->iProduct = dev_str[USB_GADGET_PRODUCT_IDX].id; + dev_str[USB_GADGET_PRODUCT_IDX].s = covr->product; + } } diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 86553c8c3e8b..5cd110ec0a23 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -402,6 +402,7 @@ struct usb_composite_overwrite { u16 bcdDevice; char *serial_number; char *manufacturer; + char *product; }; #define USB_GADGET_COMPOSITE_OPTIONS() \ static struct usb_composite_overwrite coverwrite; \ @@ -421,7 +422,10 @@ struct usb_composite_overwrite { \ module_param_named(iManufacturer, coverwrite.manufacturer, charp, \ S_IRUGO); \ - MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string") + MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); \ + \ + module_param_named(iProduct, coverwrite.product, charp, S_IRUGO); \ + MODULE_PARM_DESC(iProduct, "USB Product string") void usb_composite_overwrite_options(struct usb_composite_dev *cdev, struct usb_composite_overwrite *covr); -- cgit v1.2.3-59-g8ed1b From d33f74fce3756d51a0203cec3d0d278e3b48d827 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 15:01:57 +0200 Subject: usb: gadget: remove string override from struct usb_composite_driver The struct usb_composite_driver members iProduct, iSerial and iManufacturer can be entered directly via the string array. There is no need for them to appear here. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 29 +++++++---------------------- drivers/usb/gadget/g_ffs.c | 4 ++-- drivers/usb/gadget/mass_storage.c | 4 ++-- drivers/usb/gadget/multi.c | 4 ++-- include/linux/usb/composite.h | 12 ------------ 5 files changed, 13 insertions(+), 40 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 47b9130968bc..f3689e1bf4b2 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -904,11 +904,7 @@ static int get_string(struct usb_composite_dev *cdev, * check if the string has not been overridden. */ if (cdev->manufacturer_override == id) - str = composite->iManufacturer ?: composite_manufacturer; - else if (cdev->product_override == id) - str = composite->iProduct; - else if (cdev->serial_override == id) - str = composite->iSerialNumber; + str = composite_manufacturer; else str = NULL; if (str) { @@ -1483,26 +1479,17 @@ static int composite_bind(struct usb_gadget *gadget, /* string overrides */ if (!cdev->desc.iManufacturer) { - if (!composite->iManufacturer) - snprintf(composite_manufacturer, - sizeof composite_manufacturer, - "%s %s with %s", - init_utsname()->sysname, - init_utsname()->release, - gadget->name); + snprintf(composite_manufacturer, + sizeof composite_manufacturer, + "%s %s with %s", + init_utsname()->sysname, + init_utsname()->release, + gadget->name); cdev->manufacturer_override = override_id(cdev, &cdev->desc.iManufacturer); } - if (!cdev->desc.iProduct && composite->iProduct) - cdev->product_override = - override_id(cdev, &cdev->desc.iProduct); - - if (composite->iSerialNumber) - cdev->serial_override = - override_id(cdev, &cdev->desc.iSerialNumber); - /* has userspace failed to provide a serial number? */ if (composite->needs_serial && !cdev->desc.iSerialNumber) WARNING(cdev, "userspace failed to provide iSerialNumber\n"); @@ -1619,8 +1606,6 @@ int usb_composite_probe(struct usb_composite_driver *driver) if (!driver->name) driver->name = "composite"; - if (!driver->iProduct) - driver->iProduct = driver->name; driver->gadget_driver = composite_driver_template; gadget_driver = &driver->gadget_driver; diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 16d18873ebeb..eaaed199e453 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -117,7 +117,7 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = { /* String IDs are assigned dynamically */ static struct usb_string gfs_strings[] = { [USB_GADGET_MANUFACTURER_IDX].s = "", - [USB_GADGET_PRODUCT_IDX].s = "", + [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, [USB_GADGET_SERIAL_IDX].s = "", #ifdef CONFIG_USB_FUNCTIONFS_RNDIS { .s = "FunctionFS + RNDIS" }, @@ -172,7 +172,6 @@ static __refdata struct usb_composite_driver gfs_driver = { .max_speed = USB_SPEED_HIGH, .bind = gfs_bind, .unbind = gfs_unbind, - .iProduct = DRIVER_DESC, }; static DEFINE_MUTEX(gfs_lock); @@ -360,6 +359,7 @@ static int gfs_bind(struct usb_composite_dev *cdev) ret = usb_string_ids_tab(cdev, gfs_strings); if (unlikely(ret < 0)) goto error; + gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id; for (i = func_num; --i; ) { ret = functionfs_bind(ffs_tab[i].ffs_data, cdev); diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 6f5a3b232d81..50da3c88cb06 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -85,7 +85,7 @@ static const struct usb_descriptor_header *otg_desc[] = { static struct usb_string strings_dev[] = { [USB_GADGET_MANUFACTURER_IDX].s = "", - [USB_GADGET_PRODUCT_IDX].s = "", + [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ }; @@ -160,6 +160,7 @@ static int __init msg_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) return status; + msg_device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; status = usb_add_config(cdev, &msg_config_driver, msg_do_config); if (status < 0) @@ -177,7 +178,6 @@ static int __init msg_bind(struct usb_composite_dev *cdev) static __refdata struct usb_composite_driver msg_driver = { .name = "g_mass_storage", .dev = &msg_device_desc, - .iProduct = DRIVER_DESC, .max_speed = USB_SPEED_SUPER, .needs_serial = 1, .strings = dev_strings, diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 94b35e5539d7..c158706b5ab0 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -115,7 +115,7 @@ enum { static struct usb_string strings_dev[] = { [USB_GADGET_MANUFACTURER_IDX].s = "", - [USB_GADGET_PRODUCT_IDX].s = "", + [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, [USB_GADGET_SERIAL_IDX].s = "", [MULTI_STRING_RNDIS_CONFIG_IDX].s = "Multifunction with RNDIS", [MULTI_STRING_CDC_CONFIG_IDX].s = "Multifunction with CDC ECM", @@ -293,6 +293,7 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (unlikely(status < 0)) goto fail2; + device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; /* register configurations */ status = rndis_config_register(cdev); @@ -338,7 +339,6 @@ static __refdata struct usb_composite_driver multi_driver = { .max_speed = USB_SPEED_HIGH, .bind = multi_bind, .unbind = __exit_p(multi_unbind), - .iProduct = DRIVER_DESC, .needs_serial = 1, }; diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 5cd110ec0a23..60f8815998bd 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -259,13 +259,6 @@ enum { /** * struct usb_composite_driver - groups configurations into a gadget * @name: For diagnostics, identifies the driver. - * @iProduct: Used as iProduct override if @dev->iProduct is not set. - * If NULL value of @name is taken. - * @iManufacturer: Used as iManufacturer override if @dev->iManufacturer is - * not set. If NULL a default " with " value - * will be used. - * @iSerialNumber: Used as iSerialNumber override if @dev->iSerialNumber is - * not set. * @dev: Template descriptor for the device, including default device * identifiers. * @strings: tables of strings, keyed by identifiers assigned during @bind @@ -300,9 +293,6 @@ enum { */ struct usb_composite_driver { const char *name; - const char *iProduct; - const char *iManufacturer; - const char *iSerialNumber; const struct usb_device_descriptor *dev; struct usb_gadget_strings **strings; enum usb_device_speed max_speed; @@ -369,8 +359,6 @@ struct usb_composite_dev { struct usb_composite_driver *driver; u8 next_string_id; u8 manufacturer_override; - u8 product_override; - u8 serial_override; /* the gadget driver won't enable the data pullup * while the deactivation count is nonzero. -- cgit v1.2.3-59-g8ed1b From cc2683c318a5bf192b75cd5c343b51009db0cf6c Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 15:01:58 +0200 Subject: usb: gadget: Provide a default implementation of default manufacturer string Some gadgets provide custom entry here. Some may override it with an etntry that is also created by composite if there was no value sumbitted at all. This patch removes all "custom manufacturer" strings which are the same as these which are created by composite. Then it moves the creation of the default manufacturer string to usb_composite_overwrite_options() in case no command line argument has been used and the entry is still an empty string. By doing this we get rid of the global variable "composite_manufacturer" in composite. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/acm_ms.c | 12 +------ drivers/usb/gadget/audio.c | 9 +---- drivers/usb/gadget/cdc2.c | 10 +----- drivers/usb/gadget/composite.c | 67 ++++++++++++------------------------- drivers/usb/gadget/ether.c | 12 +------ drivers/usb/gadget/f_hid.c | 1 - drivers/usb/gadget/f_mass_storage.c | 1 - drivers/usb/gadget/f_midi.c | 1 - drivers/usb/gadget/g_ffs.c | 1 - drivers/usb/gadget/gmidi.c | 1 - drivers/usb/gadget/hid.c | 10 +----- drivers/usb/gadget/mass_storage.c | 2 -- drivers/usb/gadget/multi.c | 2 -- drivers/usb/gadget/ncm.c | 12 +------ drivers/usb/gadget/nokia.c | 1 - drivers/usb/gadget/printer.c | 8 +---- drivers/usb/gadget/serial.c | 9 +---- drivers/usb/gadget/zero.c | 9 +---- include/linux/usb/composite.h | 2 +- 19 files changed, 32 insertions(+), 138 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 35db6aa57281..d280f164887c 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -15,7 +15,6 @@ */ #include -#include #include "u_serial.h" @@ -87,13 +86,9 @@ static const struct usb_descriptor_header *otg_desc[] = { NULL, }; - /* string IDs are assigned dynamically */ - -static char manufacturer[50]; - static struct usb_string strings_dev[] = { - [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ @@ -186,11 +181,6 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) * Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ - - /* device descriptor strings: manufacturer, product */ - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail1; diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 8857b6eeb6a2..1f81e0f4fab9 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -12,7 +12,6 @@ /* #define VERBOSE_DEBUG */ #include -#include #include #include "gadget_chips.h" @@ -33,10 +32,8 @@ USB_GADGET_COMPOSITE_OPTIONS(); /* string IDs are assigned dynamically */ -static char manufacturer[50]; - static struct usb_string strings_dev[] = { - [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ @@ -161,10 +158,6 @@ static int __init audio_bind(struct usb_composite_dev *cdev) __constant_cpu_to_le16(0x0300 | 0x0099); } - /* device descriptor strings: manufacturer, product */ - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - cdev->gadget->name); status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 8966bdec1534..4e2060bf35e3 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -11,7 +11,6 @@ */ #include -#include #include #include "u_ether.h" @@ -90,10 +89,8 @@ static const struct usb_descriptor_header *otg_desc[] = { /* string IDs are assigned dynamically */ -static char manufacturer[50]; - static struct usb_string strings_dev[] = { - [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ @@ -182,15 +179,10 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) cpu_to_le16(0x0300 | 0x0099); } - /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ - /* device descriptor strings: manufacturer, product */ - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail1; diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f3689e1bf4b2..c7066cd4c95a 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -28,9 +28,6 @@ * with the relevant device-wide data. */ -static char composite_manufacturer[50]; - -/*-------------------------------------------------------------------------*/ /** * next_ep_desc() - advance to the next EP descriptor * @t: currect pointer within descriptor array @@ -860,7 +857,6 @@ static int get_string(struct usb_composite_dev *cdev, struct usb_configuration *c; struct usb_function *f; int len; - const char *str; /* Yes, not only is USB's I18N support probably more than most * folk will ever care about ... also, it's all supported here. @@ -900,21 +896,6 @@ static int get_string(struct usb_composite_dev *cdev, return s->bLength; } - /* Otherwise, look up and return a specified string. First - * check if the string has not been overridden. - */ - if (cdev->manufacturer_override == id) - str = composite_manufacturer; - else - str = NULL; - if (str) { - struct usb_gadget_strings strings = { - .language = language, - .strings = &(struct usb_string) { 0xff, str } - }; - return usb_gadget_get_string(&strings, 0xff, buf); - } - /* String IDs are device-scoped, so we look up each string * table we're told about. These lookups are infrequent; * simpler-is-better here. @@ -1367,23 +1348,11 @@ composite_unbind(struct usb_gadget *gadget) usb_ep_free_request(gadget->ep0, cdev->req); } device_remove_file(&gadget->dev, &dev_attr_suspended); + kfree(cdev->def_manufacturer); kfree(cdev); set_gadget_data(gadget, NULL); } -static u8 override_id(struct usb_composite_dev *cdev, u8 *desc) -{ - if (!*desc) { - int ret = usb_string_id(cdev); - if (unlikely(ret < 0)) - WARNING(cdev, "failed to override string ID\n"); - else - *desc = ret; - } - - return *desc; -} - static void update_unchanged_dev_desc(struct usb_device_descriptor *new, const struct usb_device_descriptor *old) { @@ -1477,19 +1446,6 @@ static int composite_bind(struct usb_gadget *gadget, update_unchanged_dev_desc(&cdev->desc, composite->dev); - /* string overrides */ - if (!cdev->desc.iManufacturer) { - snprintf(composite_manufacturer, - sizeof composite_manufacturer, - "%s %s with %s", - init_utsname()->sysname, - init_utsname()->release, - gadget->name); - - cdev->manufacturer_override = - override_id(cdev, &cdev->desc.iManufacturer); - } - /* has userspace failed to provide a serial number? */ if (composite->needs_serial && !cdev->desc.iSerialNumber) WARNING(cdev, "userspace failed to provide iSerialNumber\n"); @@ -1665,6 +1621,22 @@ void usb_composite_setup_continue(struct usb_composite_dev *cdev) spin_unlock_irqrestore(&cdev->lock, flags); } +static char *composite_default_mfr(struct usb_gadget *gadget) +{ + char *mfr; + int len; + + len = snprintf(NULL, 0, "%s %s with %s", init_utsname()->sysname, + init_utsname()->release, gadget->name); + len++; + mfr = kmalloc(len, GFP_KERNEL); + if (!mfr) + return NULL; + snprintf(mfr, len, "%s %s with %s", init_utsname()->sysname, + init_utsname()->release, gadget->name); + return mfr; +} + void usb_composite_overwrite_options(struct usb_composite_dev *cdev, struct usb_composite_overwrite *covr) { @@ -1688,6 +1660,11 @@ void usb_composite_overwrite_options(struct usb_composite_dev *cdev, if (covr->manufacturer) { desc->iManufacturer = dev_str[USB_GADGET_MANUFACTURER_IDX].id; dev_str[USB_GADGET_MANUFACTURER_IDX].s = covr->manufacturer; + + } else if (!strlen(dev_str[USB_GADGET_MANUFACTURER_IDX].s)) { + desc->iManufacturer = dev_str[USB_GADGET_MANUFACTURER_IDX].id; + cdev->def_manufacturer = composite_default_mfr(cdev->gadget); + dev_str[USB_GADGET_MANUFACTURER_IDX].s = cdev->def_manufacturer; } if (covr->product) { diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index dd5e00d207fe..a5c272067625 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -14,8 +14,6 @@ /* #define VERBOSE_DEBUG */ #include -#include - #if defined USB_ETH_RNDIS # undef USB_ETH_RNDIS @@ -193,11 +191,8 @@ static const struct usb_descriptor_header *otg_desc[] = { NULL, }; -/* string IDs are assigned dynamically */ -static char manufacturer[50]; - static struct usb_string strings_dev[] = { - [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = PREFIX DRIVER_DESC, [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ @@ -333,15 +328,10 @@ static int __init eth_bind(struct usb_composite_dev *cdev) cpu_to_le16(0x0300 | 0x0099); } - /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ - /* device descriptor strings: manufacturer, product */ - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c index 16a8b1c15c62..77dbca099bcb 100644 --- a/drivers/usb/gadget/f_hid.c +++ b/drivers/usb/gadget/f_hid.c @@ -10,7 +10,6 @@ */ #include -#include #include #include #include diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 4f1142efa6d1..11150960d88b 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -213,7 +213,6 @@ #include #include #include -#include #include #include diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c index 2f7e8f2930cc..8ed1259fe80d 100644 --- a/drivers/usb/gadget/f_midi.c +++ b/drivers/usb/gadget/f_midi.c @@ -21,7 +21,6 @@ #include #include -#include #include #include diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index eaaed199e453..9e62c20fb5bc 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -13,7 +13,6 @@ #define pr_fmt(fmt) "g_ffs: " fmt #include -#include /* * kbuild is not very cooperative with respect to linking separately diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 2ee3a74056c9..59621ef7657d 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -22,7 +22,6 @@ #include #include -#include #include #include diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 16caf50e916d..0e2e357cc59e 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -91,10 +91,8 @@ static const struct usb_descriptor_header *otg_desc[] = { /* string IDs are assigned dynamically */ -static char manufacturer[50]; - static struct usb_string strings_dev[] = { - [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ @@ -165,16 +163,10 @@ static int __init hid_bind(struct usb_composite_dev *cdev) else device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099); - /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ - /* device descriptor strings: manufacturer, product */ - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); - status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) return status; diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 50da3c88cb06..9eb2be685803 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -29,10 +29,8 @@ #include -#include #include - /*-------------------------------------------------------------------------*/ #define DRIVER_DESC "Mass Storage Gadget" diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index c158706b5ab0..5bc5d96beaac 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -14,10 +14,8 @@ #include -#include #include - #if defined USB_ETH_RNDIS # undef USB_ETH_RNDIS #endif diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index 1a26452ce4ca..343f3d364ef8 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -20,8 +20,6 @@ /* #define VERBOSE_DEBUG */ #include -#include - #include "u_ether.h" @@ -95,12 +93,9 @@ static const struct usb_descriptor_header *otg_desc[] = { NULL, }; - /* string IDs are assigned dynamically */ -static char manufacturer[50]; - static struct usb_string strings_dev[] = { - [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, [USB_GADGET_SERIAL_IDX].s = "", { } /* end of list */ @@ -169,15 +164,10 @@ static int __init gncm_bind(struct usb_composite_dev *cdev) cpu_to_le16(0x0300 | 0x0099); } - /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ - /* device descriptor strings: manufacturer, product */ - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index 34b97f12b7da..465766e41442 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -16,7 +16,6 @@ */ #include -#include #include #include "u_serial.h" diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 3321a9df4862..9bd994203d3d 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -237,7 +236,6 @@ static const struct usb_descriptor_header *otg_desc[] = { /* descriptors that are built on-demand */ -static char manufacturer [50]; static char product_desc [40] = DRIVER_DESC; static char serial_num [40] = "1"; static char pnp_string [1024] = @@ -245,7 +243,7 @@ static char pnp_string [1024] = /* static strings, in UTF-8 */ static struct usb_string strings [] = { - [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = product_desc, [USB_GADGET_SERIAL_IDX].s = serial_num, { } /* end of list */ @@ -1165,10 +1163,6 @@ static int __init printer_bind_config(struct usb_configuration *c) device_desc.bcdDevice = cpu_to_le16(0xFFFF); } - snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); - if (iPNPstring) strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2); diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 768a38e896f7..bf12d55cd07b 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -11,7 +11,6 @@ */ #include -#include #include #include #include @@ -61,10 +60,8 @@ USB_GADGET_COMPOSITE_OPTIONS(); #define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX -static char manufacturer[50]; - static struct usb_string strings_dev[] = { - [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = GS_VERSION_NAME, [USB_GADGET_SERIAL_IDX].s = "", [STRING_DESCRIPTION_IDX].s = NULL /* updated; f(use_acm) */, @@ -171,10 +168,6 @@ static int __init gs_bind(struct usb_composite_dev *cdev) * contents can be overridden by the composite_dev glue. */ - /* device description: manufacturer, product */ - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index ee769c45498b..a837f3af2047 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -42,7 +42,6 @@ #include #include -#include #include #include "g_zero.h" @@ -139,13 +138,11 @@ const struct usb_descriptor_header *otg_desc[] = { #endif /* string IDs are assigned dynamically */ -static char manufacturer[50]; - /* default serial number takes at least two packets */ static char serial[] = "0123456789.0123456789.0123456789"; static struct usb_string strings_dev[] = { - [USB_GADGET_MANUFACTURER_IDX].s = manufacturer, + [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = longname, [USB_GADGET_SERIAL_IDX].s = serial, { } /* end of list */ @@ -305,10 +302,6 @@ static int __init zero_bind(struct usb_composite_dev *cdev) INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname); - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); - return 0; } diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 60f8815998bd..65ae0a3feb5b 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -358,7 +358,7 @@ struct usb_composite_dev { struct list_head configs; struct usb_composite_driver *driver; u8 next_string_id; - u8 manufacturer_override; + char *def_manufacturer; /* the gadget driver won't enable the data pullup * while the deactivation count is nonzero. -- cgit v1.2.3-59-g8ed1b From 721e2e91945bc2520d57d795dfe1b502ecec567c Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:27 +0200 Subject: usb: gadget: libcomposite: move composite.c into libcomposite This moves composite.c into libcomposite and updates all gadgets. Finally! Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Makefile | 3 ++- drivers/usb/gadget/acm_ms.c | 2 +- drivers/usb/gadget/audio.c | 11 +---------- drivers/usb/gadget/cdc2.c | 1 - drivers/usb/gadget/composite.c | 14 +++++++++++++- drivers/usb/gadget/ether.c | 2 -- drivers/usb/gadget/f_hid.c | 1 + drivers/usb/gadget/g_ffs.c | 3 --- drivers/usb/gadget/gmidi.c | 2 +- drivers/usb/gadget/hid.c | 5 ++--- drivers/usb/gadget/mass_storage.c | 3 +-- drivers/usb/gadget/multi.c | 3 --- drivers/usb/gadget/ncm.c | 4 ++-- drivers/usb/gadget/nokia.c | 2 -- drivers/usb/gadget/printer.c | 12 +----------- drivers/usb/gadget/serial.c | 2 -- drivers/usb/gadget/tcm_usb_gadget.c | 2 -- drivers/usb/gadget/webcam.c | 2 -- drivers/usb/gadget/zero.c | 2 -- 19 files changed, 25 insertions(+), 51 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 4fec0e8ee000..5c4a1330b498 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -5,7 +5,8 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG obj-$(CONFIG_USB_GADGET) += udc-core.o obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o -libcomposite-y := usbstring.o config.o epautoconf.o gadget_chips.o +libcomposite-y := usbstring.o config.o epautoconf.o +libcomposite-y += gadget_chips.o composite.o obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2272) += net2272.o obj-$(CONFIG_USB_NET2280) += net2280.o diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index d280f164887c..b0abc2518b38 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -15,6 +15,7 @@ */ #include +#include #include "u_serial.h" @@ -40,7 +41,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "composite.c" #include "u_serial.c" #include "f_acm.c" #include "f_mass_storage.c" diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 1f81e0f4fab9..1b9dee91d686 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -12,22 +12,13 @@ /* #define VERBOSE_DEBUG */ #include +#include #include #include "gadget_chips.h" #define DRIVER_DESC "Linux USB Audio Gadget" #define DRIVER_VERSION "Feb 2, 2012" -/*-------------------------------------------------------------------------*/ - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "composite.c" USB_GADGET_COMPOSITE_OPTIONS(); /* string IDs are assigned dynamically */ diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 4e2060bf35e3..ba38d2a43723 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -43,7 +43,6 @@ USB_GADGET_COMPOSITE_OPTIONS(); * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "composite.c" #include "u_serial.c" #include "f_acm.c" #include "f_ecm.c" diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index c7066cd4c95a..27ac36638827 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -154,6 +154,7 @@ ep_found: } return 0; } +EXPORT_SYMBOL_GPL(config_ep_by_speed); /** * usb_add_function() - add a function to a configuration @@ -212,6 +213,7 @@ done: function->name, function, value); return value; } +EXPORT_SYMBOL_GPL(usb_add_function); /** * usb_function_deactivate - prevent function and gadget enumeration @@ -248,6 +250,7 @@ int usb_function_deactivate(struct usb_function *function) spin_unlock_irqrestore(&cdev->lock, flags); return status; } +EXPORT_SYMBOL_GPL(usb_function_deactivate); /** * usb_function_activate - allow function and gadget enumeration @@ -278,6 +281,7 @@ int usb_function_activate(struct usb_function *function) spin_unlock_irqrestore(&cdev->lock, flags); return status; } +EXPORT_SYMBOL_GPL(usb_function_activate); /** * usb_interface_id() - allocate an unused interface ID @@ -314,6 +318,7 @@ int usb_interface_id(struct usb_configuration *config, } return -ENODEV; } +EXPORT_SYMBOL_GPL(usb_interface_id); static int config_buf(struct usb_configuration *config, enum usb_device_speed speed, void *buf, u8 type) @@ -754,6 +759,7 @@ done: config->bConfigurationValue, status); return status; } +EXPORT_SYMBOL_GPL(usb_add_config); static void remove_config(struct usb_composite_dev *cdev, struct usb_configuration *config) @@ -947,6 +953,7 @@ int usb_string_id(struct usb_composite_dev *cdev) } return -ENODEV; } +EXPORT_SYMBOL_GPL(usb_string_id); /** * usb_string_ids() - allocate unused string IDs in batch @@ -978,6 +985,7 @@ int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str) return 0; } +EXPORT_SYMBOL_GPL(usb_string_ids_tab); /** * usb_string_ids_n() - allocate unused string IDs in batch @@ -1006,7 +1014,7 @@ int usb_string_ids_n(struct usb_composite_dev *c, unsigned n) c->next_string_id += n; return next + 1; } - +EXPORT_SYMBOL_GPL(usb_string_ids_n); /*-------------------------------------------------------------------------*/ @@ -1572,6 +1580,7 @@ int usb_composite_probe(struct usb_composite_driver *driver) return usb_gadget_probe_driver(gadget_driver); } +EXPORT_SYMBOL_GPL(usb_composite_probe); /** * usb_composite_unregister() - unregister a composite driver @@ -1584,6 +1593,7 @@ void usb_composite_unregister(struct usb_composite_driver *driver) { usb_gadget_unregister_driver(&driver->gadget_driver); } +EXPORT_SYMBOL_GPL(usb_composite_unregister); /** * usb_composite_setup_continue() - Continue with the control transfer @@ -1620,6 +1630,7 @@ void usb_composite_setup_continue(struct usb_composite_dev *cdev) spin_unlock_irqrestore(&cdev->lock, flags); } +EXPORT_SYMBOL_GPL(usb_composite_setup_continue); static char *composite_default_mfr(struct usb_gadget *gadget) { @@ -1672,3 +1683,4 @@ void usb_composite_overwrite_options(struct usb_composite_dev *cdev, dev_str[USB_GADGET_PRODUCT_IDX].s = covr->product; } } +EXPORT_SYMBOL_GPL(usb_composite_overwrite_options); diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index a5c272067625..d7ec87e0bfcb 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -100,8 +100,6 @@ static inline bool has_rndis(void) * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "composite.c" - #include "f_ecm.c" #include "f_subset.c" #ifdef USB_ETH_RNDIS diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c index 77dbca099bcb..511e527178e2 100644 --- a/drivers/usb/gadget/f_hid.c +++ b/drivers/usb/gadget/f_hid.c @@ -17,6 +17,7 @@ #include #include #include +#include #include static int major, minors; diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 9e62c20fb5bc..3953dd4d7186 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -21,9 +21,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ - -#include "composite.c" - #if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS # if defined USB_ETH_RNDIS # undef USB_ETH_RNDIS diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 59621ef7657d..4181524d1c4b 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -30,13 +30,13 @@ #include #include +#include #include #include #include #include "gadget_chips.h" -#include "composite.c" #include "f_midi.c" /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 0e2e357cc59e..5fa1bfa8c6c6 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "gadget_chips.h" #define DRIVER_DESC "HID Gadget" @@ -34,9 +36,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ - -#include "composite.c" - #include "f_hid.c" diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 9eb2be685803..080e577773d5 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -30,6 +30,7 @@ #include #include +#include /*-------------------------------------------------------------------------*/ @@ -45,8 +46,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ - -#include "composite.c" #include "f_mass_storage.c" /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 5bc5d96beaac..9d2e75c017dc 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -40,9 +40,6 @@ MODULE_LICENSE("GPL"); * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ - -#include "composite.c" - #include "f_mass_storage.c" #include "u_serial.c" diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index 343f3d364ef8..b21ec269b8f5 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -20,6 +20,8 @@ /* #define VERBOSE_DEBUG */ #include +#include +#include #include "u_ether.h" @@ -34,8 +36,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "composite.c" - #include "f_ncm.c" #include "u_ether.c" diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index 465766e41442..ad0cc3473073 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -37,8 +37,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "composite.c" - #include "u_serial.c" #include "f_acm.c" #include "f_ecm.c" diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 9bd994203d3d..e394050afd02 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -37,22 +37,12 @@ #include #include +#include #include #include #include "gadget_chips.h" - -/* - * Kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "composite.c" - -/*-------------------------------------------------------------------------*/ USB_GADGET_COMPOSITE_OPTIONS(); #define DRIVER_DESC "Printer Gadget" diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index bf12d55cd07b..f17d4626af55 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -36,8 +36,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "composite.c" - #include "f_acm.c" #include "f_obex.c" #include "f_serial.c" diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index b56d57d59796..eaa1005377fc 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -25,8 +25,6 @@ #include #include -#include "composite.c" - #include "tcm_usb_gadget.h" USB_GADGET_COMPOSITE_OPTIONS(); diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index 03591194b17a..69cf5c2cd335 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c @@ -23,8 +23,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "composite.c" - #include "uvc_queue.c" #include "uvc_video.c" #include "uvc_v4l2.c" diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index a837f3af2047..0dabffa5f493 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -57,8 +57,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "composite.c" - #include "f_sourcesink.c" #include "f_loopback.c" -- cgit v1.2.3-59-g8ed1b From d80c304bcacaf340efa29364ed0107f5c30378c8 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 6 Sep 2012 20:11:28 +0200 Subject: usb: gadget: libcomposite: move MODULE_VERSION to composite.c MODULE_VERSION and AUTHOR looks better in composite.c than in usbstrings.c so I move it there. I put David Brownell as the module Author as I belive he wrote most of it. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 3 +++ drivers/usb/gadget/usbstring.c | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 27ac36638827..cacb273ba708 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1684,3 +1684,6 @@ void usb_composite_overwrite_options(struct usb_composite_dev *cdev, } } EXPORT_SYMBOL_GPL(usb_composite_overwrite_options); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("David Brownell"); diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index 24e9bbd255a7..1f49fce0f0b7 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c @@ -70,4 +70,3 @@ usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf) return buf [0]; } EXPORT_SYMBOL_GPL(usb_gadget_get_string); -MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From 162ca3ca613e02e115ec9c5273f94bd22dad0af2 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 7 Sep 2012 14:54:25 +0800 Subject: usb: gadget: at91_udc: move the dereference below the NULL test The dereference should be moved below the NULL test. spatch with a semantic match is used to found this. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/gadget/at91_udc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index c9e66dfb02e6..d95f6b079345 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -469,7 +469,7 @@ static int at91_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) { struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); - struct at91_udc *udc = ep->udc; + struct at91_udc *udc; u16 maxpacket; u32 tmp; unsigned long flags; @@ -484,6 +484,7 @@ static int at91_ep_enable(struct usb_ep *_ep, return -EINVAL; } + udc = ep->udc; if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) { DBG("bogus device state\n"); return -ESHUTDOWN; -- cgit v1.2.3-59-g8ed1b From 9c6d196d5aa35e07482f23c3e37755e7a82140e0 Mon Sep 17 00:00:00 2001 From: Fabio Porcedda Date: Fri, 7 Sep 2012 15:27:42 +0200 Subject: usb: gadget: at91_udc: fix dt support Don't fail the initialization check for the platform_data if there is avaiable an associated device tree node. Signed-off-by: Fabio Porcedda Signed-off-by: Felipe Balbi --- drivers/usb/gadget/at91_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index d95f6b079345..af931282843d 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1704,7 +1704,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) int retval; struct resource *res; - if (!dev->platform_data) { + if (!dev->platform_data && !pdev->dev.of_node) { /* small (so we copy it) but critical! */ DBG("missing platform_data\n"); return -ENODEV; -- cgit v1.2.3-59-g8ed1b From ed9cbda63d45638b69ce62412e3a3c7b00644835 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 09:16:07 +0200 Subject: usb: gadget: remove usb_gadget_controller_number() The bcdDevice field is defined as |Device release number in binary-coded decimal in the USB 2.0 specification. We use this field to distinguish the UDCs from each other. In theory this could be used on the host side to apply certain quirks if the "special" UDC in combination with this gadget is used. This hasn't been done as far as I am aware. In practice it would be better to fix the UDC driver before shipping since a later release might not need this quirk anymore. There are some driver in tree (on the host side) which use the bcdDevice field to figure out special workarounds for a given firmware revision. This seems to make sense. Therefore this patch converts all gadgets (except a few) to use the kernel version instead a random 2 or 3 plus the UDC number. The few that don't report kernel's version are: - webcam This one reports always a version 0x10 so allow it to do so in future. - nokia This one reports always 0x211. The comment says that this gadget works only if the UDC supports altsettings so I added a check for this. - serial This one reports 0x2400 + UDC number. Since the gadget version is 2.4 this could make sense. Therefore bcdDevice is 0x2400 here. I also remove various gadget_is_ macros which are unused. The remaining few macros should be moved to feature / bug bitfield. Acked-by: Michal Nazarewicz Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Makefile | 2 +- drivers/usb/gadget/acm_ms.c | 13 ----- drivers/usb/gadget/audio.c | 12 ----- drivers/usb/gadget/cdc2.c | 16 ------- drivers/usb/gadget/composite.c | 2 + drivers/usb/gadget/ether.c | 17 ------- drivers/usb/gadget/f_mass_storage.c | 15 +----- drivers/usb/gadget/file_storage.c | 14 ++---- drivers/usb/gadget/gadget_chips.c | 94 ------------------------------------- drivers/usb/gadget/gadget_chips.h | 23 --------- drivers/usb/gadget/gmidi.c | 16 +------ drivers/usb/gadget/hid.c | 8 +--- drivers/usb/gadget/multi.c | 11 +---- drivers/usb/gadget/ncm.c | 17 ------- drivers/usb/gadget/nokia.c | 14 +----- drivers/usb/gadget/printer.c | 11 ----- drivers/usb/gadget/serial.c | 22 +-------- drivers/usb/gadget/zero.c | 17 ------- include/linux/usb/composite.h | 11 +++++ 19 files changed, 24 insertions(+), 311 deletions(-) delete mode 100644 drivers/usb/gadget/gadget_chips.c (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 5c4a1330b498..307be5fa824c 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -6,7 +6,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG obj-$(CONFIG_USB_GADGET) += udc-core.o obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o libcomposite-y := usbstring.o config.o epautoconf.o -libcomposite-y += gadget_chips.o composite.o +libcomposite-y += composite.o obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2272) += net2272.o obj-$(CONFIG_USB_NET2280) += net2280.o diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index b0abc2518b38..5a7f289805ff 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -148,7 +148,6 @@ static struct usb_configuration acm_ms_config_driver = { static int __init acm_ms_bind(struct usb_composite_dev *cdev) { - int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; void *retp; @@ -165,18 +164,6 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) goto fail0; } - /* set bcdDevice */ - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) { - device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); - } else { - WARNING(cdev, "controller '%s' not recognized; trying %s\n", - gadget->name, - acm_ms_config_driver.label); - device_desc.bcdDevice = - cpu_to_le16(0x0300 | 0x0099); - } - /* * Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 1b9dee91d686..231b0efe8fdc 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c @@ -135,20 +135,8 @@ static struct usb_configuration audio_config_driver = { static int __init audio_bind(struct usb_composite_dev *cdev) { - int gcnum; int status; - gcnum = usb_gadget_controller_number(cdev->gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); - else { - ERROR(cdev, "controller '%s' not recognized; trying %s\n", - cdev->gadget->name, - audio_config_driver.label); - device_desc.bcdDevice = - __constant_cpu_to_le16(0x0300 | 0x0099); - } - status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index ba38d2a43723..1e4bb77f00bb 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -143,7 +143,6 @@ static struct usb_configuration cdc_config_driver = { static int __init cdc_bind(struct usb_composite_dev *cdev) { - int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; @@ -163,21 +162,6 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) if (status < 0) goto fail0; - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); - else { - /* We assume that can_support_ecm() tells the truth; - * but if the controller isn't recognized at all then - * that assumption is a bit more likely to be wrong. - */ - WARNING(cdev, "controller '%s' not recognized; trying %s\n", - gadget->name, - cdc_config_driver.label); - device_desc.bcdDevice = - cpu_to_le16(0x0300 | 0x0099); - } - /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index cacb273ba708..957f973dd96a 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1389,6 +1389,8 @@ static void update_unchanged_dev_desc(struct usb_device_descriptor *new, new->idProduct = idProduct; if (bcdDevice) new->bcdDevice = bcdDevice; + else + new->bcdDevice = cpu_to_le16(get_default_bcdDevice()); if (iSerialNumber) new->iSerialNumber = iSerialNumber; if (iManufacturer) diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index d7ec87e0bfcb..18c3f423706e 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -275,7 +275,6 @@ static struct usb_configuration eth_config_driver = { static int __init eth_bind(struct usb_composite_dev *cdev) { - int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; @@ -310,22 +309,6 @@ static int __init eth_bind(struct usb_composite_dev *cdev) device_desc.bNumConfigurations = 2; } - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); - else { - /* We assume that can_support_ecm() tells the truth; - * but if the controller isn't recognized at all then - * that assumption is a bit more likely to be wrong. - */ - dev_warn(&gadget->dev, - "controller '%s' not recognized; trying %s\n", - gadget->name, - eth_config_driver.label); - device_desc.bcdDevice = - cpu_to_le16(0x0300 | 0x0099); - } - /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 11150960d88b..3a7668bde3ef 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -348,7 +348,6 @@ struct fsg_config { const char *vendor_name; /* 8 characters or less */ const char *product_name; /* 16 characters or less */ - u16 release; char can_stall; }; @@ -2772,18 +2771,7 @@ buffhds_first_it: bh->next = common->buffhds; /* Prepare inquiryString */ - if (cfg->release != 0xffff) { - i = cfg->release; - } else { - i = usb_gadget_controller_number(gadget); - if (i >= 0) { - i = 0x0300 + i; - } else { - WARNING(common, "controller '%s' not recognized\n", - gadget->name); - i = 0x0399; - } - } + i = get_default_bcdDevice(); snprintf(common->inquiry_string, sizeof common->inquiry_string, "%-8s%-16s%04x", cfg->vendor_name ?: "Linux", /* Assume product name dependent on the first LUN */ @@ -3109,7 +3097,6 @@ fsg_config_from_params(struct fsg_config *cfg, /* Let MSF use defaults */ cfg->vendor_name = 0; cfg->product_name = 0; - cfg->release = 0xffff; cfg->ops = NULL; cfg->private_data = NULL; diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index ce362f7e39d3..3f7d640b6758 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -251,6 +251,7 @@ #include #include +#include #include #include @@ -3198,7 +3199,6 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) static int __init check_parameters(struct fsg_dev *fsg) { int prot; - int gcnum; /* Store the default values */ mod_data.transport_type = USB_PR_BULK; @@ -3213,16 +3213,8 @@ static int __init check_parameters(struct fsg_dev *fsg) if (gadget_is_at91(fsg->gadget)) mod_data.can_stall = 0; - if (mod_data.release == 0xffff) { // Parameter wasn't set - gcnum = usb_gadget_controller_number(fsg->gadget); - if (gcnum >= 0) - mod_data.release = 0x0300 + gcnum; - else { - WARNING(fsg, "controller '%s' not recognized\n", - fsg->gadget->name); - mod_data.release = 0x0399; - } - } + if (mod_data.release == 0xffff) + mod_data.release = get_default_bcdDevice(); prot = simple_strtol(mod_data.protocol_parm, NULL, 0); diff --git a/drivers/usb/gadget/gadget_chips.c b/drivers/usb/gadget/gadget_chips.c deleted file mode 100644 index 6387d43d3f8c..000000000000 --- a/drivers/usb/gadget/gadget_chips.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * USB device controllers have lots of quirks. Use these macros in - * gadget drivers or other code that needs to deal with them, and which - * autoconfigures instead of using early binding to the hardware. - * - * This SHOULD eventually work like the ARM mach_is_*() stuff, driven by - * some config file that gets updated as new hardware is supported. - * (And avoiding all runtime comparisons in typical one-choice configs!) - * - * NOTE: some of these controller drivers may not be available yet. - * Some are available on 2.4 kernels; several are available, but not - * yet pushed in the 2.6 mainline tree. - */ - -#include -#include - -#include "gadget_chips.h" - -/** - * usb_gadget_controller_number - support bcdDevice id convention - * @gadget: the controller being driven - * - * Return a 2-digit BCD value associated with the peripheral controller, - * suitable for use as part of a bcdDevice value, or a negative error code. - * - * NOTE: this convention is purely optional, and has no meaning in terms of - * any USB specification. If you want to use a different convention in your - * gadget driver firmware -- maybe a more formal revision ID -- feel free. - * - * Hosts see these bcdDevice numbers, and are allowed (but not encouraged!) - * to change their behavior accordingly. For example it might help avoiding - * some chip bug. - */ -int usb_gadget_controller_number(struct usb_gadget *gadget) -{ - if (gadget_is_net2280(gadget)) - return 0x01; - else if (gadget_is_dummy(gadget)) - return 0x02; - else if (gadget_is_pxa(gadget)) - return 0x03; - else if (gadget_is_goku(gadget)) - return 0x06; - else if (gadget_is_omap(gadget)) - return 0x08; - else if (gadget_is_pxa27x(gadget)) - return 0x11; - else if (gadget_is_s3c2410(gadget)) - return 0x12; - else if (gadget_is_at91(gadget)) - return 0x13; - else if (gadget_is_imx(gadget)) - return 0x14; - else if (gadget_is_musbhdrc(gadget)) - return 0x16; - else if (gadget_is_atmel_usba(gadget)) - return 0x18; - else if (gadget_is_fsl_usb2(gadget)) - return 0x19; - else if (gadget_is_amd5536udc(gadget)) - return 0x20; - else if (gadget_is_m66592(gadget)) - return 0x21; - else if (gadget_is_fsl_qe(gadget)) - return 0x22; - else if (gadget_is_ci13xxx_pci(gadget)) - return 0x23; - else if (gadget_is_langwell(gadget)) - return 0x24; - else if (gadget_is_r8a66597(gadget)) - return 0x25; - else if (gadget_is_s3c_hsotg(gadget)) - return 0x26; - else if (gadget_is_pch(gadget)) - return 0x27; - else if (gadget_is_ci13xxx_msm(gadget)) - return 0x28; - else if (gadget_is_renesas_usbhs(gadget)) - return 0x29; - else if (gadget_is_s3c_hsudc(gadget)) - return 0x30; - else if (gadget_is_net2272(gadget)) - return 0x31; - else if (gadget_is_dwc3(gadget)) - return 0x32; - else if (gadget_is_lpc32xx(gadget)) - return 0x33; - else if (gadget_is_bcm63xx(gadget)) - return 0x34; - - return -ENOENT; -} -EXPORT_SYMBOL_GPL(usb_gadget_controller_number); diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index c7055cd1e92e..bcd04bc66b98 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -27,35 +27,12 @@ * If you have forgotten the alphabetical order let VIM/EMACS * do that for you. */ -#define gadget_is_amd5536udc(g) (!strcmp("amd5536udc", (g)->name)) #define gadget_is_at91(g) (!strcmp("at91_udc", (g)->name)) -#define gadget_is_atmel_usba(g) (!strcmp("atmel_usba_udc", (g)->name)) -#define gadget_is_bcm63xx(g) (!strcmp("bcm63xx_udc", (g)->name)) -#define gadget_is_ci13xxx_msm(g) (!strcmp("ci13xxx_msm", (g)->name)) -#define gadget_is_ci13xxx_pci(g) (!strcmp("ci13xxx_pci", (g)->name)) -#define gadget_is_dummy(g) (!strcmp("dummy_udc", (g)->name)) -#define gadget_is_dwc3(g) (!strcmp("dwc3-gadget", (g)->name)) -#define gadget_is_fsl_qe(g) (!strcmp("fsl_qe_udc", (g)->name)) -#define gadget_is_fsl_usb2(g) (!strcmp("fsl-usb2-udc", (g)->name)) #define gadget_is_goku(g) (!strcmp("goku_udc", (g)->name)) -#define gadget_is_imx(g) (!strcmp("imx_udc", (g)->name)) -#define gadget_is_langwell(g) (!strcmp("langwell_udc", (g)->name)) -#define gadget_is_lpc32xx(g) (!strcmp("lpc32xx_udc", (g)->name)) -#define gadget_is_m66592(g) (!strcmp("m66592_udc", (g)->name)) #define gadget_is_musbhdrc(g) (!strcmp("musb-hdrc", (g)->name)) -#define gadget_is_net2272(g) (!strcmp("net2272", (g)->name)) #define gadget_is_net2280(g) (!strcmp("net2280", (g)->name)) -#define gadget_is_omap(g) (!strcmp("omap_udc", (g)->name)) -#define gadget_is_pch(g) (!strcmp("pch_udc", (g)->name)) #define gadget_is_pxa(g) (!strcmp("pxa25x_udc", (g)->name)) #define gadget_is_pxa27x(g) (!strcmp("pxa27x_udc", (g)->name)) -#define gadget_is_r8a66597(g) (!strcmp("r8a66597_udc", (g)->name)) -#define gadget_is_renesas_usbhs(g) (!strcmp("renesas_usbhs_udc", (g)->name)) -#define gadget_is_s3c2410(g) (!strcmp("s3c2410_udc", (g)->name)) -#define gadget_is_s3c_hsotg(g) (!strcmp("s3c-hsotg", (g)->name)) -#define gadget_is_s3c_hsudc(g) (!strcmp("s3c-hsudc", (g)->name)) - -int usb_gadget_controller_number(struct usb_gadget *gadget); /** * gadget_supports_altsettings - return true if altsettings work diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 4181524d1c4b..881aab86ae99 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -137,8 +137,7 @@ static int __init midi_bind_config(struct usb_configuration *c) static int __init midi_bind(struct usb_composite_dev *cdev) { - struct usb_gadget *gadget = cdev->gadget; - int gcnum, status; + int status; status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) @@ -147,19 +146,6 @@ static int __init midi_bind(struct usb_composite_dev *cdev) device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; midi_config.iConfiguration = strings_dev[STRING_DESCRIPTION_IDX].id; - gcnum = usb_gadget_controller_number(gadget); - if (gcnum < 0) { - /* gmidi is so simple (no altsettings) that - * it SHOULD NOT have problems with bulk-capable hardware. - * so warn about unrecognized controllers, don't panic. - */ - pr_warning("%s: controller '%s' not recognized\n", - __func__, gadget->name); - device_desc.bcdDevice = cpu_to_le16(0x9999); - } else { - device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); - } - status = usb_add_config(cdev, &midi_config, midi_bind_config); if (status < 0) return status; diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 5fa1bfa8c6c6..74130f6c12c0 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -143,7 +143,7 @@ static int __init hid_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; struct list_head *tmp; - int status, gcnum, funcs = 0; + int status, funcs = 0; list_for_each(tmp, &hidg_func_list) funcs++; @@ -156,12 +156,6 @@ static int __init hid_bind(struct usb_composite_dev *cdev) if (status < 0) return status; - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); - else - device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099); - /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 9d2e75c017dc..88472bf7dbb7 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -247,7 +247,7 @@ static int cdc_config_register(struct usb_composite_dev *cdev) static int __ref multi_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; - int status, gcnum; + int status; if (!can_support_ecm(cdev->gadget)) { dev_err(&gadget->dev, "controller '%s' not usable\n", @@ -275,15 +275,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) } } - /* set bcdDevice */ - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) { - device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); - } else { - WARNING(cdev, "controller '%s' not recognized\n", gadget->name); - device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099); - } - /* allocate string IDs */ status = usb_string_ids_tab(cdev, strings_dev); if (unlikely(status < 0)) diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c index b21ec269b8f5..a22ad9af0565 100644 --- a/drivers/usb/gadget/ncm.c +++ b/drivers/usb/gadget/ncm.c @@ -139,7 +139,6 @@ static struct usb_configuration ncm_config_driver = { static int __init gncm_bind(struct usb_composite_dev *cdev) { - int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; @@ -148,22 +147,6 @@ static int __init gncm_bind(struct usb_composite_dev *cdev) if (status < 0) return status; - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); - else { - /* We assume that can_support_ecm() tells the truth; - * but if the controller isn't recognized at all then - * that assumption is a bit more likely to be wrong. - */ - dev_warn(&gadget->dev, - "controller '%s' not recognized; trying %s\n", - gadget->name, - ncm_config_driver.label); - device_desc.bcdDevice = - cpu_to_le16(0x0300 | 0x0099); - } - /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. */ diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index ad0cc3473073..661600abace8 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -84,6 +84,7 @@ static struct usb_device_descriptor device_desc = { .bDeviceClass = USB_CLASS_COMM, .idVendor = __constant_cpu_to_le16(NOKIA_VENDOR_ID), .idProduct = __constant_cpu_to_le16(NOKIA_PRODUCT_ID), + .bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM), /* .iManufacturer = DYNAMIC */ /* .iProduct = DYNAMIC */ .bNumConfigurations = 1, @@ -145,7 +146,6 @@ static struct usb_configuration nokia_config_100ma_driver = { static int __init nokia_bind(struct usb_composite_dev *cdev) { - int gcnum; struct usb_gadget *gadget = cdev->gadget; int status; @@ -170,18 +170,8 @@ static int __init nokia_bind(struct usb_composite_dev *cdev) nokia_config_500ma_driver.iConfiguration = status; nokia_config_100ma_driver.iConfiguration = status; - /* set up other descriptors */ - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM); - else { - /* this should only work with hw that supports altsettings - * and several endpoints, anything else, panic. - */ - pr_err("nokia_bind: controller '%s' not recognized\n", - gadget->name); + if (!gadget_supports_altsettings(gadget)) goto err_usb; - } /* finally register the configuration */ status = usb_add_config(cdev, &nokia_config_500ma_driver, diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index e394050afd02..e156e3f26727 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -1101,7 +1101,6 @@ static int __init printer_bind_config(struct usb_configuration *c) struct usb_gadget *gadget = c->cdev->gadget; struct printer_dev *dev; int status = -ENOMEM; - int gcnum; size_t len; u32 i; struct usb_request *req; @@ -1143,16 +1142,6 @@ static int __init printer_bind_config(struct usb_configuration *c) goto fail; } - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) { - device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); - } else { - dev_warn(&gadget->dev, "controller '%s' not recognized\n", - gadget->name); - /* unrecognized, but safe unless bulk is REALLY quirky */ - device_desc.bcdDevice = - cpu_to_le16(0xFFFF); - } if (iPNPstring) strlcpy(&pnp_string[2], iPNPstring, (sizeof pnp_string)-2); diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index f17d4626af55..942067327d88 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -86,7 +86,7 @@ static struct usb_device_descriptor device_desc = { /* .bMaxPacketSize0 = f(hardware) */ .idVendor = cpu_to_le16(GS_VENDOR_ID), /* .idProduct = f(use_acm) */ - /* .bcdDevice = f(hardware) */ + .bcdDevice = cpu_to_le16(GS_VERSION_NUM << 16), /* .iManufacturer = DYNAMIC */ /* .iProduct = DYNAMIC */ .bNumConfigurations = 1, @@ -154,8 +154,6 @@ static struct usb_configuration serial_config_driver = { static int __init gs_bind(struct usb_composite_dev *cdev) { - int gcnum; - struct usb_gadget *gadget = cdev->gadget; int status; status = gserial_setup(cdev->gadget, n_ports); @@ -174,24 +172,6 @@ static int __init gs_bind(struct usb_composite_dev *cdev) status = strings_dev[STRING_DESCRIPTION_IDX].id; serial_config_driver.iConfiguration = status; - /* set up other descriptors */ - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(GS_VERSION_NUM | gcnum); - else { - /* this is so simple (for now, no altsettings) that it - * SHOULD NOT have problems with bulk-capable hardware. - * so warn about unrcognized controllers -- don't panic. - * - * things like configuration and altsetting numbering - * can need hardware-specific attention though. - */ - pr_warning("gs_bind: controller '%s' not recognized\n", - gadget->name); - device_desc.bcdDevice = - cpu_to_le16(GS_VERSION_NUM | 0x0099); - } - if (gadget_is_otg(cdev->gadget)) { serial_config_driver.descriptors = otg_desc; serial_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 0dabffa5f493..6bf4c0611365 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -253,8 +253,6 @@ static void zero_resume(struct usb_composite_dev *cdev) static int __init zero_bind(struct usb_composite_dev *cdev) { - int gcnum; - struct usb_gadget *gadget = cdev->gadget; int status; /* Allocate string descriptor numbers ... note that string @@ -281,21 +279,6 @@ static int __init zero_bind(struct usb_composite_dev *cdev) loopback_add(cdev, autoresume != 0); } - gcnum = usb_gadget_controller_number(gadget); - if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); - else { - /* gadget zero is so simple (for now, no altsettings) that - * it SHOULD NOT have problems with bulk-capable hardware. - * so just warn about unrcognized controllers -- don't panic. - * - * things like configuration and altsetting numbering - * can need hardware-specific attention though. - */ - pr_warning("%s: controller '%s' not recognized\n", - longname, gadget->name); - device_desc.bcdDevice = cpu_to_le16(0x9999); - } usb_composite_overwrite_options(cdev, &coverwrite); INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname); diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 65ae0a3feb5b..f8dda0621800 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -34,6 +34,8 @@ * the composite model the host can use both functions at the same time. */ +#include +#include #include #include @@ -418,6 +420,15 @@ struct usb_composite_overwrite { void usb_composite_overwrite_options(struct usb_composite_dev *cdev, struct usb_composite_overwrite *covr); +static inline u16 get_default_bcdDevice(void) +{ + u16 bcdDevice; + + bcdDevice = bin2bcd((LINUX_VERSION_CODE >> 16 & 0xff)) << 8; + bcdDevice |= bin2bcd((LINUX_VERSION_CODE >> 8 & 0xff)); + return bcdDevice; +} + /* messaging utils */ #define DBG(d, fmt, args...) \ dev_dbg(&(d)->gadget->dev , fmt , ## args) -- cgit v1.2.3-59-g8ed1b From 9830317a3f97afc358949ffa87529ee9da49bb44 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 16:30:50 +0200 Subject: usb: gadget: add module.h to u_ether.c Spotted by Fengguang Wu: |In file included from drivers/usb/gadget/ether.c:110:0: |drivers/usb/gadget/u_ether.c:87:21: error: expected ')' before 'uint' |drivers/usb/gadget/u_ether.c:88:25: error: expected ')' before string constant This is because u_ether.c relied on having module.h included somewhere. This isn't the case since composite.c is no longer included. Reported-by: Fengguang Wu Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/u_ether.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 1154a99dc8db..41b17d18ddc4 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -14,6 +14,7 @@ /* #define VERBOSE_DEBUG */ #include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 5c4d46eb89fe99011a02048533857345d9e8b506 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 10 Sep 2012 19:06:44 +0200 Subject: usb: gadget serial: don't shift bcd version left by 16 Fengguang Wu reported: |drivers/usb/gadget/serial.c:89:22: sparse: cast truncates bits from |constant value (24000000 becomes 0) I obviously let the version number shift away. Since the version is a 16bit number it can be applied as it. Cc: fengguang.wu@intel.com Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 942067327d88..44752f531e85 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -86,7 +86,7 @@ static struct usb_device_descriptor device_desc = { /* .bMaxPacketSize0 = f(hardware) */ .idVendor = cpu_to_le16(GS_VENDOR_ID), /* .idProduct = f(use_acm) */ - .bcdDevice = cpu_to_le16(GS_VERSION_NUM << 16), + .bcdDevice = cpu_to_le16(GS_VERSION_NUM), /* .iManufacturer = DYNAMIC */ /* .iProduct = DYNAMIC */ .bNumConfigurations = 1, -- cgit v1.2.3-59-g8ed1b