summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/function
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/function')
-rw-r--r--drivers/usb/gadget/function/f_ecm.c22
-rw-r--r--drivers/usb/gadget/function/f_hid.c60
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.c3
-rw-r--r--drivers/usb/gadget/function/f_printer.c9
-rw-r--r--drivers/usb/gadget/function/f_uvc.c20
-rw-r--r--drivers/usb/gadget/function/storage_common.c9
-rw-r--r--drivers/usb/gadget/function/u_ether.c4
-rw-r--r--drivers/usb/gadget/function/u_serial.c3
-rw-r--r--drivers/usb/gadget/function/uvc_configfs.c12
9 files changed, 73 insertions, 69 deletions
diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c
index ffe2486fce71..a7ab30e603e2 100644
--- a/drivers/usb/gadget/function/f_ecm.c
+++ b/drivers/usb/gadget/function/f_ecm.c
@@ -685,7 +685,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_composite_dev *cdev = c->cdev;
struct f_ecm *ecm = func_to_ecm(f);
struct usb_string *us;
- int status;
+ int status = 0;
struct usb_ep *ep;
struct f_ecm_opts *ecm_opts;
@@ -695,23 +695,19 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
ecm_opts = container_of(f->fi, struct f_ecm_opts, func_inst);
- /*
- * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
- * configurations are bound in sequence with list_for_each_entry,
- * in each configuration its functions are bound in sequence
- * with list_for_each_entry, so we assume no race condition
- * with regard to ecm_opts->bound access
- */
+ mutex_lock(&ecm_opts->lock);
+
+ gether_set_gadget(ecm_opts->net, cdev->gadget);
+
if (!ecm_opts->bound) {
- mutex_lock(&ecm_opts->lock);
- gether_set_gadget(ecm_opts->net, cdev->gadget);
status = gether_register_netdev(ecm_opts->net);
- mutex_unlock(&ecm_opts->lock);
- if (status)
- return status;
ecm_opts->bound = true;
}
+ mutex_unlock(&ecm_opts->lock);
+ if (status)
+ return status;
+
ecm_string_defs[1].s = ecm->ethaddr;
us = usb_gstrings_attach(cdev, ecm_strings,
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
index ca0a7d9eaa34..a8da3b4a2855 100644
--- a/drivers/usb/gadget/function/f_hid.c
+++ b/drivers/usb/gadget/function/f_hid.c
@@ -71,7 +71,7 @@ struct f_hidg {
wait_queue_head_t write_queue;
struct usb_request *req;
- int minor;
+ struct device dev;
struct cdev cdev;
struct usb_function func;
@@ -84,6 +84,14 @@ static inline struct f_hidg *func_to_hidg(struct usb_function *f)
return container_of(f, struct f_hidg, func);
}
+static void hidg_release(struct device *dev)
+{
+ struct f_hidg *hidg = container_of(dev, struct f_hidg, dev);
+
+ kfree(hidg->set_report_buf);
+ kfree(hidg);
+}
+
/*-------------------------------------------------------------------------*/
/* Static descriptors */
@@ -904,9 +912,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_ep *ep;
struct f_hidg *hidg = func_to_hidg(f);
struct usb_string *us;
- struct device *device;
int status;
- dev_t dev;
/* maybe allocate device-global string IDs, and patch descriptors */
us = usb_gstrings_attach(c->cdev, ct_func_strings,
@@ -999,21 +1005,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
/* create char device */
cdev_init(&hidg->cdev, &f_hidg_fops);
- dev = MKDEV(major, hidg->minor);
- status = cdev_add(&hidg->cdev, dev, 1);
+ status = cdev_device_add(&hidg->cdev, &hidg->dev);
if (status)
goto fail_free_descs;
- device = device_create(hidg_class, NULL, dev, NULL,
- "%s%d", "hidg", hidg->minor);
- if (IS_ERR(device)) {
- status = PTR_ERR(device);
- goto del;
- }
-
return 0;
-del:
- cdev_del(&hidg->cdev);
fail_free_descs:
usb_free_all_descriptors(f);
fail:
@@ -1244,9 +1240,7 @@ static void hidg_free(struct usb_function *f)
hidg = func_to_hidg(f);
opts = container_of(f->fi, struct f_hid_opts, func_inst);
- kfree(hidg->report_desc);
- kfree(hidg->set_report_buf);
- kfree(hidg);
+ put_device(&hidg->dev);
mutex_lock(&opts->lock);
--opts->refcnt;
mutex_unlock(&opts->lock);
@@ -1256,8 +1250,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_hidg *hidg = func_to_hidg(f);
- device_destroy(hidg_class, MKDEV(major, hidg->minor));
- cdev_del(&hidg->cdev);
+ cdev_device_del(&hidg->cdev, &hidg->dev);
usb_free_all_descriptors(f);
}
@@ -1266,6 +1259,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
{
struct f_hidg *hidg;
struct f_hid_opts *opts;
+ int ret;
/* allocate and initialize one new instance */
hidg = kzalloc(sizeof(*hidg), GFP_KERNEL);
@@ -1275,25 +1269,31 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
opts = container_of(fi, struct f_hid_opts, func_inst);
mutex_lock(&opts->lock);
- ++opts->refcnt;
- hidg->minor = opts->minor;
+ device_initialize(&hidg->dev);
+ hidg->dev.release = hidg_release;
+ hidg->dev.class = hidg_class;
+ hidg->dev.devt = MKDEV(major, opts->minor);
+ ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor);
+ if (ret)
+ goto err_unlock;
+
hidg->bInterfaceSubClass = opts->subclass;
hidg->bInterfaceProtocol = opts->protocol;
hidg->report_length = opts->report_length;
hidg->report_desc_length = opts->report_desc_length;
if (opts->report_desc) {
- hidg->report_desc = kmemdup(opts->report_desc,
- opts->report_desc_length,
- GFP_KERNEL);
+ hidg->report_desc = devm_kmemdup(&hidg->dev, opts->report_desc,
+ opts->report_desc_length,
+ GFP_KERNEL);
if (!hidg->report_desc) {
- kfree(hidg);
- mutex_unlock(&opts->lock);
- return ERR_PTR(-ENOMEM);
+ ret = -ENOMEM;
+ goto err_put_device;
}
}
hidg->use_out_ep = !opts->no_out_endpoint;
+ ++opts->refcnt;
mutex_unlock(&opts->lock);
hidg->func.name = "hid";
@@ -1308,6 +1308,12 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
hidg->qlen = 4;
return &hidg->func;
+
+err_put_device:
+ put_device(&hidg->dev);
+err_unlock:
+ mutex_unlock(&opts->lock);
+ return ERR_PTR(ret);
}
DECLARE_USB_FUNCTION_INIT(hid, hidg_alloc_inst, hidg_alloc);
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index 3abf7f586e2a..3a30feb47073 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -176,6 +176,7 @@
#include <linux/fcntl.h>
#include <linux/file.h>
#include <linux/fs.h>
+#include <linux/kstrtox.h>
#include <linux/kthread.h>
#include <linux/sched/signal.h>
#include <linux/limits.h>
@@ -3387,7 +3388,7 @@ static ssize_t fsg_opts_stall_store(struct config_item *item, const char *page,
return -EBUSY;
}
- ret = strtobool(page, &stall);
+ ret = kstrtobool(page, &stall);
if (!ret) {
opts->common->can_stall = stall;
ret = len;
diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c
index a881c69b1f2b..4903d761a872 100644
--- a/drivers/usb/gadget/function/f_printer.c
+++ b/drivers/usb/gadget/function/f_printer.c
@@ -364,7 +364,7 @@ printer_open(struct inode *inode, struct file *fd)
spin_unlock_irqrestore(&dev->lock, flags);
kref_get(&dev->kref);
- DBG(dev, "printer_open returned %x\n", ret);
+
return ret;
}
@@ -382,7 +382,6 @@ printer_close(struct inode *inode, struct file *fd)
spin_unlock_irqrestore(&dev->lock, flags);
kref_put(&dev->kref, printer_dev_free);
- DBG(dev, "printer_close\n");
return 0;
}
@@ -848,8 +847,6 @@ static void printer_reset_interface(struct printer_dev *dev)
if (dev->interface < 0)
return;
- DBG(dev, "%s\n", __func__);
-
if (dev->in_ep->desc)
usb_ep_disable(dev->in_ep);
@@ -887,8 +884,6 @@ static void printer_soft_reset(struct printer_dev *dev)
{
struct usb_request *req;
- INFO(dev, "Received Printer Reset Request\n");
-
if (usb_ep_disable(dev->in_ep))
DBG(dev, "Failed to disable USB in_ep\n");
if (usb_ep_disable(dev->out_ep))
@@ -1185,8 +1180,6 @@ static void printer_func_disable(struct usb_function *f)
{
struct printer_dev *dev = func_to_printer(f);
- DBG(dev, "%s\n", __func__);
-
printer_reset_interface(dev);
}
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
index 6e196e06181e..32f2c1645467 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -39,9 +39,6 @@ MODULE_PARM_DESC(trace, "Trace level bitmask");
/* string IDs are assigned dynamically */
-#define UVC_STRING_CONTROL_IDX 0
-#define UVC_STRING_STREAMING_IDX 1
-
static struct usb_string uvc_en_us_strings[] = {
/* [UVC_STRING_CONTROL_IDX].s = DYNAMIC, */
[UVC_STRING_STREAMING_IDX].s = "Video Streaming",
@@ -216,8 +213,9 @@ uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req)
memset(&v4l2_event, 0, sizeof(v4l2_event));
v4l2_event.type = UVC_EVENT_DATA;
- uvc_event->data.length = req->actual;
- memcpy(&uvc_event->data.data, req->buf, req->actual);
+ uvc_event->data.length = min_t(unsigned int, req->actual,
+ sizeof(uvc_event->data.data));
+ memcpy(&uvc_event->data.data, req->buf, uvc_event->data.length);
v4l2_event_queue(&uvc->vdev, &v4l2_event);
}
}
@@ -228,6 +226,8 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
struct uvc_device *uvc = to_uvc(f);
struct v4l2_event v4l2_event;
struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
+ unsigned int interface = le16_to_cpu(ctrl->wIndex) & 0xff;
+ struct usb_ctrlrequest *mctrl;
if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) {
uvcg_info(f, "invalid request type\n");
@@ -248,6 +248,16 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
memset(&v4l2_event, 0, sizeof(v4l2_event));
v4l2_event.type = UVC_EVENT_SETUP;
memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req));
+
+ /* check for the interface number, fixup the interface number in
+ * the ctrl request so the userspace doesn't have to bother with
+ * offset and configfs parsing
+ */
+ mctrl = &uvc_event->req;
+ mctrl->wIndex &= ~cpu_to_le16(0xff);
+ if (interface == uvc->streaming_intf)
+ mctrl->wIndex = cpu_to_le16(UVC_STRING_STREAMING_IDX);
+
v4l2_event_queue(&uvc->vdev, &v4l2_event);
return 0;
diff --git a/drivers/usb/gadget/function/storage_common.c b/drivers/usb/gadget/function/storage_common.c
index 208c6a92780a..2a4163b0f6fe 100644
--- a/drivers/usb/gadget/function/storage_common.c
+++ b/drivers/usb/gadget/function/storage_common.c
@@ -23,6 +23,7 @@
#include <linux/blkdev.h>
#include <linux/file.h>
#include <linux/fs.h>
+#include <linux/kstrtox.h>
#include <linux/usb/composite.h>
#include "storage_common.h"
@@ -396,7 +397,7 @@ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
ssize_t rc;
bool ro;
- rc = strtobool(buf, &ro);
+ rc = kstrtobool(buf, &ro);
if (rc)
return rc;
@@ -419,7 +420,7 @@ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count)
bool nofua;
int ret;
- ret = strtobool(buf, &nofua);
+ ret = kstrtobool(buf, &nofua);
if (ret)
return ret;
@@ -470,7 +471,7 @@ ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem,
bool cdrom;
int ret;
- ret = strtobool(buf, &cdrom);
+ ret = kstrtobool(buf, &cdrom);
if (ret)
return ret;
@@ -493,7 +494,7 @@ ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
bool removable;
int ret;
- ret = strtobool(buf, &removable);
+ ret = kstrtobool(buf, &removable);
if (ret)
return ret;
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index e06022873df1..8f12f3f8f6ee 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -798,7 +798,6 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
net->max_mtu = GETHER_MAX_MTU_SIZE;
dev->gadget = g;
- SET_NETDEV_DEV(net, &g->dev);
SET_NETDEV_DEVTYPE(net, &gadget_type);
status = register_netdev(net);
@@ -873,8 +872,6 @@ int gether_register_netdev(struct net_device *net)
struct usb_gadget *g;
int status;
- if (!net->dev.parent)
- return -EINVAL;
dev = netdev_priv(net);
g = dev->gadget;
@@ -905,7 +902,6 @@ void gether_set_gadget(struct net_device *net, struct usb_gadget *g)
dev = netdev_priv(net);
dev->gadget = g;
- SET_NETDEV_DEV(net, &g->dev);
}
EXPORT_SYMBOL_GPL(gether_set_gadget);
diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c
index 7538279f9817..840626e064e1 100644
--- a/drivers/usb/gadget/function/u_serial.c
+++ b/drivers/usb/gadget/function/u_serial.c
@@ -24,6 +24,7 @@
#include <linux/export.h>
#include <linux/module.h>
#include <linux/console.h>
+#include <linux/kstrtox.h>
#include <linux/kthread.h>
#include <linux/workqueue.h>
#include <linux/kfifo.h>
@@ -1070,7 +1071,7 @@ ssize_t gserial_set_console(unsigned char port_num, const char *page, size_t cou
bool enable;
int ret;
- ret = strtobool(page, &enable);
+ ret = kstrtobool(page, &enable);
if (ret)
return ret;
diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
index 4303a3283ba0..76cb60d13049 100644
--- a/drivers/usb/gadget/function/uvc_configfs.c
+++ b/drivers/usb/gadget/function/uvc_configfs.c
@@ -1512,7 +1512,7 @@ UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, 8);
UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
-UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8);
+UVCG_UNCOMPRESSED_ATTR_RO(bm_interlace_flags, bmInterlaceFlags, 8);
#undef UVCG_UNCOMPRESSED_ATTR
#undef UVCG_UNCOMPRESSED_ATTR_RO
@@ -1541,7 +1541,7 @@ static struct configfs_attribute *uvcg_uncompressed_attrs[] = {
&uvcg_uncompressed_attr_b_default_frame_index,
&uvcg_uncompressed_attr_b_aspect_ratio_x,
&uvcg_uncompressed_attr_b_aspect_ratio_y,
- &uvcg_uncompressed_attr_bm_interface_flags,
+ &uvcg_uncompressed_attr_bm_interlace_flags,
&uvcg_uncompressed_attr_bma_controls,
NULL,
};
@@ -1574,7 +1574,7 @@ static struct config_group *uvcg_uncompressed_make(struct config_group *group,
h->desc.bDefaultFrameIndex = 1;
h->desc.bAspectRatioX = 0;
h->desc.bAspectRatioY = 0;
- h->desc.bmInterfaceFlags = 0;
+ h->desc.bmInterlaceFlags = 0;
h->desc.bCopyProtect = 0;
INIT_LIST_HEAD(&h->fmt.frames);
@@ -1700,7 +1700,7 @@ UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, 8);
UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
-UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8);
+UVCG_MJPEG_ATTR_RO(bm_interlace_flags, bmInterlaceFlags, 8);
#undef UVCG_MJPEG_ATTR
#undef UVCG_MJPEG_ATTR_RO
@@ -1728,7 +1728,7 @@ static struct configfs_attribute *uvcg_mjpeg_attrs[] = {
&uvcg_mjpeg_attr_bm_flags,
&uvcg_mjpeg_attr_b_aspect_ratio_x,
&uvcg_mjpeg_attr_b_aspect_ratio_y,
- &uvcg_mjpeg_attr_bm_interface_flags,
+ &uvcg_mjpeg_attr_bm_interlace_flags,
&uvcg_mjpeg_attr_bma_controls,
NULL,
};
@@ -1755,7 +1755,7 @@ static struct config_group *uvcg_mjpeg_make(struct config_group *group,
h->desc.bDefaultFrameIndex = 1;
h->desc.bAspectRatioX = 0;
h->desc.bAspectRatioY = 0;
- h->desc.bmInterfaceFlags = 0;
+ h->desc.bmInterlaceFlags = 0;
h->desc.bCopyProtect = 0;
INIT_LIST_HEAD(&h->fmt.frames);