diff options
Diffstat (limited to 'drivers/usb/gadget/function')
22 files changed, 270 insertions, 385 deletions
diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index 68b289fc0d92..2fa1e80a3ce7 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 0106de8e1904..7ad60ee41914 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 f965403787e4..cad35a502d3f 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 d15b06167de0..99285b416308 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 b9d8f0530058..23933bdf2d9d 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; @@ -430,7 +482,7 @@ static ssize_t f_lb_opts_qlen_show(struct config_item *item, 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; @@ -468,7 +520,7 @@ static ssize_t f_lb_opts_bulk_buflen_show(struct config_item *item, 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 1ab089f86408..223ccf89d226 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; } @@ -2347,7 +2345,6 @@ static void fsg_disable(struct usb_function *f) static void handle_exception(struct fsg_common *common) { - siginfo_t info; int i; struct fsg_buffhd *bh; enum fsg_state old_state; @@ -2359,8 +2356,7 @@ static void handle_exception(struct fsg_common *common) * into a high-priority EXIT exception. */ for (;;) { - int sig = - dequeue_signal_lock(current, ¤t->blocked, &info); + int sig = kernel_dequeue_signal(NULL); if (!sig) break; if (sig != SIGUSR1) { @@ -2662,10 +2658,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 +3068,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 0e2b8eda254e..42acb45e1ab4 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 01a99e5ce465..7ad798ace1e5 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 f6f1e6bd9186..d6396e0909ee 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 c029ef6ba419..157441dbfeba 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 3a378460bf37..0fbfb2b2aa08 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 a04b52678319..e587767e374c 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 ec837f4ea416..6bb44d613bab 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 878a5815450e..9f3ced62d916 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; @@ -915,7 +906,7 @@ static ssize_t f_ss_opts_pattern_show(struct config_item *item, 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; @@ -958,7 +949,7 @@ static ssize_t f_ss_opts_isoc_interval_show(struct config_item *item, 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; @@ -1001,7 +992,7 @@ static ssize_t f_ss_opts_isoc_maxpacket_show(struct config_item *item, char *pag 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; @@ -1044,7 +1035,7 @@ static ssize_t f_ss_opts_isoc_mult_show(struct config_item *item, 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; @@ -1087,7 +1078,7 @@ static ssize_t f_ss_opts_isoc_maxburst_show(struct config_item *item, 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; @@ -1130,7 +1121,7 @@ static ssize_t f_ss_opts_bulk_buflen_show(struct config_item *item, 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 055e4eaf80ae..829c78de9eba 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 ad0103254e6d..6a2346b99f55 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 0a5a1e1aac28..044ca79d3cb5 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; } @@ -1577,11 +1571,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..f7771d86ad6c 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -114,6 +114,7 @@ struct gs_port { struct gs_buf port_write_buf; wait_queue_head_t drain_wait; /* wait while writes drain */ bool write_busy; + wait_queue_head_t close_wait; /* REVISIT this state ... */ struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ @@ -876,7 +877,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; @@ -884,7 +884,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) pr_debug("gs_close: ttyGS%d (%p,%p) done!\n", port->port_num, tty, file); - wake_up(&port->port.close_wait); + wake_up(&port->close_wait); exit: spin_unlock_irq(&port->port_lock); } @@ -1044,6 +1044,7 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) tty_port_init(&port->port); spin_lock_init(&port->port_lock); init_waitqueue_head(&port->drain_wait); + init_waitqueue_head(&port->close_wait); tasklet_init(&port->push, gs_rx_push, (unsigned long) port); @@ -1074,7 +1075,7 @@ static void gserial_free_port(struct gs_port *port) { tasklet_kill(&port->push); /* wait for old opens to finish */ - wait_event(port->port.close_wait, gs_closed(port)); + wait_event(port->close_wait, gs_closed(port)); WARN_ON(port->port_usb != NULL); tty_port_destroy(&port->port); kfree(port); @@ -1224,7 +1225,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 +1264,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/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index d617c39a0052..51d4a1703af2 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -41,7 +41,7 @@ * videobuf2 queue operations */ -static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, +static int uvc_queue_setup(struct vb2_queue *vq, const void *parg, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) { @@ -61,9 +61,10 @@ static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, static int uvc_buffer_prepare(struct vb2_buffer *vb) { struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); - struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf); - if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT && + if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) { uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); return -EINVAL; @@ -75,7 +76,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb) buf->state = UVC_BUF_STATE_QUEUED; buf->mem = vb2_plane_vaddr(vb, 0); buf->length = vb2_plane_size(vb, 0); - if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) buf->bytesused = 0; else buf->bytesused = vb2_get_plane_payload(vb, 0); @@ -86,7 +87,8 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb) static void uvc_buffer_queue(struct vb2_buffer *vb) { struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); - struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf); unsigned long flags; spin_lock_irqsave(&queue->irqlock, flags); @@ -98,7 +100,7 @@ static void uvc_buffer_queue(struct vb2_buffer *vb) * directly. The next QBUF call will fail with -ENODEV. */ buf->state = UVC_BUF_STATE_ERROR; - vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); } spin_unlock_irqrestore(&queue->irqlock, flags); @@ -242,7 +244,7 @@ void uvcg_queue_cancel(struct uvc_video_queue *queue, int disconnect) queue); list_del(&buf->queue); buf->state = UVC_BUF_STATE_ERROR; - vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); + vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR); } /* This must be protected by the irqlock spinlock to avoid race * conditions between uvc_queue_buffer and the disconnection event that @@ -314,7 +316,7 @@ struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue, if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && buf->length != buf->bytesused) { buf->state = UVC_BUF_STATE_QUEUED; - vb2_set_plane_payload(&buf->buf, 0, 0); + vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0); return buf; } @@ -325,12 +327,12 @@ struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue, else nextbuf = NULL; - buf->buf.v4l2_buf.field = V4L2_FIELD_NONE; - buf->buf.v4l2_buf.sequence = queue->sequence++; - v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp); + buf->buf.field = V4L2_FIELD_NONE; + buf->buf.sequence = queue->sequence++; + v4l2_get_timestamp(&buf->buf.timestamp); - vb2_set_plane_payload(&buf->buf, 0, buf->bytesused); - vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE); + vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused); + vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE); return nextbuf; } diff --git a/drivers/usb/gadget/function/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h index 01ca9eab3481..ac461a9a1a70 100644 --- a/drivers/usb/gadget/function/uvc_queue.h +++ b/drivers/usb/gadget/function/uvc_queue.h @@ -6,7 +6,7 @@ #include <linux/kernel.h> #include <linux/poll.h> #include <linux/videodev2.h> -#include <media/videobuf2-core.h> +#include <media/videobuf2-v4l2.h> /* Maximum frame size in bytes, for sanity checking. */ #define UVC_MAX_FRAME_SIZE (16*1024*1024) @@ -26,7 +26,7 @@ enum uvc_buffer_state { }; struct uvc_buffer { - struct vb2_buffer buf; + struct vb2_v4l2_buffer buf; struct list_head queue; enum uvc_buffer_state state; |