Merge tag 'usb-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB/PHY updates from Greg KH:
 "Here is the big set of USB and PHY driver patches for 4.21-rc1.

  All of the usual bits are in here:

  - loads of USB gadget driver updates and additions

  - new device ids

  - phy driver updates

  - xhci reworks and new features

  - typec updates

  Full details are in the shortlog.

  All of these have been in linux-next for a long time with no reported
  issues"

* tag 'usb-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (142 commits)
  USB: serial: option: add Fibocom NL678 series
  cdc-acm: fix abnormal DATA RX issue for Mediatek Preloader.
  usb: r8a66597: Fix a possible concurrency use-after-free bug in r8a66597_endpoint_disable()
  usb: typec: tcpm: Extend the matching rules on PPS APDO selection
  usb: typec: Improve Alt Mode documentation
  usb: musb: dsps: fix runtime pm for peripheral mode
  usb: musb: dsps: fix otg state machine
  USB: serial: pl2303: add ids for Hewlett-Packard HP POS pole displays
  usb: renesas_usbhs: add support for RZ/G2E
  usb: ehci-omap: Fix deferred probe for phy handling
  usb: roles: Add a description for the class to Kconfig
  usb: renesas_usbhs: mark PM functions as __maybe_unused
  usb: core: Remove unnecessary memset()
  usb: host: isp1362-hcd: convert to DEFINE_SHOW_ATTRIBUTE
  phy: qcom-qmp: Expose provided clocks to DT
  dt-bindings: phy-qcom-qmp: Move #clock-cells to child
  phy: qcom-qmp: Utilize fully-specified DT registers
  dt-bindings: phy-qcom-qmp: Fix register underspecification
  phy: ti: fix semicolon.cocci warnings
  phy: dphy: Add configuration helpers
  ...
此提交包含在:
Linus Torvalds
2018-12-28 20:30:00 -08:00
當前提交 c0ea81b4d3
共有 118 個檔案被更改,包括 3634 行新增844 行删除

查看文件

@@ -18,11 +18,15 @@
#include <linux/pagemap.h>
#include <linux/export.h>
#include <linux/hid.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/sched/signal.h>
#include <linux/uio.h>
#include <linux/vmalloc.h>
#include <asm/unaligned.h>
#include <linux/usb/ccid.h>
#include <linux/usb/composite.h>
#include <linux/usb/functionfs.h>
@@ -218,6 +222,8 @@ struct ffs_io_data {
struct usb_ep *ep;
struct usb_request *req;
struct sg_table sgt;
bool use_sg;
struct ffs_data *ffs;
};
@@ -749,6 +755,65 @@ static ssize_t ffs_copy_to_iter(void *data, int data_len, struct iov_iter *iter)
return ret;
}
/*
* allocate a virtually contiguous buffer and create a scatterlist describing it
* @sg_table - pointer to a place to be filled with sg_table contents
* @size - required buffer size
*/
static void *ffs_build_sg_list(struct sg_table *sgt, size_t sz)
{
struct page **pages;
void *vaddr, *ptr;
unsigned int n_pages;
int i;
vaddr = vmalloc(sz);
if (!vaddr)
return NULL;
n_pages = PAGE_ALIGN(sz) >> PAGE_SHIFT;
pages = kvmalloc_array(n_pages, sizeof(struct page *), GFP_KERNEL);
if (!pages) {
vfree(vaddr);
return NULL;
}
for (i = 0, ptr = vaddr; i < n_pages; ++i, ptr += PAGE_SIZE)
pages[i] = vmalloc_to_page(ptr);
if (sg_alloc_table_from_pages(sgt, pages, n_pages, 0, sz, GFP_KERNEL)) {
kvfree(pages);
vfree(vaddr);
return NULL;
}
kvfree(pages);
return vaddr;
}
static inline void *ffs_alloc_buffer(struct ffs_io_data *io_data,
size_t data_len)
{
if (io_data->use_sg)
return ffs_build_sg_list(&io_data->sgt, data_len);
return kmalloc(data_len, GFP_KERNEL);
}
static inline void ffs_free_buffer(struct ffs_io_data *io_data)
{
if (!io_data->buf)
return;
if (io_data->use_sg) {
sg_free_table(&io_data->sgt);
vfree(io_data->buf);
} else {
kfree(io_data->buf);
}
}
static void ffs_user_copy_worker(struct work_struct *work)
{
struct ffs_io_data *io_data = container_of(work, struct ffs_io_data,
@@ -776,7 +841,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
if (io_data->read)
kfree(io_data->to_free);
kfree(io_data->buf);
ffs_free_buffer(io_data);
kfree(io_data);
}
@@ -932,6 +997,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
* earlier
*/
gadget = epfile->ffs->gadget;
io_data->use_sg = gadget->sg_supported && data_len > PAGE_SIZE;
spin_lock_irq(&epfile->ffs->eps_lock);
/* In the meantime, endpoint got disabled or changed. */
@@ -948,7 +1014,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
data_len = usb_ep_align_maybe(gadget, ep->ep, data_len);
spin_unlock_irq(&epfile->ffs->eps_lock);
data = kmalloc(data_len, GFP_KERNEL);
data = ffs_alloc_buffer(io_data, data_len);
if (unlikely(!data)) {
ret = -ENOMEM;
goto error_mutex;
@@ -988,8 +1054,16 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
bool interrupted = false;
req = ep->req;
req->buf = data;
req->length = data_len;
if (io_data->use_sg) {
req->buf = NULL;
req->sg = io_data->sgt.sgl;
req->num_sgs = io_data->sgt.nents;
} else {
req->buf = data;
}
req->length = data_len;
io_data->buf = data;
req->context = &done;
req->complete = ffs_epfile_io_complete;
@@ -1022,8 +1096,14 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
} else if (!(req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC))) {
ret = -ENOMEM;
} else {
req->buf = data;
req->length = data_len;
if (io_data->use_sg) {
req->buf = NULL;
req->sg = io_data->sgt.sgl;
req->num_sgs = io_data->sgt.nents;
} else {
req->buf = data;
}
req->length = data_len;
io_data->buf = data;
io_data->ep = ep->ep;
@@ -1052,7 +1132,7 @@ error_lock:
error_mutex:
mutex_unlock(&epfile->mutex);
error:
kfree(data);
ffs_free_buffer(io_data);
return ret;
}
@@ -1926,7 +2006,7 @@ typedef int (*ffs_os_desc_callback)(enum ffs_os_desc_type entity,
static int __must_check ffs_do_single_desc(char *data, unsigned len,
ffs_entity_callback entity,
void *priv)
void *priv, int *current_class)
{
struct usb_descriptor_header *_ds = (void *)data;
u8 length;
@@ -1984,6 +2064,7 @@ static int __must_check ffs_do_single_desc(char *data, unsigned len,
__entity(INTERFACE, ds->bInterfaceNumber);
if (ds->iInterface)
__entity(STRING, ds->iInterface);
*current_class = ds->bInterfaceClass;
}
break;
@@ -1997,11 +2078,22 @@ static int __must_check ffs_do_single_desc(char *data, unsigned len,
}
break;
case HID_DT_HID:
pr_vdebug("hid descriptor\n");
if (length != sizeof(struct hid_descriptor))
goto inv_length;
break;
case USB_TYPE_CLASS | 0x01:
if (*current_class == USB_INTERFACE_CLASS_HID) {
pr_vdebug("hid descriptor\n");
if (length != sizeof(struct hid_descriptor))
goto inv_length;
break;
} else if (*current_class == USB_INTERFACE_CLASS_CCID) {
pr_vdebug("ccid descriptor\n");
if (length != sizeof(struct ccid_descriptor))
goto inv_length;
break;
} else {
pr_vdebug("unknown descriptor: %d for class %d\n",
_ds->bDescriptorType, *current_class);
return -EINVAL;
}
case USB_DT_OTG:
if (length != sizeof(struct usb_otg_descriptor))
@@ -2058,6 +2150,7 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len,
{
const unsigned _len = len;
unsigned long num = 0;
int current_class = -1;
ENTER();
@@ -2078,7 +2171,8 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len,
if (!data)
return _len - len;
ret = ffs_do_single_desc(data, len, entity, priv);
ret = ffs_do_single_desc(data, len, entity, priv,
&current_class);
if (unlikely(ret < 0)) {
pr_debug("%s returns %d\n", __func__, ret);
return ret;

查看文件

@@ -102,7 +102,7 @@ static void uvc_buffer_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(&queue->irqlock, flags);
}
static struct vb2_ops uvc_queue_qops = {
static const struct vb2_ops uvc_queue_qops = {
.queue_setup = uvc_queue_setup,
.buf_prepare = uvc_buffer_prepare,
.buf_queue = uvc_buffer_queue,