.. | .. |
---|
12 | 12 | #include <linux/init.h> |
---|
13 | 13 | #include <linux/module.h> |
---|
14 | 14 | #include <linux/fs.h> |
---|
| 15 | +#include <linux/fs_context.h> |
---|
15 | 16 | #include <linux/pagemap.h> |
---|
16 | 17 | #include <linux/uts.h> |
---|
17 | 18 | #include <linux/wait.h> |
---|
.. | .. |
---|
20 | 21 | #include <linux/sched.h> |
---|
21 | 22 | #include <linux/slab.h> |
---|
22 | 23 | #include <linux/poll.h> |
---|
23 | | -#include <linux/mmu_context.h> |
---|
| 24 | +#include <linux/kthread.h> |
---|
24 | 25 | #include <linux/aio.h> |
---|
25 | 26 | #include <linux/uio.h> |
---|
26 | 27 | #include <linux/refcount.h> |
---|
.. | .. |
---|
228 | 229 | */ |
---|
229 | 230 | |
---|
230 | 231 | static const char *CHIP; |
---|
| 232 | +static DEFINE_MUTEX(sb_mutex); /* Serialize superblock operations */ |
---|
231 | 233 | |
---|
232 | 234 | /*----------------------------------------------------------------------*/ |
---|
233 | 235 | |
---|
.. | .. |
---|
313 | 315 | case STATE_EP_READY: /* not configured yet */ |
---|
314 | 316 | if (is_write) |
---|
315 | 317 | return 0; |
---|
316 | | - // FALLTHRU |
---|
| 318 | + fallthrough; |
---|
317 | 319 | case STATE_EP_UNBOUND: /* clean disconnect */ |
---|
318 | 320 | break; |
---|
319 | 321 | // case STATE_EP_DISABLED: /* "can't happen" */ |
---|
.. | .. |
---|
345 | 347 | spin_unlock_irq (&epdata->dev->lock); |
---|
346 | 348 | |
---|
347 | 349 | if (likely (value == 0)) { |
---|
348 | | - value = wait_event_interruptible (done.wait, done.done); |
---|
| 350 | + value = wait_for_completion_interruptible(&done); |
---|
349 | 351 | if (value != 0) { |
---|
350 | 352 | spin_lock_irq (&epdata->dev->lock); |
---|
351 | 353 | if (likely (epdata->ep != NULL)) { |
---|
.. | .. |
---|
354 | 356 | usb_ep_dequeue (epdata->ep, epdata->req); |
---|
355 | 357 | spin_unlock_irq (&epdata->dev->lock); |
---|
356 | 358 | |
---|
357 | | - wait_event (done.wait, done.done); |
---|
| 359 | + wait_for_completion(&done); |
---|
358 | 360 | if (epdata->status == -ECONNRESET) |
---|
359 | 361 | epdata->status = -EINTR; |
---|
360 | 362 | } else { |
---|
361 | 363 | spin_unlock_irq (&epdata->dev->lock); |
---|
362 | 364 | |
---|
363 | 365 | DBG (epdata->dev, "endpoint gone\n"); |
---|
| 366 | + wait_for_completion(&done); |
---|
364 | 367 | epdata->status = -ENODEV; |
---|
365 | 368 | } |
---|
366 | 369 | } |
---|
.. | .. |
---|
463 | 466 | struct kiocb *iocb = priv->iocb; |
---|
464 | 467 | size_t ret; |
---|
465 | 468 | |
---|
466 | | - use_mm(mm); |
---|
| 469 | + kthread_use_mm(mm); |
---|
467 | 470 | ret = copy_to_iter(priv->buf, priv->actual, &priv->to); |
---|
468 | | - unuse_mm(mm); |
---|
| 471 | + kthread_unuse_mm(mm); |
---|
469 | 472 | if (!ret) |
---|
470 | 473 | ret = -EFAULT; |
---|
471 | 474 | |
---|
.. | .. |
---|
1085 | 1088 | case GADGETFS_DISCONNECT: |
---|
1086 | 1089 | if (dev->state == STATE_DEV_SETUP) |
---|
1087 | 1090 | dev->setup_abort = 1; |
---|
1088 | | - // FALL THROUGH |
---|
| 1091 | + fallthrough; |
---|
1089 | 1092 | case GADGETFS_CONNECT: |
---|
1090 | 1093 | dev->ev_next = 0; |
---|
1091 | 1094 | break; |
---|
.. | .. |
---|
1220 | 1223 | if (dev->state <= STATE_DEV_OPENED) |
---|
1221 | 1224 | return DEFAULT_POLLMASK; |
---|
1222 | 1225 | |
---|
1223 | | - poll_wait(fd, &dev->wait, wait); |
---|
| 1226 | + poll_wait(fd, &dev->wait, wait); |
---|
1224 | 1227 | |
---|
1225 | | - spin_lock_irq (&dev->lock); |
---|
| 1228 | + spin_lock_irq(&dev->lock); |
---|
1226 | 1229 | |
---|
1227 | | - /* report fd mode change before acting on it */ |
---|
1228 | | - if (dev->setup_abort) { |
---|
1229 | | - dev->setup_abort = 0; |
---|
1230 | | - mask = EPOLLHUP; |
---|
1231 | | - goto out; |
---|
1232 | | - } |
---|
| 1230 | + /* report fd mode change before acting on it */ |
---|
| 1231 | + if (dev->setup_abort) { |
---|
| 1232 | + dev->setup_abort = 0; |
---|
| 1233 | + mask = EPOLLHUP; |
---|
| 1234 | + goto out; |
---|
| 1235 | + } |
---|
1233 | 1236 | |
---|
1234 | | - if (dev->state == STATE_DEV_SETUP) { |
---|
1235 | | - if (dev->setup_in || dev->setup_can_stall) |
---|
1236 | | - mask = EPOLLOUT; |
---|
1237 | | - } else { |
---|
1238 | | - if (dev->ev_next != 0) |
---|
1239 | | - mask = EPOLLIN; |
---|
1240 | | - } |
---|
| 1237 | + if (dev->state == STATE_DEV_SETUP) { |
---|
| 1238 | + if (dev->setup_in || dev->setup_can_stall) |
---|
| 1239 | + mask = EPOLLOUT; |
---|
| 1240 | + } else { |
---|
| 1241 | + if (dev->ev_next != 0) |
---|
| 1242 | + mask = EPOLLIN; |
---|
| 1243 | + } |
---|
1241 | 1244 | out: |
---|
1242 | | - spin_unlock_irq(&dev->lock); |
---|
1243 | | - return mask; |
---|
| 1245 | + spin_unlock_irq(&dev->lock); |
---|
| 1246 | + return mask; |
---|
1244 | 1247 | } |
---|
1245 | 1248 | |
---|
1246 | 1249 | static long dev_ioctl (struct file *fd, unsigned code, unsigned long value) |
---|
.. | .. |
---|
1394 | 1397 | make_qualifier (dev); |
---|
1395 | 1398 | break; |
---|
1396 | 1399 | case USB_DT_OTHER_SPEED_CONFIG: |
---|
1397 | | - // FALLTHROUGH |
---|
1398 | 1400 | case USB_DT_CONFIG: |
---|
1399 | 1401 | value = config_buf (dev, |
---|
1400 | 1402 | w_value >> 8, |
---|
.. | .. |
---|
1731 | 1733 | case STATE_DEV_UNCONNECTED: |
---|
1732 | 1734 | next_event (dev, GADGETFS_SUSPEND); |
---|
1733 | 1735 | ep0_readable (dev); |
---|
1734 | | - /* FALLTHROUGH */ |
---|
| 1736 | + fallthrough; |
---|
1735 | 1737 | default: |
---|
1736 | 1738 | break; |
---|
1737 | 1739 | } |
---|
.. | .. |
---|
1748 | 1750 | .suspend = gadgetfs_suspend, |
---|
1749 | 1751 | |
---|
1750 | 1752 | .driver = { |
---|
1751 | | - .name = (char *) shortname, |
---|
| 1753 | + .name = shortname, |
---|
1752 | 1754 | }, |
---|
1753 | 1755 | }; |
---|
1754 | 1756 | |
---|
.. | .. |
---|
1828 | 1830 | spin_lock_irq (&dev->lock); |
---|
1829 | 1831 | value = -EINVAL; |
---|
1830 | 1832 | if (dev->buf) { |
---|
| 1833 | + spin_unlock_irq(&dev->lock); |
---|
1831 | 1834 | kfree(kbuf); |
---|
1832 | | - goto fail; |
---|
| 1835 | + return value; |
---|
1833 | 1836 | } |
---|
1834 | 1837 | dev->buf = kbuf; |
---|
1835 | 1838 | |
---|
.. | .. |
---|
1876 | 1879 | |
---|
1877 | 1880 | value = usb_gadget_probe_driver(&gadgetfs_driver); |
---|
1878 | 1881 | if (value != 0) { |
---|
1879 | | - kfree (dev->buf); |
---|
1880 | | - dev->buf = NULL; |
---|
| 1882 | + spin_lock_irq(&dev->lock); |
---|
| 1883 | + goto fail; |
---|
1881 | 1884 | } else { |
---|
1882 | 1885 | /* at this point "good" hardware has for the first time |
---|
1883 | 1886 | * let the USB the host see us. alternatively, if users |
---|
.. | .. |
---|
1894 | 1897 | return value; |
---|
1895 | 1898 | |
---|
1896 | 1899 | fail: |
---|
| 1900 | + dev->config = NULL; |
---|
| 1901 | + dev->hs_config = NULL; |
---|
| 1902 | + dev->dev = NULL; |
---|
1897 | 1903 | spin_unlock_irq (&dev->lock); |
---|
1898 | 1904 | pr_debug ("%s: %s fail %zd, %p\n", shortname, __func__, value, dev); |
---|
1899 | 1905 | kfree (dev->buf); |
---|
.. | .. |
---|
2003 | 2009 | }; |
---|
2004 | 2010 | |
---|
2005 | 2011 | static int |
---|
2006 | | -gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) |
---|
| 2012 | +gadgetfs_fill_super (struct super_block *sb, struct fs_context *fc) |
---|
2007 | 2013 | { |
---|
2008 | 2014 | struct inode *inode; |
---|
2009 | 2015 | struct dev_data *dev; |
---|
| 2016 | + int rc; |
---|
2010 | 2017 | |
---|
2011 | | - if (the_device) |
---|
2012 | | - return -ESRCH; |
---|
| 2018 | + mutex_lock(&sb_mutex); |
---|
| 2019 | + |
---|
| 2020 | + if (the_device) { |
---|
| 2021 | + rc = -ESRCH; |
---|
| 2022 | + goto Done; |
---|
| 2023 | + } |
---|
2013 | 2024 | |
---|
2014 | 2025 | CHIP = usb_get_gadget_udc_name(); |
---|
2015 | | - if (!CHIP) |
---|
2016 | | - return -ENODEV; |
---|
| 2026 | + if (!CHIP) { |
---|
| 2027 | + rc = -ENODEV; |
---|
| 2028 | + goto Done; |
---|
| 2029 | + } |
---|
2017 | 2030 | |
---|
2018 | 2031 | /* superblock */ |
---|
2019 | 2032 | sb->s_blocksize = PAGE_SIZE; |
---|
.. | .. |
---|
2050 | 2063 | * from binding to a controller. |
---|
2051 | 2064 | */ |
---|
2052 | 2065 | the_device = dev; |
---|
2053 | | - return 0; |
---|
| 2066 | + rc = 0; |
---|
| 2067 | + goto Done; |
---|
2054 | 2068 | |
---|
2055 | | -Enomem: |
---|
| 2069 | + Enomem: |
---|
2056 | 2070 | kfree(CHIP); |
---|
2057 | 2071 | CHIP = NULL; |
---|
| 2072 | + rc = -ENOMEM; |
---|
2058 | 2073 | |
---|
2059 | | - return -ENOMEM; |
---|
| 2074 | + Done: |
---|
| 2075 | + mutex_unlock(&sb_mutex); |
---|
| 2076 | + return rc; |
---|
2060 | 2077 | } |
---|
2061 | 2078 | |
---|
2062 | 2079 | /* "mount -t gadgetfs path /dev/gadget" ends up here */ |
---|
2063 | | -static struct dentry * |
---|
2064 | | -gadgetfs_mount (struct file_system_type *t, int flags, |
---|
2065 | | - const char *path, void *opts) |
---|
| 2080 | +static int gadgetfs_get_tree(struct fs_context *fc) |
---|
2066 | 2081 | { |
---|
2067 | | - return mount_single (t, flags, opts, gadgetfs_fill_super); |
---|
| 2082 | + return get_tree_single(fc, gadgetfs_fill_super); |
---|
| 2083 | +} |
---|
| 2084 | + |
---|
| 2085 | +static const struct fs_context_operations gadgetfs_context_ops = { |
---|
| 2086 | + .get_tree = gadgetfs_get_tree, |
---|
| 2087 | +}; |
---|
| 2088 | + |
---|
| 2089 | +static int gadgetfs_init_fs_context(struct fs_context *fc) |
---|
| 2090 | +{ |
---|
| 2091 | + fc->ops = &gadgetfs_context_ops; |
---|
| 2092 | + return 0; |
---|
2068 | 2093 | } |
---|
2069 | 2094 | |
---|
2070 | 2095 | static void |
---|
2071 | 2096 | gadgetfs_kill_sb (struct super_block *sb) |
---|
2072 | 2097 | { |
---|
| 2098 | + mutex_lock(&sb_mutex); |
---|
2073 | 2099 | kill_litter_super (sb); |
---|
2074 | 2100 | if (the_device) { |
---|
2075 | 2101 | put_dev (the_device); |
---|
.. | .. |
---|
2077 | 2103 | } |
---|
2078 | 2104 | kfree(CHIP); |
---|
2079 | 2105 | CHIP = NULL; |
---|
| 2106 | + mutex_unlock(&sb_mutex); |
---|
2080 | 2107 | } |
---|
2081 | 2108 | |
---|
2082 | 2109 | /*----------------------------------------------------------------------*/ |
---|
.. | .. |
---|
2084 | 2111 | static struct file_system_type gadgetfs_type = { |
---|
2085 | 2112 | .owner = THIS_MODULE, |
---|
2086 | 2113 | .name = shortname, |
---|
2087 | | - .mount = gadgetfs_mount, |
---|
| 2114 | + .init_fs_context = gadgetfs_init_fs_context, |
---|
2088 | 2115 | .kill_sb = gadgetfs_kill_sb, |
---|
2089 | 2116 | }; |
---|
2090 | 2117 | MODULE_ALIAS_FS("gadgetfs"); |
---|