Merge tag 'usb-for-v3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 8 Mar 2014 00:47:36 +0000 (16:47 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 8 Mar 2014 00:47:36 +0000 (16:47 -0800)
Felipe writes:

usb: patches for v3.15

another substantial pull request with new features all over
the place.

dwc3 got a bit closer towards hibernation support with after
a few patches re-factoring code to be reused for hibernation.
Also in dwc3 two new workarounds for known silicon bugs have
been implemented, some randconfig build errors have been fixed,
and it was taught about the new generic phy layer.

MUSB on AM335x now supports isochronous transfers thanks to
George Cherian's work.

The atmel_usba driver got two crash fixes: one when no endpoint
was specified in DeviceTree data and another when stopping the UDC
in DEBUG builds.

Function FS got a much needed fix to ffs_epfile_io() which was
copying too much data to userspace in some cases.

The printer gadget got a fix for a possible deadlock and plugged
a memory leak.

Ethernet drivers now use NAPI for RX which gives improved throughput.

Other than that, the usual miscelaneous fixes, cleanups, and
the like.

Signed-of-by: Felipe Balbi <balbi@ti.com>
1  2 
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/printer.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_host.c

@@@ -581,10 -656,55 +656,54 @@@ static void ffs_epfile_io_complete(stru
        }
  }
  
- static ssize_t ffs_epfile_io(struct file *file,
-                            char __user *buf, size_t len, int read)
+ static void ffs_user_copy_worker(struct work_struct *work)
+ {
+       struct ffs_io_data *io_data = container_of(work, struct ffs_io_data,
+                                                  work);
+       int ret = io_data->req->status ? io_data->req->status :
+                                        io_data->req->actual;
+       if (io_data->read && ret > 0) {
+               int i;
+               size_t pos = 0;
+               use_mm(io_data->mm);
+               for (i = 0; i < io_data->nr_segs; i++) {
+                       if (unlikely(copy_to_user(io_data->iovec[i].iov_base,
+                                                &io_data->buf[pos],
+                                                io_data->iovec[i].iov_len))) {
+                               ret = -EFAULT;
+                               break;
+                       }
+                       pos += io_data->iovec[i].iov_len;
+               }
+               unuse_mm(io_data->mm);
+       }
+       aio_complete(io_data->kiocb, ret, ret);
+       usb_ep_free_request(io_data->ep, io_data->req);
+       io_data->kiocb->private = NULL;
+       if (io_data->read)
+               kfree(io_data->iovec);
+       kfree(io_data->buf);
+       kfree(io_data);
+ }
+ static void ffs_epfile_async_io_complete(struct usb_ep *_ep,
+                                        struct usb_request *req)
+ {
+       struct ffs_io_data *io_data = req->context;
+       ENTER();
+       INIT_WORK(&io_data->work, ffs_user_copy_worker);
+       schedule_work(&io_data->work);
+ }
+ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
  {
        struct ffs_epfile *epfile = file->private_data;
 -      struct usb_gadget *gadget = epfile->ffs->gadget;
        struct ffs_ep *ep;
        char *data = NULL;
        ssize_t ret, data_len;
Simple merge
Simple merge
Simple merge