diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-04 21:26:27 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-04 21:26:27 -0800 |
commit | 3d6f47801c34e42da26e2b6b29706f0bfe423978 (patch) | |
tree | 98062d64ec5d1f4034f67265c7d933cf6c04aec6 /drivers/usb/gadget | |
parent | e0700ce70921fbe3d1913968c663beb9df2b01a9 (diff) | |
parent | 0bbc367e21bfeea33230d893be4fa3a3ff9bcb48 (diff) | |
download | lwn-3d6f47801c34e42da26e2b6b29706f0bfe423978.tar.gz lwn-3d6f47801c34e42da26e2b6b29706f0bfe423978.zip |
Merge tag 'usb-4.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB updates from Greg KH:
"Here is the big USB patchset for 4.4-rc1.
As usual, most of the changes are in the gadget subsystem, and we
removed a host controller for a device that is no longer in existance,
and probably never was even made public. There is also other minor
driver updates and new device ids, full details in the changelog.
All of these have been in linux-next for a while"
* tag 'usb-4.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (233 commits)
USB: core: Codestyle fix in urb.c
usb: misc: usb3503: Use i2c_add_driver helper macro
usb: host: lpc32xx: don't unregister phy device
usb: host: lpc32xx: balance clk enable/disable on removal
usb: host: lpc32xx: fix warnings caused by enabling unprepared clock
uwb: drp: Use setup_timer
uwb: neh: Use setup_timer
uwb: rsv: Use setup_timer
USB: qcserial: add Sierra Wireless MC74xx/EM74xx
usb: chipidea: otg: don't wait vbus drops below BSV when starts host
chipidea: ci_hdrc_pci: use PCI_VDEVICE() instead of PCI_DEVICE()
doc: dt-binding: ci-hdrc-usb2: split vendor specific properties
usb: chipidea: imx: add imx6ul usb support
doc: dt-binding: ci-hdrc-usb2: improve property description
usb: chipidea: imx: add usb support for imx7d
Doc: usb: ci-hdrc-usb2: Add phy-clkgate-delay-us entry
usb: chipidea: Add support for 'phy-clkgate-delay-us' property
usb: chipidea: Use extcon framework for VBUS and ID detect
usb: gadget: net2280: restore ep_cfg after defect7374 workaround
usb: dwc2: host: Fix use after free w/ simultaneous irqs
...
Diffstat (limited to 'drivers/usb/gadget')
32 files changed, 594 insertions, 730 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bcf83c0a6e62..33834aa09ed4 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -113,7 +113,7 @@ config USB_GADGET_VBUS_DRAW config USB_GADGET_STORAGE_NUM_BUFFERS int "Number of storage pipeline buffers" - range 2 4 + range 2 32 default 2 help Usually 2 buffers are enough to establish a good buffering diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index b474499839d3..8b14c2a13ac5 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -839,9 +839,7 @@ int usb_add_config(struct usb_composite_dev *cdev, } } - /* set_alt(), or next bind(), sets up - * ep->driver_data as needed. - */ + /* set_alt(), or next bind(), sets up ep->claimed as needed */ usb_ep_autoconfig_reset(cdev->gadget); done: @@ -1506,6 +1504,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) } else { cdev->desc.bcdUSB = cpu_to_le16(0x0210); } + } else { + cdev->desc.bcdUSB = cpu_to_le16(0x0200); } value = min(w_length, (u16) sizeof cdev->desc); diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 6399c106a3a5..30fdab0ae383 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -53,13 +53,13 @@ * the restrictions that may apply. Some combinations of driver * and hardware won't be able to autoconfigure. * - * On success, this returns an un-claimed usb_ep, and modifies the endpoint + * On success, this returns an claimed usb_ep, and modifies the endpoint * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value * is initialized as if the endpoint were used at full speed and * the bmAttribute field in the ep companion descriptor is * updated with the assigned number of streams if it is * different from the original value. To prevent the endpoint - * from being returned by a later autoconfig call, claim it by + * from being returned by a later autoconfig call, claims it by * assigning ep->claimed to true. * * On failure, this returns a null endpoint descriptor. @@ -154,10 +154,10 @@ EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss); * USB controller, and it can't know all the restrictions that may apply. * Some combinations of driver and hardware won't be able to autoconfigure. * - * On success, this returns an un-claimed usb_ep, and modifies the endpoint + * On success, this returns an claimed usb_ep, and modifies the endpoint * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value * is initialized as if the endpoint were used at full speed. To prevent - * the endpoint from being returned by a later autoconfig call, claim it + * the endpoint from being returned by a later autoconfig call, claims it * by assigning ep->claimed to true. * * On failure, this returns a null endpoint descriptor. @@ -172,6 +172,23 @@ struct usb_ep *usb_ep_autoconfig( EXPORT_SYMBOL_GPL(usb_ep_autoconfig); /** + * usb_ep_autoconfig_release - releases endpoint and set it to initial state + * @ep: endpoint which should be released + * + * This function can be used during function bind for endpoints obtained + * from usb_ep_autoconfig(). It unclaims endpoint claimed by + * usb_ep_autoconfig() to make it available for other functions. Endpoint + * which was released is no longer invalid and shouldn't be used in + * context of function which released it. + */ +void usb_ep_autoconfig_release(struct usb_ep *ep) +{ + ep->claimed = false; + ep->driver_data = NULL; +} +EXPORT_SYMBOL_GPL(usb_ep_autoconfig_release); + +/** * usb_ep_autoconfig_reset - reset endpoint autoconfig state * @gadget: device for which autoconfig state will be reset * diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index be9df09fde26..22e723d12d36 100644 --- a/drivers/usb/gadget/function/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c @@ -428,21 +428,18 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0, so this is an activation or a reset */ if (intf == acm->ctrl_id) { - if (acm->notify->driver_data) { - dev_vdbg(&cdev->gadget->dev, - "reset acm control interface %d\n", intf); - usb_ep_disable(acm->notify); - } + dev_vdbg(&cdev->gadget->dev, + "reset acm control interface %d\n", intf); + usb_ep_disable(acm->notify); if (!acm->notify->desc) if (config_ep_by_speed(cdev->gadget, f, acm->notify)) return -EINVAL; usb_ep_enable(acm->notify); - acm->notify->driver_data = acm; } else if (intf == acm->data_id) { - if (acm->port.in->driver_data) { + if (acm->notify->enabled) { dev_dbg(&cdev->gadget->dev, "reset acm ttyGS%d\n", acm->port_num); gserial_disconnect(&acm->port); @@ -475,7 +472,6 @@ static void acm_disable(struct usb_function *f) dev_dbg(&cdev->gadget->dev, "acm ttyGS%d deactivated\n", acm->port_num); gserial_disconnect(&acm->port); usb_ep_disable(acm->notify); - acm->notify->driver_data = NULL; } /*-------------------------------------------------------------------------*/ @@ -655,19 +651,16 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; acm->port.in = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc); if (!ep) goto fail; acm->port.out = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc); if (!ep) goto fail; acm->notify = ep; - ep->driver_data = cdev; /* claim */ /* allocate notification */ acm->notify_req = gs_alloc_req(ep, @@ -709,14 +702,6 @@ fail: if (acm->notify_req) gs_free_req(acm->notify, acm->notify_req); - /* we might as well release our claims on endpoints */ - if (acm->notify) - acm->notify->driver_data = NULL; - if (acm->port.out) - acm->port.out->driver_data = NULL; - if (acm->port.in) - acm->port.in->driver_data = NULL; - ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); return status; diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index 7b7424f10ddd..4abca70cdaab 100644 --- a/drivers/usb/gadget/function/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c @@ -541,24 +541,21 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt != 0) goto fail; - if (ecm->notify->driver_data) { - VDBG(cdev, "reset ecm control %d\n", intf); - usb_ep_disable(ecm->notify); - } + VDBG(cdev, "reset ecm control %d\n", intf); + usb_ep_disable(ecm->notify); if (!(ecm->notify->desc)) { VDBG(cdev, "init ecm ctrl %d\n", intf); if (config_ep_by_speed(cdev->gadget, f, ecm->notify)) goto fail; } usb_ep_enable(ecm->notify); - ecm->notify->driver_data = ecm; /* Data interface has two altsettings, 0 and 1 */ } else if (intf == ecm->data_id) { if (alt > 1) goto fail; - if (ecm->port.in_ep->driver_data) { + if (ecm->port.in_ep->enabled) { DBG(cdev, "reset ecm\n"); gether_disconnect(&ecm->port); } @@ -618,7 +615,7 @@ static int ecm_get_alt(struct usb_function *f, unsigned intf) if (intf == ecm->ctrl_id) return 0; - return ecm->port.in_ep->driver_data ? 1 : 0; + return ecm->port.in_ep->enabled ? 1 : 0; } static void ecm_disable(struct usb_function *f) @@ -628,14 +625,11 @@ static void ecm_disable(struct usb_function *f) DBG(cdev, "ecm deactivated\n"); - if (ecm->port.in_ep->driver_data) + if (ecm->port.in_ep->enabled) gether_disconnect(&ecm->port); - if (ecm->notify->driver_data) { - usb_ep_disable(ecm->notify); - ecm->notify->driver_data = NULL; - ecm->notify->desc = NULL; - } + usb_ep_disable(ecm->notify); + ecm->notify->desc = NULL; } /*-------------------------------------------------------------------------*/ @@ -750,13 +744,11 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; ecm->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc); if (!ep) goto fail; ecm->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ /* NOTE: a status/notification endpoint is *OPTIONAL* but we * don't treat it that way. It's simpler, and some newer CDC @@ -766,7 +758,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; ecm->notify = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -820,14 +811,6 @@ fail: usb_ep_free_request(ecm->notify, ecm->notify_req); } - /* we might as well release our claims on endpoints */ - if (ecm->notify) - ecm->notify->driver_data = NULL; - if (ecm->port.out_ep) - ecm->port.out_ep->driver_data = NULL; - if (ecm->port.in_ep) - ecm->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index c9e90de5bdd9..9a55757c729b 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -195,11 +195,8 @@ static int eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt) goto fail; if (intf == eem->ctrl_id) { - - if (eem->port.in_ep->driver_data) { - DBG(cdev, "reset eem\n"); - gether_disconnect(&eem->port); - } + DBG(cdev, "reset eem\n"); + gether_disconnect(&eem->port); if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) { DBG(cdev, "init eem\n"); @@ -237,7 +234,7 @@ static void eem_disable(struct usb_function *f) DBG(cdev, "eem deactivated\n"); - if (eem->port.in_ep->driver_data) + if (eem->port.in_ep->enabled) gether_disconnect(&eem->port); } @@ -293,13 +290,11 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; eem->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_out_desc); if (!ep) goto fail; eem->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -325,11 +320,6 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - if (eem->port.out_ep) - eem->port.out_ep->driver_data = NULL; - if (eem->port.in_ep) - eem->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 6df9715a4bcd..21fcf18f53a0 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -492,10 +492,7 @@ static void hidg_disable(struct usb_function *f) struct f_hidg_req_list *list, *next; usb_ep_disable(hidg->in_ep); - hidg->in_ep->driver_data = NULL; - usb_ep_disable(hidg->out_ep); - hidg->out_ep->driver_data = NULL; list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) { list_del(&list->list); @@ -513,8 +510,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (hidg->in_ep != NULL) { /* restart endpoint */ - if (hidg->in_ep->driver_data != NULL) - usb_ep_disable(hidg->in_ep); + usb_ep_disable(hidg->in_ep); status = config_ep_by_speed(f->config->cdev->gadget, f, hidg->in_ep); @@ -533,8 +529,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (hidg->out_ep != NULL) { /* restart endpoint */ - if (hidg->out_ep->driver_data != NULL) - usb_ep_disable(hidg->out_ep); + usb_ep_disable(hidg->out_ep); status = config_ep_by_speed(f->config->cdev->gadget, f, hidg->out_ep); @@ -566,7 +561,6 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) hidg->out_ep->name, status); } else { usb_ep_disable(hidg->out_ep); - hidg->out_ep->driver_data = NULL; status = -ENOMEM; goto fail; } @@ -614,13 +608,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc); if (!ep) goto fail; - ep->driver_data = c->cdev; /* claim */ hidg->in_ep = ep; ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc); if (!ep) goto fail; - ep->driver_data = c->cdev; /* claim */ hidg->out_ep = ep; /* preallocate request and buffer */ diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index 6e2fe63b9267..6b2102bc0699 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -34,6 +34,9 @@ struct f_loopback { struct usb_ep *in_ep; struct usb_ep *out_ep; + + unsigned qlen; + unsigned buflen; }; static inline struct f_loopback *func_to_loop(struct usb_function *f) @@ -41,13 +44,10 @@ static inline struct f_loopback *func_to_loop(struct usb_function *f) return container_of(f, struct f_loopback, function); } -static unsigned qlen; -static unsigned buflen; - /*-------------------------------------------------------------------------*/ static struct usb_interface_descriptor loopback_intf = { - .bLength = sizeof loopback_intf, + .bLength = sizeof(loopback_intf), .bDescriptorType = USB_DT_INTERFACE, .bNumEndpoints = 2, @@ -195,12 +195,10 @@ autoconf_fail: f->name, cdev->gadget->name); return -ENODEV; } - loop->in_ep->driver_data = cdev; /* claim */ loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc); if (!loop->out_ep) goto autoconf_fail; - loop->out_ep->driver_data = cdev; /* claim */ /* support high speed hardware */ hs_loop_source_desc.bEndpointAddress = @@ -245,22 +243,38 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) int status = req->status; switch (status) { - case 0: /* normal completion? */ if (ep == loop->out_ep) { - req->zero = (req->actual < req->length); - req->length = req->actual; + /* + * We received some data from the host so let's + * queue it so host can read the from our in ep + */ + struct usb_request *in_req = req->context; + + in_req->zero = (req->actual < req->length); + in_req->length = req->actual; + ep = loop->in_ep; + req = in_req; + } else { + /* + * We have just looped back a bunch of data + * to host. Now let's wait for some more data. + */ + req = req->context; + ep = loop->out_ep; } - /* queue the buffer for some later OUT packet */ - req->length = buflen; + /* queue the buffer back to host or for next bunch of data */ status = usb_ep_queue(ep, req, GFP_ATOMIC); - if (status == 0) + if (status == 0) { return; + } else { + ERROR(cdev, "Unable to loop back buffer to %s: %d\n", + ep->name, status); + goto free_req; + } /* "should never get here" */ - /* FALLTHROUGH */ - default: ERROR(cdev, "%s loop complete --> %d, %d/%d\n", ep->name, status, req->actual, req->length); @@ -274,6 +288,10 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) case -ECONNABORTED: /* hardware forced ep reset */ case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN: /* disconnect from host */ +free_req: + usb_ep_free_request(ep == loop->in_ep ? + loop->out_ep : loop->in_ep, + req->context); free_ep_req(ep, req); return; } @@ -290,53 +308,77 @@ static void disable_loopback(struct f_loopback *loop) static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len) { - return alloc_ep_req(ep, len, buflen); + struct f_loopback *loop = ep->driver_data; + + return alloc_ep_req(ep, len, loop->buflen); } -static int enable_endpoint(struct usb_composite_dev *cdev, struct f_loopback *loop, - struct usb_ep *ep) +static int alloc_requests(struct usb_composite_dev *cdev, + struct f_loopback *loop) { - struct usb_request *req; - unsigned i; - int result; - - /* - * one endpoint writes data back IN to the host while another endpoint - * just reads OUT packets - */ - result = config_ep_by_speed(cdev->gadget, &(loop->function), ep); - if (result) - goto fail0; - result = usb_ep_enable(ep); - if (result < 0) - goto fail0; - ep->driver_data = loop; + struct usb_request *in_req, *out_req; + int i; + int result = 0; /* * allocate a bunch of read buffers and queue them all at once. - * we buffer at most 'qlen' transfers; fewer if any need more - * than 'buflen' bytes each. + * we buffer at most 'qlen' transfers; We allocate buffers only + * for out transfer and reuse them in IN transfers to implement + * our loopback functionality */ - for (i = 0; i < qlen && result == 0; i++) { - req = lb_alloc_ep_req(ep, 0); - if (!req) - goto fail1; + for (i = 0; i < loop->qlen && result == 0; i++) { + result = -ENOMEM; + + in_req = usb_ep_alloc_request(loop->in_ep, GFP_KERNEL); + if (!in_req) + goto fail; + + out_req = lb_alloc_ep_req(loop->out_ep, 0); + if (!out_req) + goto fail_in; - req->complete = loopback_complete; - result = usb_ep_queue(ep, req, GFP_ATOMIC); + in_req->complete = loopback_complete; + out_req->complete = loopback_complete; + + in_req->buf = out_req->buf; + /* length will be set in complete routine */ + in_req->context = out_req; + out_req->context = in_req; + + result = usb_ep_queue(loop->out_ep, out_req, GFP_ATOMIC); if (result) { ERROR(cdev, "%s queue req --> %d\n", - ep->name, result); - goto fail1; + loop->out_ep->name, result); + goto fail_out; } } return 0; -fail1: - usb_ep_disable(ep); +fail_out: + free_ep_req(loop->out_ep, out_req); +fail_in: + usb_ep_free_request(loop->in_ep, in_req); +fail: + return result; +} + +static int enable_endpoint(struct usb_composite_dev *cdev, + struct f_loopback *loop, struct usb_ep *ep) +{ + int result; + + result = config_ep_by_speed(cdev->gadget, &(loop->function), ep); + if (result) + goto out; -fail0: + result = usb_ep_enable(ep); + if (result < 0) + goto out; + ep->driver_data = loop; + result = 0; + +out: return result; } @@ -347,13 +389,24 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop) result = enable_endpoint(cdev, loop, loop->in_ep); if (result) - return result; + goto out; result = enable_endpoint(cdev, loop, loop->out_ep); if (result) - return result; + goto disable_in; + + result = alloc_requests(cdev, loop); + if (result) + goto disable_out; DBG(cdev, "%s enabled\n", loop->function.name); + return 0; + +disable_out: + usb_ep_disable(loop->out_ep); +disable_in: + usb_ep_disable(loop->in_ep); +out: return result; } @@ -364,8 +417,7 @@ static int loopback_set_alt(struct usb_function *f, struct usb_composite_dev *cdev = f->config->cdev; /* we know alt is zero */ - if (loop->in_ep->driver_data) - disable_loopback(loop); + disable_loopback(loop); return enable_loopback(cdev, loop); } @@ -391,10 +443,10 @@ static struct usb_function *loopback_alloc(struct usb_function_instance *fi) lb_opts->refcnt++; mutex_unlock(&lb_opts->lock); - buflen = lb_opts->bulk_buflen; - qlen = lb_opts->qlen; - if (!qlen) - qlen = 32; + loop->buflen = lb_opts->bulk_buflen; + loop->qlen = lb_opts->qlen; + if (!loop->qlen) + loop->qlen = 32; loop->function.name = "loopback"; loop->function.bind = loopback_bind; @@ -434,7 +486,7 @@ static ssize_t f_lb_opts_qlen_show(struct f_lb_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%d", opts->qlen); + result = sprintf(page, "%d\n", opts->qlen); mutex_unlock(&opts->lock); return result; @@ -473,7 +525,7 @@ static ssize_t f_lb_opts_bulk_buflen_show(struct f_lb_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%d", opts->bulk_buflen); + result = sprintf(page, "%d\n", opts->bulk_buflen); mutex_unlock(&opts->lock); return result; diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index a6eb537d7768..cd54e72a6c50 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -2258,12 +2258,10 @@ reset: /* Disable the endpoints */ if (fsg->bulk_in_enabled) { usb_ep_disable(fsg->bulk_in); - fsg->bulk_in->driver_data = NULL; fsg->bulk_in_enabled = 0; } if (fsg->bulk_out_enabled) { usb_ep_disable(fsg->bulk_out); - fsg->bulk_out->driver_data = NULL; fsg->bulk_out_enabled = 0; } @@ -2662,10 +2660,12 @@ EXPORT_SYMBOL_GPL(fsg_common_put); /* check if fsg_num_buffers is within a valid range */ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers) { - if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4) +#define FSG_MAX_NUM_BUFFERS 32 + + if (fsg_num_buffers >= 2 && fsg_num_buffers <= FSG_MAX_NUM_BUFFERS) return 0; pr_err("fsg_num_buffers %u is out of range (%d to %d)\n", - fsg_num_buffers, 2, 4); + fsg_num_buffers, 2, FSG_MAX_NUM_BUFFERS); return -EINVAL; } @@ -3070,13 +3070,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); if (!ep) goto autoconf_fail; - ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_in = ep; ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc); if (!ep) goto autoconf_fail; - ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_out = ep; /* Assume endpoint addresses are the same for both speeds */ diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a287a4829273..ce3c8a629266 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -302,8 +302,7 @@ static int f_midi_start_ep(struct f_midi *midi, int err; struct usb_composite_dev *cdev = f->config->cdev; - if (ep->driver_data) - usb_ep_disable(ep); + usb_ep_disable(ep); err = config_ep_by_speed(midi->gadget, f, ep); if (err) { @@ -341,8 +340,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (err) return err; - if (midi->out_ep->driver_data) - usb_ep_disable(midi->out_ep); + usb_ep_disable(midi->out_ep); err = config_ep_by_speed(midi->gadget, f, midi->out_ep); if (err) { @@ -547,10 +545,16 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req) } } - if (req->length > 0) - usb_ep_queue(ep, req, GFP_ATOMIC); - else + if (req->length > 0) { + int err; + + err = usb_ep_queue(ep, req, GFP_ATOMIC); + if (err < 0) + ERROR(midi, "%s queue req: %d\n", + midi->in_ep->name, err); + } else { free_ep_req(ep, req); + } } static void f_midi_in_tasklet(unsigned long data) @@ -757,12 +761,10 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc); if (!midi->in_ep) goto fail; - midi->in_ep->driver_data = cdev; /* claim */ midi->out_ep = usb_ep_autoconfig(cdev->gadget, &bulk_out_desc); if (!midi->out_ep) goto fail; - midi->out_ep->driver_data = cdev; /* claim */ /* allocate temporary function list */ midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function), @@ -889,12 +891,6 @@ fail_f_midi: fail: f_midi_unregister_card(midi); fail_register: - /* we might as well release our claims on endpoints */ - if (midi->out_ep) - midi->out_ep->driver_data = NULL; - if (midi->in_ep) - midi->in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 3f05c6bd57f0..b6f7ed7d48a7 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -586,7 +586,7 @@ static void ncm_ep0out_complete(struct usb_ep *ep, struct usb_request *req) unsigned in_size; struct usb_function *f = req->context; struct f_ncm *ncm = func_to_ncm(f); - struct usb_composite_dev *cdev = ep->driver_data; + struct usb_composite_dev *cdev = f->config->cdev; req->context = NULL; if (req->status || req->actual != req->length) { @@ -803,10 +803,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt != 0) goto fail; - if (ncm->notify->driver_data) { - DBG(cdev, "reset ncm control %d\n", intf); - usb_ep_disable(ncm->notify); - } + DBG(cdev, "reset ncm control %d\n", intf); + usb_ep_disable(ncm->notify); if (!(ncm->notify->desc)) { DBG(cdev, "init ncm ctrl %d\n", intf); @@ -814,14 +812,13 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) goto fail; } usb_ep_enable(ncm->notify); - ncm->notify->driver_data = ncm; /* Data interface has two altsettings, 0 and 1 */ } else if (intf == ncm->data_id) { if (alt > 1) goto fail; - if (ncm->port.in_ep->driver_data) { + if (ncm->port.in_ep->enabled) { DBG(cdev, "reset ncm\n"); ncm->timer_stopping = true; ncm->netdev = NULL; @@ -885,7 +882,7 @@ static int ncm_get_alt(struct usb_function *f, unsigned intf) if (intf == ncm->ctrl_id) return 0; - return ncm->port.in_ep->driver_data ? 1 : 0; + return ncm->port.in_ep->enabled ? 1 : 0; } static struct sk_buff *package_for_tx(struct f_ncm *ncm) @@ -1276,15 +1273,14 @@ static void ncm_disable(struct usb_function *f) DBG(cdev, "ncm deactivated\n"); - if (ncm->port.in_ep->driver_data) { + if (ncm->port.in_ep->enabled) { ncm->timer_stopping = true; ncm->netdev = NULL; gether_disconnect(&ncm->port); } - if (ncm->notify->driver_data) { + if (ncm->notify->enabled) { usb_ep_disable(ncm->notify); - ncm->notify->driver_data = NULL; ncm->notify->desc = NULL; } } @@ -1402,19 +1398,16 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; ncm->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc); if (!ep) goto fail; ncm->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc); if (!ep) goto fail; ncm->notify = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -1468,14 +1461,6 @@ fail: usb_ep_free_request(ncm->notify, ncm->notify_req); } - /* we might as well release our claims on endpoints */ - if (ncm->notify) - ncm->notify->driver_data = NULL; - if (ncm->port.out_ep) - ncm->port.out_ep->driver_data = NULL; - if (ncm->port.in_ep) - ncm->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; diff --git a/drivers/usb/gadget/function/f_obex.c b/drivers/usb/gadget/function/f_obex.c index 5460426057eb..1c3d30ad2f92 100644 --- a/drivers/usb/gadget/function/f_obex.c +++ b/drivers/usb/gadget/function/f_obex.c @@ -206,7 +206,7 @@ static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt > 1) goto fail; - if (obex->port.in->driver_data) { + if (obex->port.in->enabled) { dev_dbg(&cdev->gadget->dev, "reset obex ttyGS%d\n", obex->port_num); gserial_disconnect(&obex->port); @@ -348,13 +348,11 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; obex->port.in = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc); if (!ep) goto fail; obex->port.out = ep; - ep->driver_data = cdev; /* claim */ /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at @@ -378,12 +376,6 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - /* we might as well release our claims on endpoints */ - if (obex->port.out) - obex->port.out->driver_data = NULL; - if (obex->port.in) - obex->port.in->driver_data = NULL; - ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); return status; diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index c0c3ef272714..62a198754029 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c @@ -418,7 +418,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) spin_lock(&port->lock); - if (fp->in_ep->driver_data) + if (fp->in_ep->enabled) __pn_reset(f); if (alt == 1) { @@ -530,13 +530,11 @@ static int pn_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto err; fp->out_ep = ep; - ep->driver_data = fp; /* Claim */ ep = usb_ep_autoconfig(gadget, &pn_fs_source_desc); if (!ep) goto err; fp->in_ep = ep; - ep->driver_data = fp; /* Claim */ pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress; pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress; @@ -575,10 +573,6 @@ err_req: usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); usb_free_all_descriptors(f); err: - if (fp->out_ep) - fp->out_ep->driver_data = NULL; - if (fp->in_ep) - fp->in_ep->driver_data = NULL; ERROR(cdev, "USB CDC Phonet: cannot autoconfigure\n"); return status; } diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 8e2b6bea07bc..7fb3209ed52c 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -1039,12 +1039,10 @@ autoconf_fail: 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; diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 32985dade838..fd301ed9e294 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -543,22 +543,20 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0 */ if (intf == rndis->ctrl_id) { - if (rndis->notify->driver_data) { - VDBG(cdev, "reset rndis control %d\n", intf); - usb_ep_disable(rndis->notify); - } + VDBG(cdev, "reset rndis control %d\n", intf); + usb_ep_disable(rndis->notify); + if (!rndis->notify->desc) { VDBG(cdev, "init rndis ctrl %d\n", intf); if (config_ep_by_speed(cdev->gadget, f, rndis->notify)) goto fail; } usb_ep_enable(rndis->notify); - rndis->notify->driver_data = rndis; } else if (intf == rndis->data_id) { struct net_device *net; - if (rndis->port.in_ep->driver_data) { + if (rndis->port.in_ep->enabled) { DBG(cdev, "reset rndis\n"); gether_disconnect(&rndis->port); } @@ -612,7 +610,7 @@ static void rndis_disable(struct usb_function *f) struct f_rndis *rndis = func_to_rndis(f); struct usb_composite_dev *cdev = f->config->cdev; - if (!rndis->notify->driver_data) + if (!rndis->notify->enabled) return; DBG(cdev, "rndis deactivated\n"); @@ -621,7 +619,6 @@ static void rndis_disable(struct usb_function *f) gether_disconnect(&rndis->port); usb_ep_disable(rndis->notify); - rndis->notify->driver_data = NULL; } /*-------------------------------------------------------------------------*/ @@ -745,13 +742,11 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; rndis->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc); if (!ep) goto fail; rndis->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ /* NOTE: a status/notification endpoint is, strictly speaking, * optional. We don't treat it that way though! It's simpler, @@ -761,7 +756,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; rndis->notify = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -829,14 +823,6 @@ fail: usb_ep_free_request(rndis->notify, rndis->notify_req); } - /* we might as well release our claims on endpoints */ - if (rndis->notify) - rndis->notify->driver_data = NULL; - if (rndis->port.out_ep) - rndis->port.out_ep->driver_data = NULL; - if (rndis->port.in_ep) - rndis->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; diff --git a/drivers/usb/gadget/function/f_serial.c b/drivers/usb/gadget/function/f_serial.c index 1d162e200e83..ba705e047d7e 100644 --- a/drivers/usb/gadget/function/f_serial.c +++ b/drivers/usb/gadget/function/f_serial.c @@ -153,7 +153,7 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0, so this is an activation or a reset */ - if (gser->port.in->driver_data) { + if (gser->port.in->enabled) { dev_dbg(&cdev->gadget->dev, "reset generic ttyGS%d\n", gser->port_num); gserial_disconnect(&gser->port); @@ -219,13 +219,11 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; gser->port.in = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc); if (!ep) goto fail; gser->port.out = ep; - ep->driver_data = cdev; /* claim */ /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at @@ -249,12 +247,6 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - /* we might as well release our claims on endpoints */ - if (gser->port.out) - gser->port.out->driver_data = NULL; - if (gser->port.in) - gser->port.in->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index cbfaf86fe456..d7646d3acd63 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -50,6 +50,13 @@ struct f_sourcesink { struct usb_ep *iso_in_ep; struct usb_ep *iso_out_ep; int cur_alt; + + unsigned pattern; + unsigned isoc_interval; + unsigned isoc_maxpacket; + unsigned isoc_mult; + unsigned isoc_maxburst; + unsigned buflen; }; static inline struct f_sourcesink *func_to_ss(struct usb_function *f) @@ -57,13 +64,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f) return container_of(f, struct f_sourcesink, function); } -static unsigned pattern; -static unsigned isoc_interval; -static unsigned isoc_maxpacket; -static unsigned isoc_mult; -static unsigned isoc_maxburst; -static unsigned buflen; - /*-------------------------------------------------------------------------*/ static struct usb_interface_descriptor source_sink_intf_alt0 = { @@ -298,7 +298,9 @@ static struct usb_gadget_strings *sourcesink_strings[] = { static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len) { - return alloc_ep_req(ep, len, buflen); + struct f_sourcesink *ss = ep->driver_data; + + return alloc_ep_req(ep, len, ss->buflen); } void free_ep_req(struct usb_ep *ep, struct usb_request *req) @@ -311,13 +313,9 @@ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) { int value; - if (ep->driver_data) { - value = usb_ep_disable(ep); - if (value < 0) - DBG(cdev, "disable %s --> %d\n", - ep->name, value); - ep->driver_data = NULL; - } + value = usb_ep_disable(ep); + if (value < 0) + DBG(cdev, "disable %s --> %d\n", ep->name, value); } void disable_endpoints(struct usb_composite_dev *cdev, @@ -355,42 +353,37 @@ autoconf_fail: f->name, cdev->gadget->name); return -ENODEV; } - ss->in_ep->driver_data = cdev; /* claim */ ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc); if (!ss->out_ep) goto autoconf_fail; - ss->out_ep->driver_data = cdev; /* claim */ /* sanity check the isoc module parameters */ - if (isoc_interval < 1) - isoc_interval = 1; - if (isoc_interval > 16) - isoc_interval = 16; - if (isoc_mult > 2) - isoc_mult = 2; - if (isoc_maxburst > 15) - isoc_maxburst = 15; + if (ss->isoc_interval < 1) + ss->isoc_interval = 1; + if (ss->isoc_interval > 16) + ss->isoc_interval = 16; + if (ss->isoc_mult > 2) + ss->isoc_mult = 2; + if (ss->isoc_maxburst > 15) + ss->isoc_maxburst = 15; /* fill in the FS isoc descriptors from the module parameters */ - fs_iso_source_desc.wMaxPacketSize = isoc_maxpacket > 1023 ? - 1023 : isoc_maxpacket; - fs_iso_source_desc.bInterval = isoc_interval; - fs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket > 1023 ? - 1023 : isoc_maxpacket; - fs_iso_sink_desc.bInterval = isoc_interval; + fs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ? + 1023 : ss->isoc_maxpacket; + fs_iso_source_desc.bInterval = ss->isoc_interval; + fs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ? + 1023 : ss->isoc_maxpacket; + fs_iso_sink_desc.bInterval = ss->isoc_interval; /* allocate iso endpoints */ ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc); if (!ss->iso_in_ep) goto no_iso; - ss->iso_in_ep->driver_data = cdev; /* claim */ ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc); - if (ss->iso_out_ep) { - ss->iso_out_ep->driver_data = cdev; /* claim */ - } else { - ss->iso_in_ep->driver_data = NULL; + if (!ss->iso_out_ep) { + usb_ep_autoconfig_release(ss->iso_in_ep); ss->iso_in_ep = NULL; no_iso: /* @@ -403,8 +396,8 @@ no_iso: ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL; } - if (isoc_maxpacket > 1024) - isoc_maxpacket = 1024; + if (ss->isoc_maxpacket > 1024) + ss->isoc_maxpacket = 1024; /* support high speed hardware */ hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; @@ -415,15 +408,15 @@ no_iso: * We assume that the user knows what they are doing and won't * give parameters that their UDC doesn't support. */ - hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket; - hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11; - hs_iso_source_desc.bInterval = isoc_interval; + hs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket; + hs_iso_source_desc.wMaxPacketSize |= ss->isoc_mult << 11; + hs_iso_source_desc.bInterval = ss->isoc_interval; hs_iso_source_desc.bEndpointAddress = fs_iso_source_desc.bEndpointAddress; - hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket; - hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11; - hs_iso_sink_desc.bInterval = isoc_interval; + hs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket; + hs_iso_sink_desc.wMaxPacketSize |= ss->isoc_mult << 11; + hs_iso_sink_desc.bInterval = ss->isoc_interval; hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; /* support super speed hardware */ @@ -437,21 +430,21 @@ no_iso: * We assume that the user knows what they are doing and won't * give parameters that their UDC doesn't support. */ - ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket; - ss_iso_source_desc.bInterval = isoc_interval; - ss_iso_source_comp_desc.bmAttributes = isoc_mult; - ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst; - ss_iso_source_comp_desc.wBytesPerInterval = - isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1); + ss_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket; + ss_iso_source_desc.bInterval = ss->isoc_interval; + ss_iso_source_comp_desc.bmAttributes = ss->isoc_mult; + ss_iso_source_comp_desc.bMaxBurst = ss->isoc_maxburst; + ss_iso_source_comp_desc.wBytesPerInterval = ss->isoc_maxpacket * + (ss->isoc_mult + 1) * (ss->isoc_maxburst + 1); ss_iso_source_desc.bEndpointAddress = fs_iso_source_desc.bEndpointAddress; - ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket; - ss_iso_sink_desc.bInterval = isoc_interval; - ss_iso_sink_comp_desc.bmAttributes = isoc_mult; - ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst; - ss_iso_sink_comp_desc.wBytesPerInterval = - isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1); + ss_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket; + ss_iso_sink_desc.bInterval = ss->isoc_interval; + ss_iso_sink_comp_desc.bmAttributes = ss->isoc_mult; + ss_iso_sink_comp_desc.bMaxBurst = ss->isoc_maxburst; + ss_iso_sink_comp_desc.wBytesPerInterval = ss->isoc_maxpacket * + (ss->isoc_mult + 1) * (ss->isoc_maxburst + 1); ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; ret = usb_assign_descriptors(f, fs_source_sink_descs, @@ -489,12 +482,13 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req) unsigned i; u8 *buf = req->buf; struct usb_composite_dev *cdev = ss->function.config->cdev; + int max_packet_size = le16_to_cpu(ss->out_ep->desc->wMaxPacketSize); - if (pattern == 2) + if (ss->pattern == 2) return 0; for (i = 0; i < req->actual; i++, buf++) { - switch (pattern) { + switch (ss->pattern) { /* all-zeroes has no synchronization issues */ case 0: @@ -510,7 +504,7 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req) * stutter for any reason, including buffer duplication...) */ case 1: - if (*buf == (u8)(i % 63)) + if (*buf == (u8)((i % max_packet_size) % 63)) continue; break; } @@ -525,14 +519,16 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) { unsigned i; u8 *buf = req->buf; + int max_packet_size = le16_to_cpu(ep->desc->wMaxPacketSize); + struct f_sourcesink *ss = ep->driver_data; - switch (pattern) { + switch (ss->pattern) { case 0: memset(req->buf, 0, req->length); break; case 1: for (i = 0; i < req->length; i++) - *buf++ = (u8) (i % 63); + *buf++ = (u8) ((i % max_packet_size) % 63); break; case 2: break; @@ -556,7 +552,7 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) case 0: /* normal completion? */ if (ep == ss->out_ep) { check_read_data(ss, req); - if (pattern != 2) + if (ss->pattern != 2) memset(req->buf, 0x55, req->length); } break; @@ -605,15 +601,16 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, if (is_iso) { switch (speed) { case USB_SPEED_SUPER: - size = isoc_maxpacket * (isoc_mult + 1) * - (isoc_maxburst + 1); + size = ss->isoc_maxpacket * + (ss->isoc_mult + 1) * + (ss->isoc_maxburst + 1); break; case USB_SPEED_HIGH: - size = isoc_maxpacket * (isoc_mult + 1); + size = ss->isoc_maxpacket * (ss->isoc_mult + 1); break; default: - size = isoc_maxpacket > 1023 ? - 1023 : isoc_maxpacket; + size = ss->isoc_maxpacket > 1023 ? + 1023 : ss->isoc_maxpacket; break; } ep = is_in ? ss->iso_in_ep : ss->iso_out_ep; @@ -629,7 +626,7 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, req->complete = source_sink_complete; if (is_in) reinit_write_data(ep, req); - else if (pattern != 2) + else if (ss->pattern != 2) memset(req->buf, 0x55, req->length); status = usb_ep_queue(ep, req, GFP_ATOMIC); @@ -683,7 +680,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss, fail: ep = ss->in_ep; usb_ep_disable(ep); - ep->driver_data = NULL; return result; } @@ -702,7 +698,6 @@ fail: fail2: ep = ss->out_ep; usb_ep_disable(ep); - ep->driver_data = NULL; goto fail; } @@ -724,10 +719,8 @@ fail2: if (result < 0) { fail3: ep = ss->iso_in_ep; - if (ep) { + if (ep) usb_ep_disable(ep); - ep->driver_data = NULL; - } goto fail2; } } @@ -746,7 +739,6 @@ fail3: result = source_sink_start_ep(ss, false, true, speed); if (result < 0) { usb_ep_disable(ep); - ep->driver_data = NULL; goto fail3; } } @@ -763,8 +755,7 @@ static int sourcesink_set_alt(struct usb_function *f, struct f_sourcesink *ss = func_to_ss(f); struct usb_composite_dev *cdev = f->config->cdev; - if (ss->in_ep->driver_data) - disable_source_sink(ss); + disable_source_sink(ss); return enable_source_sink(cdev, ss, alt); } @@ -872,12 +863,12 @@ static struct usb_function *source_sink_alloc_func( ss_opts->refcnt++; mutex_unlock(&ss_opts->lock); - pattern = ss_opts->pattern; - isoc_interval = ss_opts->isoc_interval; - isoc_maxpacket = ss_opts->isoc_maxpacket; - isoc_mult = ss_opts->isoc_mult; - isoc_maxburst = ss_opts->isoc_maxburst; - buflen = ss_opts->bulk_buflen; + ss->pattern = ss_opts->pattern; + ss->isoc_interval = ss_opts->isoc_interval; + ss->isoc_maxpacket = ss_opts->isoc_maxpacket; + ss->isoc_mult = ss_opts->isoc_mult; + ss->isoc_maxburst = ss_opts->isoc_maxburst; + ss->buflen = ss_opts->bulk_buflen; ss->function.name = "source/sink"; ss->function.bind = sourcesink_bind; @@ -919,7 +910,7 @@ static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->pattern); + result = sprintf(page, "%u\n", opts->pattern); mutex_unlock(&opts->lock); return result; @@ -963,7 +954,7 @@ static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->isoc_interval); + result = sprintf(page, "%u\n", opts->isoc_interval); mutex_unlock(&opts->lock); return result; @@ -1007,7 +998,7 @@ static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->isoc_maxpacket); + result = sprintf(page, "%u\n", opts->isoc_maxpacket); mutex_unlock(&opts->lock); return result; @@ -1051,7 +1042,7 @@ static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->isoc_mult); + result = sprintf(page, "%u\n", opts->isoc_mult); mutex_unlock(&opts->lock); return result; @@ -1095,7 +1086,7 @@ static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->isoc_maxburst); + result = sprintf(page, "%u\n", opts->isoc_maxburst); mutex_unlock(&opts->lock); return result; @@ -1139,7 +1130,7 @@ static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->bulk_buflen); + result = sprintf(page, "%u\n", opts->bulk_buflen); mutex_unlock(&opts->lock); return result; diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c index e3dfa675ff06..2e66e624e6e1 100644 --- a/drivers/usb/gadget/function/f_subset.c +++ b/drivers/usb/gadget/function/f_subset.c @@ -262,7 +262,7 @@ static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0, so this is an activation or a reset */ - if (geth->port.in_ep->driver_data) { + if (geth->port.in_ep->enabled) { DBG(cdev, "reset cdc subset\n"); gether_disconnect(&geth->port); } @@ -343,13 +343,11 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; geth->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc); if (!ep) goto fail; geth->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at @@ -380,12 +378,6 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - /* we might as well release our claims on endpoints */ - if (geth->port.out_ep) - geth->port.out_ep->driver_data = NULL; - if (geth->port.in_ep) - geth->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 7856b3394494..8ee701924d29 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -593,7 +593,6 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return err; usb_ep_enable(out_ep); - out_ep->driver_data = audio; audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); if (IS_ERR(audio->copy_buf)) return -ENOMEM; @@ -718,7 +717,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) goto fail; audio->out_ep = ep; audio->out_ep->desc = &as_out_ep_desc; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -730,8 +728,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) fail: gaudio_cleanup(&audio->card); - if (ep) - ep->driver_data = NULL; return status; } diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index f8de7ea2a0c1..63336e269898 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1081,14 +1081,12 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); goto err; } - agdev->out_ep->driver_data = agdev; agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); if (!agdev->in_ep) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); goto err; } - agdev->in_ep->driver_data = agdev; uac2->p_prm.uac2 = uac2; uac2->c_prm.uac2 = uac2; @@ -1132,10 +1130,6 @@ err_free_descs: err: kfree(agdev->uac2.p_prm.rbuf); kfree(agdev->uac2.c_prm.rbuf); - if (agdev->in_ep) - agdev->in_ep->driver_data = NULL; - if (agdev->out_ep) - agdev->out_ep->driver_data = NULL; return -EINVAL; } @@ -1583,11 +1577,6 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f) prm = &agdev->uac2.c_prm; kfree(prm->rbuf); usb_free_all_descriptors(f); - - if (agdev->in_ep) - agdev->in_ep->driver_data = NULL; - if (agdev->out_ep) - agdev->out_ep->driver_data = NULL; } static struct usb_function *afunc_alloc(struct usb_function_instance *fi) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 743be34605dc..29b41b5dee04 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -280,7 +280,7 @@ uvc_function_get_alt(struct usb_function *f, unsigned interface) else if (interface != uvc->streaming_intf) return -EINVAL; else - return uvc->video.ep->driver_data ? 1 : 0; + return uvc->video.ep->enabled ? 1 : 0; } static int @@ -298,18 +298,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (alt) return -EINVAL; - if (uvc->control_ep->driver_data) { - INFO(cdev, "reset UVC Control\n"); - usb_ep_disable(uvc->control_ep); - uvc->control_ep->driver_data = NULL; - } + INFO(cdev, "reset UVC Control\n"); + usb_ep_disable(uvc->control_ep); if (!uvc->control_ep->desc) if (config_ep_by_speed(cdev->gadget, f, uvc->control_ep)) return -EINVAL; usb_ep_enable(uvc->control_ep); - uvc->control_ep->driver_data = uvc; if (uvc->state == UVC_STATE_DISCONNECTED) { memset(&v4l2_event, 0, sizeof(v4l2_event)); @@ -336,10 +332,8 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (uvc->state != UVC_STATE_STREAMING) return 0; - if (uvc->video.ep) { + if (uvc->video.ep) usb_ep_disable(uvc->video.ep); - uvc->video.ep->driver_data = NULL; - } memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMOFF; @@ -355,18 +349,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (!uvc->video.ep) return -EINVAL; - if (uvc->video.ep->driver_data) { - INFO(cdev, "reset UVC\n"); - usb_ep_disable(uvc->video.ep); - uvc->video.ep->driver_data = NULL; - } + INFO(cdev, "reset UVC\n"); + usb_ep_disable(uvc->video.ep); ret = config_ep_by_speed(f->config->cdev->gadget, &(uvc->func), uvc->video.ep); if (ret) return ret; usb_ep_enable(uvc->video.ep); - uvc->video.ep->driver_data = uvc; memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMON; @@ -392,15 +382,8 @@ uvc_function_disable(struct usb_function *f) uvc->state = UVC_STATE_DISCONNECTED; - if (uvc->video.ep->driver_data) { - usb_ep_disable(uvc->video.ep); - uvc->video.ep->driver_data = NULL; - } - - if (uvc->control_ep->driver_data) { - usb_ep_disable(uvc->control_ep); - uvc->control_ep->driver_data = NULL; - } + usb_ep_disable(uvc->video.ep); + usb_ep_disable(uvc->control_ep); } /* -------------------------------------------------------------------------- @@ -651,7 +634,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) goto error; } uvc->control_ep = ep; - ep->driver_data = uvc; if (gadget_is_superspeed(c->cdev->gadget)) ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep, @@ -666,7 +648,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) goto error; } uvc->video.ep = ep; - ep->driver_data = uvc; uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address; uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address; @@ -755,11 +736,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) error: v4l2_device_unregister(&uvc->v4l2_dev); - if (uvc->control_ep) - uvc->control_ep->driver_data = NULL; - if (uvc->video.ep) - uvc->video.ep->driver_data = NULL; - if (uvc->control_req) usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); kfree(uvc->control_buf); @@ -886,8 +862,6 @@ static void uvc_unbind(struct usb_configuration *c, struct usb_function *f) video_unregister_device(&uvc->vdev); v4l2_device_unregister(&uvc->v4l2_dev); - uvc->control_ep->driver_data = NULL; - uvc->video.ep->driver_data = NULL; usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); kfree(uvc->control_buf); diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index f1fd777ef4ec..6554322af2c1 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -48,6 +48,11 @@ #define UETH__VERSION "29-May-2008" +/* Experiments show that both Linux and Windows hosts allow up to 16k + * frame sizes. Set the max size to 15k+52 to prevent allocating 32k + * blocks and still have efficient handling. */ +#define GETHER_MAX_ETH_FRAME_LEN 15412 + struct eth_dev { /* lock is held while accessing port_usb */ @@ -146,7 +151,7 @@ static int ueth_change_mtu(struct net_device *net, int new_mtu) spin_lock_irqsave(&dev->lock, flags); if (dev->port_usb) status = -EBUSY; - else if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN) + else if (new_mtu <= ETH_HLEN || new_mtu > GETHER_MAX_ETH_FRAME_LEN) status = -ERANGE; else net->mtu = new_mtu; @@ -294,7 +299,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) while (skb2) { if (status < 0 || ETH_HLEN > skb2->len - || skb2->len > VLAN_ETH_FRAME_LEN) { + || skb2->len > GETHER_MAX_ETH_FRAME_LEN) { dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; DBG(dev, "rx length %d\n", skb2->len); @@ -1144,7 +1149,6 @@ void gether_disconnect(struct gether *link) spin_lock(&dev->req_lock); } spin_unlock(&dev->req_lock); - link->in_ep->driver_data = NULL; link->in_ep->desc = NULL; usb_ep_disable(link->out_ep); @@ -1159,7 +1163,6 @@ void gether_disconnect(struct gether *link) spin_lock(&dev->req_lock); } spin_unlock(&dev->req_lock); - link->out_ep->driver_data = NULL; link->out_ep->desc = NULL; /* finish forgetting about this USB link episode */ diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 7ee057930ae7..9cc6a13d5e5b 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -876,7 +876,6 @@ static void gs_close(struct tty_struct *tty, struct file *file) else gs_buf_clear(&port->port_write_buf); - tty->driver_data = NULL; port->port.tty = NULL; port->openclose = false; @@ -1224,7 +1223,6 @@ int gserial_connect(struct gserial *gser, u8 port_num) fail_out: usb_ep_disable(gser->in); - gser->in->driver_data = NULL; return status; } EXPORT_SYMBOL_GPL(gserial_connect); @@ -1264,10 +1262,7 @@ void gserial_disconnect(struct gserial *gser) /* disable endpoints, aborting down any active I/O */ usb_ep_disable(gser->out); - gser->out->driver_data = NULL; - usb_ep_disable(gser->in); - gser->in->driver_data = NULL; /* finally, free any unused/unusable I/O buffers */ spin_lock_irqsave(&port->port_lock, flags); diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 5231a32aef55..99ca3dabc4f3 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -79,10 +79,7 @@ static int dbgp_consume(char *buf, unsigned len) static void __disable_ep(struct usb_ep *ep) { - if (ep && ep->driver_data == dbgp.gadget) { - usb_ep_disable(ep); - ep->driver_data = NULL; - } + usb_ep_disable(ep); } static void dbgp_disable_ep(void) @@ -171,7 +168,6 @@ static int __enable_ep(struct usb_ep *ep, struct usb_endpoint_descriptor *desc) int err; ep->desc = desc; err = usb_ep_enable(ep); - ep->driver_data = dbgp.gadget; return err; } @@ -229,8 +225,6 @@ static void dbgp_unbind(struct usb_gadget *gadget) usb_ep_free_request(gadget->ep0, dbgp.req); dbgp.req = NULL; } - - gadget->ep0->driver_data = NULL; } #ifdef CONFIG_USB_G_DBGP_SERIAL @@ -249,18 +243,15 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget) goto fail_1; } - dbgp.i_ep->driver_data = gadget; i_desc.wMaxPacketSize = cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE); dbgp.o_ep = usb_ep_autoconfig(gadget, &o_desc); if (!dbgp.o_ep) { - dbgp.i_ep->driver_data = NULL; stp = 2; - goto fail_2; + goto fail_1; } - dbgp.o_ep->driver_data = gadget; o_desc.wMaxPacketSize = cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE); @@ -277,8 +268,6 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget) return 0; -fail_2: - dbgp.i_ep->driver_data = NULL; fail_1: dev_dbg(&dbgp.gadget->dev, "ep config: failure (%d)\n", stp); return -ENODEV; @@ -306,7 +295,6 @@ static int dbgp_bind(struct usb_gadget *gadget, } dbgp.req->length = DBGP_REQ_EP0_LEN; - gadget->ep0->driver_data = gadget; #ifdef CONFIG_USB_G_DBGP_SERIAL dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL); @@ -356,8 +344,6 @@ static int dbgp_setup(struct usb_gadget *gadget, void *data = NULL; u16 len = 0; - gadget->ep0->driver_data = gadget; - if (request == USB_REQ_GET_DESCRIPTOR) { switch (value>>8) { case USB_DT_DEVICE: diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index c3c48088fced..778e42abb3cb 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -2018,14 +2018,6 @@ static struct usb_configuration usbg_config_driver = { .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; -static void give_back_ep(struct usb_ep **pep) -{ - struct usb_ep *ep = *pep; - if (!ep) - return; - ep->driver_data = NULL; -} - static int usbg_bind(struct usb_configuration *c, struct usb_function *f) { struct f_uas *fu = to_f_uas(f); @@ -2045,29 +2037,24 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f) &uasp_bi_ep_comp_desc); if (!ep) goto ep_fail; - - ep->driver_data = fu; fu->ep_in = ep; ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc, &uasp_bo_ep_comp_desc); if (!ep) goto ep_fail; - ep->driver_data = fu; fu->ep_out = ep; ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc, &uasp_status_in_ep_comp_desc); if (!ep) goto ep_fail; - ep->driver_data = fu; fu->ep_status = ep; ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc, &uasp_cmd_comp_desc); if (!ep) goto ep_fail; - ep->driver_data = fu; fu->ep_cmd = ep; /* Assume endpoint addresses are the same for both speeds */ @@ -2091,11 +2078,6 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f) return 0; ep_fail: pr_err("Can't claim all required eps\n"); - - give_back_ep(&fu->ep_in); - give_back_ep(&fu->ep_out); - give_back_ep(&fu->ep_status); - give_back_ep(&fu->ep_cmd); return -ENOTSUPP; } diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 9a3a6b00391a..cdbff54e07ac 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -55,7 +55,7 @@ config USB_LPC32XX config USB_ATMEL_USBA tristate "Atmel USBA" - depends on AVR32 || ARCH_AT91 + depends on ((AVR32 && !OF) || ARCH_AT91) help USBA is the integrated high-speed USB Device controller on the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 175ca93fe5e2..cd8764150861 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -65,18 +65,10 @@ static void udc_tasklet_disconnect(unsigned long); static void empty_req_queue(struct udc_ep *); -static int udc_probe(struct udc *dev); -static void udc_basic_init(struct udc *dev); static void udc_setup_endpoints(struct udc *dev); static void udc_soft_reset(struct udc *dev); static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq); -static int udc_free_dma_chain(struct udc *dev, struct udc_request *req); -static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req, - unsigned long buf_len, gfp_t gfp_flags); -static int udc_remote_wakeup(struct udc *dev); -static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); -static void udc_pci_remove(struct pci_dev *pdev); /* description */ static const char mod_desc[] = UDC_MOD_DESCRIPTION; @@ -615,6 +607,30 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp) return &req->req; } +/* frees pci pool descriptors of a DMA chain */ +static int udc_free_dma_chain(struct udc *dev, struct udc_request *req) +{ + int ret_val = 0; + struct udc_data_dma *td; + struct udc_data_dma *td_last = NULL; + unsigned int i; + + DBG(dev, "free chain req = %p\n", req); + + /* do not free first desc., will be done by free for request */ + td_last = req->td_data; + td = phys_to_virt(td_last->next); + + for (i = 1; i < req->chain_len; i++) { + pci_pool_free(dev->data_requests, td, + (dma_addr_t)td_last->next); + td_last = td; + td = phys_to_virt(td_last->next); + } + + return ret_val; +} + /* Frees request packet, called by gadget driver */ static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq) @@ -789,6 +805,123 @@ udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req) return finished; } +/* Creates or re-inits a DMA chain */ +static int udc_create_dma_chain( + struct udc_ep *ep, + struct udc_request *req, + unsigned long buf_len, gfp_t gfp_flags +) +{ + unsigned long bytes = req->req.length; + unsigned int i; + dma_addr_t dma_addr; + struct udc_data_dma *td = NULL; + struct udc_data_dma *last = NULL; + unsigned long txbytes; + unsigned create_new_chain = 0; + unsigned len; + + VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n", + bytes, buf_len); + dma_addr = DMA_DONT_USE; + + /* unset L bit in first desc for OUT */ + if (!ep->in) + req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); + + /* alloc only new desc's if not already available */ + len = req->req.length / ep->ep.maxpacket; + if (req->req.length % ep->ep.maxpacket) + len++; + + if (len > req->chain_len) { + /* shorter chain already allocated before */ + if (req->chain_len > 1) + udc_free_dma_chain(ep->dev, req); + req->chain_len = len; + create_new_chain = 1; + } + + td = req->td_data; + /* gen. required number of descriptors and buffers */ + for (i = buf_len; i < bytes; i += buf_len) { + /* create or determine next desc. */ + if (create_new_chain) { + td = pci_pool_alloc(ep->dev->data_requests, + gfp_flags, &dma_addr); + if (!td) + return -ENOMEM; + + td->status = 0; + } else if (i == buf_len) { + /* first td */ + td = (struct udc_data_dma *)phys_to_virt( + req->td_data->next); + td->status = 0; + } else { + td = (struct udc_data_dma *)phys_to_virt(last->next); + td->status = 0; + } + + if (td) + td->bufptr = req->req.dma + i; /* assign buffer */ + else + break; + + /* short packet ? */ + if ((bytes - i) >= buf_len) { + txbytes = buf_len; + } else { + /* short packet */ + txbytes = bytes - i; + } + + /* link td and assign tx bytes */ + if (i == buf_len) { + if (create_new_chain) + req->td_data->next = dma_addr; + /* + * else + * req->td_data->next = virt_to_phys(td); + */ + /* write tx bytes */ + if (ep->in) { + /* first desc */ + req->td_data->status = + AMD_ADDBITS(req->td_data->status, + ep->ep.maxpacket, + UDC_DMA_IN_STS_TXBYTES); + /* second desc */ + td->status = AMD_ADDBITS(td->status, + txbytes, + UDC_DMA_IN_STS_TXBYTES); + } + } else { + if (create_new_chain) + last->next = dma_addr; + /* + * else + * last->next = virt_to_phys(td); + */ + if (ep->in) { + /* write tx bytes */ + td->status = AMD_ADDBITS(td->status, + txbytes, + UDC_DMA_IN_STS_TXBYTES); + } + } + last = td; + } + /* set last bit */ + if (td) { + td->status |= AMD_BIT(UDC_DMA_IN_STS_L); + /* last desc. points to itself */ + req->td_data_last = td; + } + + return 0; +} + /* create/re-init a DMA descriptor or a DMA descriptor chain */ static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp) { @@ -913,32 +1046,6 @@ __acquires(ep->dev->lock) ep->halted = halted; } -/* frees pci pool descriptors of a DMA chain */ -static int udc_free_dma_chain(struct udc *dev, struct udc_request *req) -{ - - int ret_val = 0; - struct udc_data_dma *td; - struct udc_data_dma *td_last = NULL; - unsigned int i; - - DBG(dev, "free chain req = %p\n", req); - - /* do not free first desc., will be done by free for request */ - td_last = req->td_data; - td = phys_to_virt(td_last->next); - - for (i = 1; i < req->chain_len; i++) { - - pci_pool_free(dev->data_requests, td, - (dma_addr_t) td_last->next); - td_last = td; - td = phys_to_virt(td_last->next); - } - - return ret_val; -} - /* Iterates to the end of a DMA chain and returns last descriptor */ static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req) { @@ -975,125 +1082,6 @@ static u32 udc_get_ppbdu_rxbytes(struct udc_request *req) } -/* Creates or re-inits a DMA chain */ -static int udc_create_dma_chain( - struct udc_ep *ep, - struct udc_request *req, - unsigned long buf_len, gfp_t gfp_flags -) -{ - unsigned long bytes = req->req.length; - unsigned int i; - dma_addr_t dma_addr; - struct udc_data_dma *td = NULL; - struct udc_data_dma *last = NULL; - unsigned long txbytes; - unsigned create_new_chain = 0; - unsigned len; - - VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n", - bytes, buf_len); - dma_addr = DMA_DONT_USE; - - /* unset L bit in first desc for OUT */ - if (!ep->in) - req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); - - /* alloc only new desc's if not already available */ - len = req->req.length / ep->ep.maxpacket; - if (req->req.length % ep->ep.maxpacket) - len++; - - if (len > req->chain_len) { - /* shorter chain already allocated before */ - if (req->chain_len > 1) - udc_free_dma_chain(ep->dev, req); - req->chain_len = len; - create_new_chain = 1; - } - - td = req->td_data; - /* gen. required number of descriptors and buffers */ - for (i = buf_len; i < bytes; i += buf_len) { - /* create or determine next desc. */ - if (create_new_chain) { - - td = pci_pool_alloc(ep->dev->data_requests, - gfp_flags, &dma_addr); - if (!td) - return -ENOMEM; - - td->status = 0; - } else if (i == buf_len) { - /* first td */ - td = (struct udc_data_dma *) phys_to_virt( - req->td_data->next); - td->status = 0; - } else { - td = (struct udc_data_dma *) phys_to_virt(last->next); - td->status = 0; - } - - - if (td) - td->bufptr = req->req.dma + i; /* assign buffer */ - else - break; - - /* short packet ? */ - if ((bytes - i) >= buf_len) { - txbytes = buf_len; - } else { - /* short packet */ - txbytes = bytes - i; - } - - /* link td and assign tx bytes */ - if (i == buf_len) { - if (create_new_chain) - req->td_data->next = dma_addr; - /* - else - req->td_data->next = virt_to_phys(td); - */ - /* write tx bytes */ - if (ep->in) { - /* first desc */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - ep->ep.maxpacket, - UDC_DMA_IN_STS_TXBYTES); - /* second desc */ - td->status = AMD_ADDBITS(td->status, - txbytes, - UDC_DMA_IN_STS_TXBYTES); - } - } else { - if (create_new_chain) - last->next = dma_addr; - /* - else - last->next = virt_to_phys(td); - */ - if (ep->in) { - /* write tx bytes */ - td->status = AMD_ADDBITS(td->status, - txbytes, - UDC_DMA_IN_STS_TXBYTES); - } - } - last = td; - } - /* set last bit */ - if (td) { - td->status |= AMD_BIT(UDC_DMA_IN_STS_L); - /* last desc. points to itself */ - req->td_data_last = td; - } - - return 0; -} - /* Enabling RX DMA */ static void udc_set_rde(struct udc *dev) { @@ -1453,6 +1441,26 @@ static int udc_get_frame(struct usb_gadget *gadget) return -EOPNOTSUPP; } +/* Initiates a remote wakeup */ +static int udc_remote_wakeup(struct udc *dev) +{ + unsigned long flags; + u32 tmp; + + DBG(dev, "UDC initiates remote wakeup\n"); + + spin_lock_irqsave(&dev->lock, flags); + + tmp = readl(&dev->regs->ctl); + tmp |= AMD_BIT(UDC_DEVCTL_RES); + writel(tmp, &dev->regs->ctl); + tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES); + writel(tmp, &dev->regs->ctl); + + spin_unlock_irqrestore(&dev->lock, flags); + return 0; +} + /* Remote wakeup gadget interface */ static int udc_wakeup(struct usb_gadget *gadget) { @@ -1498,33 +1506,6 @@ static void make_ep_lists(struct udc *dev) dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE; } -/* init registers at driver load time */ -static int startup_registers(struct udc *dev) -{ - u32 tmp; - - /* init controller by soft reset */ - udc_soft_reset(dev); - - /* mask not needed interrupts */ - udc_mask_unused_interrupts(dev); - - /* put into initial config */ - udc_basic_init(dev); - /* link up all endpoints */ - udc_setup_endpoints(dev); - - /* program speed */ - tmp = readl(&dev->regs->cfg); - if (use_fullspeed) - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); - else - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); - writel(tmp, &dev->regs->cfg); - - return 0; -} - /* Inits UDC context */ static void udc_basic_init(struct udc *dev) { @@ -1563,6 +1544,33 @@ static void udc_basic_init(struct udc *dev) dev->data_ep_queued = 0; } +/* init registers at driver load time */ +static int startup_registers(struct udc *dev) +{ + u32 tmp; + + /* init controller by soft reset */ + udc_soft_reset(dev); + + /* mask not needed interrupts */ + udc_mask_unused_interrupts(dev); + + /* put into initial config */ + udc_basic_init(dev); + /* link up all endpoints */ + udc_setup_endpoints(dev); + + /* program speed */ + tmp = readl(&dev->regs->cfg); + if (use_fullspeed) + tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); + else + tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); + writel(tmp, &dev->regs->cfg); + + return 0; +} + /* Sets initial endpoint parameters */ static void udc_setup_endpoints(struct udc *dev) { @@ -2177,7 +2185,7 @@ static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) } /* DMA */ - } else if (!ep->cancel_transfer && req != NULL) { + } else if (!ep->cancel_transfer && req) { ret_val = IRQ_HANDLED; /* check for DMA done */ @@ -3107,6 +3115,17 @@ static void udc_remove(struct udc *dev) udc = NULL; } +/* free all the dma pools */ +static void free_dma_pools(struct udc *dev) +{ + dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td, + dev->ep[UDC_EP0OUT_IX].td_phys); + dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td_stp, + dev->ep[UDC_EP0OUT_IX].td_stp_dma); + dma_pool_destroy(dev->stp_requests); + dma_pool_destroy(dev->data_requests); +} + /* Reset all pci context */ static void udc_pci_remove(struct pci_dev *pdev) { @@ -3116,35 +3135,19 @@ static void udc_pci_remove(struct pci_dev *pdev) usb_del_gadget_udc(&udc->gadget); /* gadget driver must not be registered */ - BUG_ON(dev->driver != NULL); + if (WARN_ON(dev->driver)) + return; /* dma pool cleanup */ - if (dev->data_requests) - pci_pool_destroy(dev->data_requests); - - if (dev->stp_requests) { - /* cleanup DMA desc's for ep0in */ - pci_pool_free(dev->stp_requests, - dev->ep[UDC_EP0OUT_IX].td_stp, - dev->ep[UDC_EP0OUT_IX].td_stp_dma); - pci_pool_free(dev->stp_requests, - dev->ep[UDC_EP0OUT_IX].td, - dev->ep[UDC_EP0OUT_IX].td_phys); - - pci_pool_destroy(dev->stp_requests); - } + free_dma_pools(dev); /* reset controller */ writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); - if (dev->irq_registered) - free_irq(pdev->irq, dev); - if (dev->virt_addr) - iounmap(dev->virt_addr); - if (dev->mem_region) - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (dev->active) - pci_disable_device(pdev); + free_irq(pdev->irq, dev); + iounmap(dev->virt_addr); + release_mem_region(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + pci_disable_device(pdev); udc_remove(dev); } @@ -3169,8 +3172,7 @@ static int init_dma_pools(struct udc *dev) sizeof(struct udc_data_dma), 0, 0); if (!dev->data_requests) { DBG(dev, "can't get request data pool\n"); - retval = -ENOMEM; - goto finished; + return -ENOMEM; } /* EP0 in dma regs = dev control regs */ @@ -3182,27 +3184,101 @@ static int init_dma_pools(struct udc *dev) if (!dev->stp_requests) { DBG(dev, "can't get stp request pool\n"); retval = -ENOMEM; - goto finished; + goto err_create_dma_pool; } /* setup */ td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, &dev->ep[UDC_EP0OUT_IX].td_stp_dma); - if (td_stp == NULL) { + if (!td_stp) { retval = -ENOMEM; - goto finished; + goto err_alloc_dma; } dev->ep[UDC_EP0OUT_IX].td_stp = td_stp; /* data: 0 packets !? */ td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, &dev->ep[UDC_EP0OUT_IX].td_phys); - if (td_data == NULL) { + if (!td_data) { retval = -ENOMEM; - goto finished; + goto err_alloc_phys; } dev->ep[UDC_EP0OUT_IX].td = td_data; return 0; +err_alloc_phys: + dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td_stp, + dev->ep[UDC_EP0OUT_IX].td_stp_dma); +err_alloc_dma: + dma_pool_destroy(dev->stp_requests); + dev->stp_requests = NULL; +err_create_dma_pool: + dma_pool_destroy(dev->data_requests); + dev->data_requests = NULL; + return retval; +} + +/* general probe */ +static int udc_probe(struct udc *dev) +{ + char tmp[128]; + u32 reg; + int retval; + + /* mark timer as not initialized */ + udc_timer.data = 0; + udc_pollstall_timer.data = 0; + + /* device struct setup */ + dev->gadget.ops = &udc_ops; + + dev_set_name(&dev->gadget.dev, "gadget"); + dev->gadget.name = name; + dev->gadget.max_speed = USB_SPEED_HIGH; + + /* init registers, interrupts, ... */ + startup_registers(dev); + + dev_info(&dev->pdev->dev, "%s\n", mod_desc); + + snprintf(tmp, sizeof(tmp), "%d", dev->irq); + dev_info(&dev->pdev->dev, + "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n", + tmp, dev->phys_addr, dev->chiprev, + (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1"); + strcpy(tmp, UDC_DRIVER_VERSION_STRING); + if (dev->chiprev == UDC_HSA0_REV) { + dev_err(&dev->pdev->dev, "chip revision is A0; too old\n"); + retval = -ENODEV; + goto finished; + } + dev_info(&dev->pdev->dev, + "driver version: %s(for Geode5536 B1)\n", tmp); + udc = dev; + + retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget, + gadget_release); + if (retval) + goto finished; + + /* timer init */ + init_timer(&udc_timer); + udc_timer.function = udc_timer_function; + udc_timer.data = 1; + /* timer pollstall init */ + init_timer(&udc_pollstall_timer); + udc_pollstall_timer.function = udc_pollstall_timer_function; + udc_pollstall_timer.data = 1; + + /* set SD */ + reg = readl(&dev->regs->ctl); + reg |= AMD_BIT(UDC_DEVCTL_SD); + writel(reg, &dev->regs->ctl); + + /* print dev register info */ + print_regs(dev); + + return 0; + finished: return retval; } @@ -3234,7 +3310,6 @@ static int udc_pci_probe( retval = -ENODEV; goto err_pcidev; } - dev->active = 1; /* PCI resource allocation */ resource = pci_resource_start(pdev, 0); @@ -3245,10 +3320,9 @@ static int udc_pci_probe( retval = -EBUSY; goto err_memreg; } - dev->mem_region = 1; dev->virt_addr = ioremap_nocache(resource, len); - if (dev->virt_addr == NULL) { + if (!dev->virt_addr) { dev_dbg(&pdev->dev, "start address cannot be mapped\n"); retval = -EFAULT; goto err_ioremap; @@ -3276,7 +3350,6 @@ static int udc_pci_probe( retval = -EBUSY; goto err_irq; } - dev->irq_registered = 1; pci_set_drvdata(pdev, dev); @@ -3290,7 +3363,7 @@ static int udc_pci_probe( if (use_dma) { retval = init_dma_pools(dev); if (retval != 0) - goto finished; + goto err_dma; } dev->phys_addr = resource; @@ -3298,13 +3371,17 @@ static int udc_pci_probe( dev->pdev = pdev; /* general probing */ - if (udc_probe(dev) == 0) - return 0; - -finished: - udc_pci_remove(pdev); - return retval; + if (udc_probe(dev)) { + retval = -ENODEV; + goto err_probe; + } + return 0; +err_probe: + if (use_dma) + free_dma_pools(dev); +err_dma: + free_irq(pdev->irq, dev); err_irq: iounmap(dev->virt_addr); err_ioremap: @@ -3316,92 +3393,6 @@ err_pcidev: return retval; } -/* general probe */ -static int udc_probe(struct udc *dev) -{ - char tmp[128]; - u32 reg; - int retval; - - /* mark timer as not initialized */ - udc_timer.data = 0; - udc_pollstall_timer.data = 0; - - /* device struct setup */ - dev->gadget.ops = &udc_ops; - - dev_set_name(&dev->gadget.dev, "gadget"); - dev->gadget.name = name; - dev->gadget.max_speed = USB_SPEED_HIGH; - - /* init registers, interrupts, ... */ - startup_registers(dev); - - dev_info(&dev->pdev->dev, "%s\n", mod_desc); - - snprintf(tmp, sizeof tmp, "%d", dev->irq); - dev_info(&dev->pdev->dev, - "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n", - tmp, dev->phys_addr, dev->chiprev, - (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1"); - strcpy(tmp, UDC_DRIVER_VERSION_STRING); - if (dev->chiprev == UDC_HSA0_REV) { - dev_err(&dev->pdev->dev, "chip revision is A0; too old\n"); - retval = -ENODEV; - goto finished; - } - dev_info(&dev->pdev->dev, - "driver version: %s(for Geode5536 B1)\n", tmp); - udc = dev; - - retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget, - gadget_release); - if (retval) - goto finished; - - /* timer init */ - init_timer(&udc_timer); - udc_timer.function = udc_timer_function; - udc_timer.data = 1; - /* timer pollstall init */ - init_timer(&udc_pollstall_timer); - udc_pollstall_timer.function = udc_pollstall_timer_function; - udc_pollstall_timer.data = 1; - - /* set SD */ - reg = readl(&dev->regs->ctl); - reg |= AMD_BIT(UDC_DEVCTL_SD); - writel(reg, &dev->regs->ctl); - - /* print dev register info */ - print_regs(dev); - - return 0; - -finished: - return retval; -} - -/* Initiates a remote wakeup */ -static int udc_remote_wakeup(struct udc *dev) -{ - unsigned long flags; - u32 tmp; - - DBG(dev, "UDC initiates remote wakeup\n"); - - spin_lock_irqsave(&dev->lock, flags); - - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_RES); - writel(tmp, &dev->regs->ctl); - tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES); - writel(tmp, &dev->regs->ctl); - - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} - /* PCI device parameters */ static const struct pci_device_id pci_id[] = { { diff --git a/drivers/usb/gadget/udc/amd5536udc.h b/drivers/usb/gadget/udc/amd5536udc.h index 6744d3b83109..4638d707f169 100644 --- a/drivers/usb/gadget/udc/amd5536udc.h +++ b/drivers/usb/gadget/udc/amd5536udc.h @@ -526,14 +526,11 @@ struct udc { struct udc_ep ep[UDC_EP_NUM]; struct usb_gadget_driver *driver; /* operational flags */ - unsigned active : 1, - stall_ep0in : 1, + unsigned stall_ep0in : 1, waiting_zlp_ack_ep0in : 1, set_cfg_not_acked : 1, - irq_registered : 1, data_ep_enabled : 1, data_ep_queued : 1, - mem_region : 1, sys_suspended : 1, connected; diff --git a/drivers/usb/gadget/udc/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h index 2679c8b217cc..0a433e6b346b 100644 --- a/drivers/usb/gadget/udc/at91_udc.h +++ b/drivers/usb/gadget/udc/at91_udc.h @@ -112,6 +112,14 @@ struct at91_udc_caps { void (*pullup)(struct at91_udc *udc, int is_on); }; +struct at91_udc_data { + int vbus_pin; /* high == host powering us */ + u8 vbus_active_low; /* vbus polarity */ + u8 vbus_polled; /* Use polling, not interrupt */ + int pullup_pin; /* active == D+ pulled up */ + u8 pullup_active_low; /* true == pullup_pin is active low */ +}; + /* * driver is non-SMP, and just blocks IRQs whenever it needs * access protection for chip registers or driver state diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 27af0f008b57..dde44450dfa9 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -833,10 +833,10 @@ static const struct usb_ep_ops dummy_ep_ops = { /* there are both host and device side versions of this call ... */ static int dummy_g_get_frame(struct usb_gadget *_gadget) { - struct timeval tv; + struct timespec64 ts64; - do_gettimeofday(&tv); - return tv.tv_usec / 1000; + ktime_get_ts64(&ts64); + return ts64.tv_nsec / NSEC_PER_MSEC; } static int dummy_wakeup(struct usb_gadget *_gadget) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index cf0ed42f5591..6706aef907f4 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -1913,7 +1913,7 @@ static void defect7374_disable_data_eps(struct net2280 *dev) for (i = 1; i < 5; i++) { ep = &dev->ep[i]; - writel(0, &ep->cfg->ep_cfg); + writel(i, &ep->cfg->ep_cfg); } /* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */ diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index e5f4c5274298..7a04157ff579 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -330,7 +330,7 @@ struct pch_vbus_gpio_data { * @prot_stall: protcol stall requested * @irq_registered: irq registered with system * @mem_region: device memory mapped - * @registered: driver regsitered with system + * @registered: driver registered with system * @suspended: driver in suspended state * @connected: gadget driver associated * @vbus_session: required vbus_session state @@ -2747,18 +2747,18 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) if (dev_intr & UDC_DEVINT_US) { if (dev->driver && dev->driver->suspend) { - spin_lock(&dev->lock); - dev->driver->suspend(&dev->gadget); spin_unlock(&dev->lock); + dev->driver->suspend(&dev->gadget); + spin_lock(&dev->lock); } vbus = pch_vbus_gpio_get_value(dev); if ((dev->vbus_session == 0) && (vbus != 1)) { if (dev->driver && dev->driver->disconnect) { - spin_lock(&dev->lock); - dev->driver->disconnect(&dev->gadget); spin_unlock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); } pch_udc_reconnect(dev); } else if ((dev->vbus_session == 0) |