diff options
author | INSUN PYO <insun.pyo@samsung.com> | 2018-10-04 10:26:22 +0900 |
---|---|---|
committer | Seung-Woo Kim <sw0312.kim@samsung.com> | 2018-10-11 12:44:15 +0900 |
commit | fb8f8e60820f8d5428d6b02287c4373893f9a0f7 (patch) | |
tree | 72836622701127fce676c346213a03f0d2bff7e2 | |
parent | a205a11445ca26e72f7ef1ee6dddf075315f3b49 (diff) | |
download | linux-3.10-sc7730-accepted/tizen_5.0_unified.tar.gz linux-3.10-sc7730-accepted/tizen_5.0_unified.tar.bz2 linux-3.10-sc7730-accepted/tizen_5.0_unified.zip |
usb: gadget: f_fs: remove global epin/epout fileio completionsubmit/tizen_5.0/20181106.000001submit/tizen_5.0/20181101.000009submit/tizen/20181011.060219accepted/tizen/unified/20181011.095032accepted/tizen/5.0/unified/20181106.202900accepted/tizen_5.0_unified
In product code, global epin/epi fileio completion is applied but
if more than one multiple instance of functionfs are used, the
global completions cause transfer error. Remove global epin/epout
fileio to resolve transfer error in functionfs.
Change-Id: Ic71b34bbc83e0cfd9e76321fc4b8f86c2e259bfd
Signed-off-by: INSUN PYO <insun.pyo@samsung.com>
[sw0312.kim: rebase and remove related unnecessary part also]
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
-rw-r--r-- | drivers/usb/gadget/f_fs.c | 47 |
1 files changed, 20 insertions, 27 deletions
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index ac03922d..079dacc0 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -146,8 +146,6 @@ struct ffs_data { struct usb_request *ep0req; /* P: mutex */ struct completion ep0req_completion; /* P: mutex */ int ep0req_status; /* P: mutex */ - struct completion epin_completion; /* P: mutex */ - struct completion epout_completion; /* P: mutex */ /* reference counter */ atomic_t ref; @@ -795,10 +793,8 @@ static const struct file_operations ffs_ep0_operations = { static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req) { - struct ffs_ep *ep = _ep->driver_data; ENTER(); - /* req may be freed during unbind */ - if (ep && ep->req && likely(req->context)) { + if (likely(req->context)) { struct ffs_ep *ep = _ep->driver_data; ep->status = req->status ? req->status : req->actual; complete(req->context); @@ -809,7 +805,6 @@ static ssize_t ffs_epfile_io(struct file *file, char __user *buf, size_t len, int read) { struct ffs_epfile *epfile = file->private_data; - struct ffs_data *ffs = epfile->ffs; struct ffs_ep *ep; char *data = NULL; ssize_t ret, data_len; @@ -892,37 +887,37 @@ first_try: spin_unlock_irq(&epfile->ffs->eps_lock); ret = -EBADMSG; } else { - /* Fire the request */ - struct completion *done; - + DECLARE_COMPLETION_ONSTACK(done); struct usb_request *req = ep->req; + req->context = &done; req->complete = ffs_epfile_io_complete; req->buf = data; req->length = data_len; - if (read) { - INIT_COMPLETION(ffs->epout_completion); - req->context = done = &ffs->epout_completion; - } else { - INIT_COMPLETION(ffs->epin_completion); - req->context = done = &ffs->epin_completion; - } - ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC); spin_unlock_irq(&epfile->ffs->eps_lock); if (unlikely(ret < 0)) { /* nop */ - } else if (unlikely(wait_for_completion_interruptible(done))) { - ret = -EINTR; - usb_ep_dequeue(ep->ep, req); + } else if (unlikely( + wait_for_completion_interruptible(&done))) { + ret = -EINTR; + usb_ep_dequeue(ep->ep, req); } else { - ret = ep->status; - if (read && ret > 0){ - ret = min_t(size_t, ret, len); - if(unlikely(copy_to_user(buf, data, ret))) - ret = -EFAULT; + /* + * XXX We may end up silently droping data + * here. Since data_len (i.e. req->length) may + * be bigger than len (after being rounded up + * to maxpacketsize), we may end up with more + * data then user space has space for. + */ + ret = ep->status; + if (read && ret > 0) { + ret = min_t(size_t, ret, len); + + if(unlikely(copy_to_user(buf, data, ret))) + ret = -EFAULT; } } } @@ -1433,8 +1428,6 @@ static struct ffs_data *ffs_data_new(void) spin_lock_init(&ffs->eps_lock); init_waitqueue_head(&ffs->ev.waitq); init_completion(&ffs->ep0req_completion); - init_completion(&ffs->epin_completion); - init_completion(&ffs->epout_completion); /* XXX REVISIT need to update it in some places, or do we? */ ffs->ev.can_stall = 1; |