summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/legacy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/legacy')
-rw-r--r--drivers/usb/gadget/legacy/inode.c49
-rw-r--r--drivers/usb/gadget/legacy/raw_gadget.c3
-rw-r--r--drivers/usb/gadget/legacy/zero.c27
3 files changed, 44 insertions, 35 deletions
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
index 13c3da49348c..62566a8e7451 100644
--- a/drivers/usb/gadget/legacy/inode.c
+++ b/drivers/usb/gadget/legacy/inode.c
@@ -150,7 +150,6 @@ struct dev_data {
void *buf;
wait_queue_head_t wait;
struct super_block *sb;
- struct dentry *dentry;
/* except this scratch i/o buffer for ep0 */
u8 rbuf[RBUF_SIZE];
@@ -208,7 +207,6 @@ struct ep_data {
struct usb_endpoint_descriptor desc, hs_desc;
struct list_head epfiles;
wait_queue_head_t wait;
- struct dentry *dentry;
};
static inline void get_ep (struct ep_data *data)
@@ -1561,16 +1559,12 @@ static void destroy_ep_files (struct dev_data *dev)
spin_lock_irq (&dev->lock);
while (!list_empty(&dev->epfiles)) {
struct ep_data *ep;
- struct dentry *dentry;
/* break link to FS */
ep = list_first_entry (&dev->epfiles, struct ep_data, epfiles);
list_del_init (&ep->epfiles);
spin_unlock_irq (&dev->lock);
- dentry = ep->dentry;
- ep->dentry = NULL;
-
/* break link to controller */
mutex_lock(&ep->lock);
if (ep->state == STATE_EP_ENABLED)
@@ -1581,10 +1575,11 @@ static void destroy_ep_files (struct dev_data *dev)
mutex_unlock(&ep->lock);
wake_up (&ep->wait);
- put_ep (ep);
/* break link to dcache */
- simple_recursive_removal(dentry, NULL);
+ simple_remove_by_name(dev->sb->s_root, ep->name, NULL);
+
+ put_ep (ep);
spin_lock_irq (&dev->lock);
}
@@ -1592,14 +1587,14 @@ static void destroy_ep_files (struct dev_data *dev)
}
-static struct dentry *
-gadgetfs_create_file (struct super_block *sb, char const *name,
+static int gadgetfs_create_file (struct super_block *sb, char const *name,
void *data, const struct file_operations *fops);
static int activate_ep_files (struct dev_data *dev)
{
struct usb_ep *ep;
struct ep_data *data;
+ int err;
gadget_for_each_ep (ep, dev->gadget) {
@@ -1622,9 +1617,9 @@ static int activate_ep_files (struct dev_data *dev)
if (!data->req)
goto enomem1;
- data->dentry = gadgetfs_create_file (dev->sb, data->name,
+ err = gadgetfs_create_file (dev->sb, data->name,
data, &ep_io_operations);
- if (!data->dentry)
+ if (err)
goto enomem2;
list_add_tail (&data->epfiles, &dev->epfiles);
}
@@ -1988,25 +1983,27 @@ gadgetfs_make_inode (struct super_block *sb,
/* creates in fs root directory, so non-renamable and non-linkable.
* so inode and dentry are paired, until device reconfig.
*/
-static struct dentry *
-gadgetfs_create_file (struct super_block *sb, char const *name,
+static int gadgetfs_create_file (struct super_block *sb, char const *name,
void *data, const struct file_operations *fops)
{
struct dentry *dentry;
struct inode *inode;
- dentry = d_alloc_name(sb->s_root, name);
- if (!dentry)
- return NULL;
-
inode = gadgetfs_make_inode (sb, data, fops,
S_IFREG | (default_perm & S_IRWXUGO));
- if (!inode) {
- dput(dentry);
- return NULL;
+ if (!inode)
+ return -ENOMEM;
+
+ dentry = simple_start_creating(sb->s_root, name);
+ if (IS_ERR(dentry)) {
+ iput(inode);
+ return PTR_ERR(dentry);
}
- d_add (dentry, inode);
- return dentry;
+
+ d_make_persistent(dentry, inode);
+
+ simple_done_creating(dentry);
+ return 0;
}
static const struct super_operations gadget_fs_operations = {
@@ -2059,8 +2056,8 @@ gadgetfs_fill_super (struct super_block *sb, struct fs_context *fc)
goto Enomem;
dev->sb = sb;
- dev->dentry = gadgetfs_create_file(sb, CHIP, dev, &ep0_operations);
- if (!dev->dentry) {
+ rc = gadgetfs_create_file(sb, CHIP, dev, &ep0_operations);
+ if (rc) {
put_dev(dev);
goto Enomem;
}
@@ -2102,7 +2099,7 @@ static void
gadgetfs_kill_sb (struct super_block *sb)
{
mutex_lock(&sb_mutex);
- kill_litter_super (sb);
+ kill_anon_super (sb);
if (the_device) {
put_dev (the_device);
the_device = NULL;
diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c
index b71680c58de6..46f343ba48b3 100644
--- a/drivers/usb/gadget/legacy/raw_gadget.c
+++ b/drivers/usb/gadget/legacy/raw_gadget.c
@@ -40,6 +40,7 @@ MODULE_LICENSE("GPL");
static DEFINE_IDA(driver_id_numbers);
#define DRIVER_DRIVER_NAME_LENGTH_MAX 32
+#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE
#define RAW_EVENT_QUEUE_SIZE 16
@@ -667,6 +668,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr,
return ERR_PTR(-EINVAL);
if (!usb_raw_io_flags_valid(io->flags))
return ERR_PTR(-EINVAL);
+ if (io->length > USB_RAW_IO_LENGTH_MAX)
+ return ERR_PTR(-EINVAL);
if (get_from_user)
data = memdup_user(ptr + sizeof(*io), io->length);
else {
diff --git a/drivers/usb/gadget/legacy/zero.c b/drivers/usb/gadget/legacy/zero.c
index a05785bdeb30..08a21bd0c2ba 100644
--- a/drivers/usb/gadget/legacy/zero.c
+++ b/drivers/usb/gadget/legacy/zero.c
@@ -147,6 +147,12 @@ static struct usb_gadget_strings *dev_strings[] = {
NULL,
};
+static struct usb_function *func_lb;
+static struct usb_function_instance *func_inst_lb;
+
+static struct usb_function *func_ss;
+static struct usb_function_instance *func_inst_ss;
+
/*-------------------------------------------------------------------------*/
static struct timer_list autoresume_timer;
@@ -156,6 +162,7 @@ static void zero_autoresume(struct timer_list *unused)
{
struct usb_composite_dev *cdev = autoresume_cdev;
struct usb_gadget *g = cdev->gadget;
+ int status;
/* unconfigured devices can't issue wakeups */
if (!cdev->config)
@@ -165,10 +172,18 @@ static void zero_autoresume(struct timer_list *unused)
* more significant than just a timer firing; likely
* because of some direct user request.
*/
- if (g->speed != USB_SPEED_UNKNOWN) {
- int status = usb_gadget_wakeup(g);
- INFO(cdev, "%s --> %d\n", __func__, status);
+ if (g->speed == USB_SPEED_UNKNOWN)
+ return;
+
+ if (g->speed >= USB_SPEED_SUPER) {
+ if (loopdefault)
+ status = usb_func_wakeup(func_lb);
+ else
+ status = usb_func_wakeup(func_ss);
+ } else {
+ status = usb_gadget_wakeup(g);
}
+ INFO(cdev, "%s --> %d\n", __func__, status);
}
static void zero_suspend(struct usb_composite_dev *cdev)
@@ -206,9 +221,6 @@ static struct usb_configuration loopback_driver = {
/* .iConfiguration = DYNAMIC */
};
-static struct usb_function *func_ss;
-static struct usb_function_instance *func_inst_ss;
-
static int ss_config_setup(struct usb_configuration *c,
const struct usb_ctrlrequest *ctrl)
{
@@ -248,9 +260,6 @@ module_param_named(isoc_maxburst, gzero_options.isoc_maxburst, uint,
S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)");
-static struct usb_function *func_lb;
-static struct usb_function_instance *func_inst_lb;
-
module_param_named(qlen, gzero_options.qlen, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(qlen, "depth of loopback queue");