diff options
Diffstat (limited to 'drivers/usb/gadget/inode.c')
| -rw-r--r-- | drivers/usb/gadget/inode.c | 67 |
1 files changed, 51 insertions, 16 deletions
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 3bdc5e3ba234..4655522a08d9 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/compiler.h> | 32 | #include <linux/compiler.h> |
| 33 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
| 34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
| 35 | #include <linux/poll.h> | ||
| 35 | 36 | ||
| 36 | #include <linux/device.h> | 37 | #include <linux/device.h> |
| 37 | #include <linux/moduleparam.h> | 38 | #include <linux/moduleparam.h> |
| @@ -222,7 +223,6 @@ static void put_ep (struct ep_data *data) | |||
| 222 | /* needs no more cleanup */ | 223 | /* needs no more cleanup */ |
| 223 | BUG_ON (!list_empty (&data->epfiles)); | 224 | BUG_ON (!list_empty (&data->epfiles)); |
| 224 | BUG_ON (waitqueue_active (&data->wait)); | 225 | BUG_ON (waitqueue_active (&data->wait)); |
| 225 | BUG_ON (down_trylock (&data->lock) != 0); | ||
| 226 | kfree (data); | 226 | kfree (data); |
| 227 | } | 227 | } |
| 228 | 228 | ||
| @@ -477,6 +477,10 @@ static int | |||
| 477 | ep_release (struct inode *inode, struct file *fd) | 477 | ep_release (struct inode *inode, struct file *fd) |
| 478 | { | 478 | { |
| 479 | struct ep_data *data = fd->private_data; | 479 | struct ep_data *data = fd->private_data; |
| 480 | int value; | ||
| 481 | |||
| 482 | if ((value = down_interruptible(&data->lock)) < 0) | ||
| 483 | return value; | ||
| 480 | 484 | ||
| 481 | /* clean up if this can be reopened */ | 485 | /* clean up if this can be reopened */ |
| 482 | if (data->state != STATE_EP_UNBOUND) { | 486 | if (data->state != STATE_EP_UNBOUND) { |
| @@ -485,6 +489,7 @@ ep_release (struct inode *inode, struct file *fd) | |||
| 485 | data->hs_desc.bDescriptorType = 0; | 489 | data->hs_desc.bDescriptorType = 0; |
| 486 | usb_ep_disable(data->ep); | 490 | usb_ep_disable(data->ep); |
| 487 | } | 491 | } |
| 492 | up (&data->lock); | ||
| 488 | put_ep (data); | 493 | put_ep (data); |
| 489 | return 0; | 494 | return 0; |
| 490 | } | 495 | } |
| @@ -709,7 +714,7 @@ ep_aio_write(struct kiocb *iocb, const char __user *ubuf, size_t len, loff_t o) | |||
| 709 | /*----------------------------------------------------------------------*/ | 714 | /*----------------------------------------------------------------------*/ |
| 710 | 715 | ||
| 711 | /* used after endpoint configuration */ | 716 | /* used after endpoint configuration */ |
| 712 | static struct file_operations ep_io_operations = { | 717 | static const struct file_operations ep_io_operations = { |
| 713 | .owner = THIS_MODULE, | 718 | .owner = THIS_MODULE, |
| 714 | .llseek = no_llseek, | 719 | .llseek = no_llseek, |
| 715 | 720 | ||
| @@ -741,7 +746,7 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
| 741 | struct ep_data *data = fd->private_data; | 746 | struct ep_data *data = fd->private_data; |
| 742 | struct usb_ep *ep; | 747 | struct usb_ep *ep; |
| 743 | u32 tag; | 748 | u32 tag; |
| 744 | int value; | 749 | int value, length = len; |
| 745 | 750 | ||
| 746 | if ((value = down_interruptible (&data->lock)) < 0) | 751 | if ((value = down_interruptible (&data->lock)) < 0) |
| 747 | return value; | 752 | return value; |
| @@ -792,7 +797,6 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
| 792 | goto fail0; | 797 | goto fail0; |
| 793 | } | 798 | } |
| 794 | } | 799 | } |
| 795 | value = len; | ||
| 796 | 800 | ||
| 797 | spin_lock_irq (&data->dev->lock); | 801 | spin_lock_irq (&data->dev->lock); |
| 798 | if (data->dev->state == STATE_DEV_UNBOUND) { | 802 | if (data->dev->state == STATE_DEV_UNBOUND) { |
| @@ -822,8 +826,10 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
| 822 | data->name); | 826 | data->name); |
| 823 | data->state = STATE_EP_DEFER_ENABLE; | 827 | data->state = STATE_EP_DEFER_ENABLE; |
| 824 | } | 828 | } |
| 825 | if (value == 0) | 829 | if (value == 0) { |
| 826 | fd->f_op = &ep_io_operations; | 830 | fd->f_op = &ep_io_operations; |
| 831 | value = length; | ||
| 832 | } | ||
| 827 | gone: | 833 | gone: |
| 828 | spin_unlock_irq (&data->dev->lock); | 834 | spin_unlock_irq (&data->dev->lock); |
| 829 | if (value < 0) { | 835 | if (value < 0) { |
| @@ -844,7 +850,7 @@ fail1: | |||
| 844 | static int | 850 | static int |
| 845 | ep_open (struct inode *inode, struct file *fd) | 851 | ep_open (struct inode *inode, struct file *fd) |
| 846 | { | 852 | { |
| 847 | struct ep_data *data = inode->u.generic_ip; | 853 | struct ep_data *data = inode->i_private; |
| 848 | int value = -EBUSY; | 854 | int value = -EBUSY; |
| 849 | 855 | ||
| 850 | if (down_interruptible (&data->lock) != 0) | 856 | if (down_interruptible (&data->lock) != 0) |
| @@ -867,7 +873,7 @@ ep_open (struct inode *inode, struct file *fd) | |||
| 867 | } | 873 | } |
| 868 | 874 | ||
| 869 | /* used before endpoint configuration */ | 875 | /* used before endpoint configuration */ |
| 870 | static struct file_operations ep_config_operations = { | 876 | static const struct file_operations ep_config_operations = { |
| 871 | .owner = THIS_MODULE, | 877 | .owner = THIS_MODULE, |
| 872 | .llseek = no_llseek, | 878 | .llseek = no_llseek, |
| 873 | 879 | ||
| @@ -1009,7 +1015,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
| 1009 | else { | 1015 | else { |
| 1010 | len = min (len, (size_t)dev->req->actual); | 1016 | len = min (len, (size_t)dev->req->actual); |
| 1011 | // FIXME don't call this with the spinlock held ... | 1017 | // FIXME don't call this with the spinlock held ... |
| 1012 | if (copy_to_user (buf, &dev->req->buf, len)) | 1018 | if (copy_to_user (buf, dev->req->buf, len)) |
| 1013 | retval = -EFAULT; | 1019 | retval = -EFAULT; |
| 1014 | clean_req (dev->gadget->ep0, dev->req); | 1020 | clean_req (dev->gadget->ep0, dev->req); |
| 1015 | /* NOTE userspace can't yet choose to stall */ | 1021 | /* NOTE userspace can't yet choose to stall */ |
| @@ -1229,6 +1235,35 @@ dev_release (struct inode *inode, struct file *fd) | |||
| 1229 | return 0; | 1235 | return 0; |
| 1230 | } | 1236 | } |
| 1231 | 1237 | ||
| 1238 | static unsigned int | ||
| 1239 | ep0_poll (struct file *fd, poll_table *wait) | ||
| 1240 | { | ||
| 1241 | struct dev_data *dev = fd->private_data; | ||
| 1242 | int mask = 0; | ||
| 1243 | |||
| 1244 | poll_wait(fd, &dev->wait, wait); | ||
| 1245 | |||
| 1246 | spin_lock_irq (&dev->lock); | ||
| 1247 | |||
| 1248 | /* report fd mode change before acting on it */ | ||
| 1249 | if (dev->setup_abort) { | ||
| 1250 | dev->setup_abort = 0; | ||
| 1251 | mask = POLLHUP; | ||
| 1252 | goto out; | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | if (dev->state == STATE_SETUP) { | ||
| 1256 | if (dev->setup_in || dev->setup_can_stall) | ||
| 1257 | mask = POLLOUT; | ||
| 1258 | } else { | ||
| 1259 | if (dev->ev_next != 0) | ||
| 1260 | mask = POLLIN; | ||
| 1261 | } | ||
| 1262 | out: | ||
| 1263 | spin_unlock_irq(&dev->lock); | ||
| 1264 | return mask; | ||
| 1265 | } | ||
| 1266 | |||
| 1232 | static int dev_ioctl (struct inode *inode, struct file *fd, | 1267 | static int dev_ioctl (struct inode *inode, struct file *fd, |
| 1233 | unsigned code, unsigned long value) | 1268 | unsigned code, unsigned long value) |
| 1234 | { | 1269 | { |
| @@ -1241,14 +1276,14 @@ static int dev_ioctl (struct inode *inode, struct file *fd, | |||
| 1241 | } | 1276 | } |
| 1242 | 1277 | ||
| 1243 | /* used after device configuration */ | 1278 | /* used after device configuration */ |
| 1244 | static struct file_operations ep0_io_operations = { | 1279 | static const struct file_operations ep0_io_operations = { |
| 1245 | .owner = THIS_MODULE, | 1280 | .owner = THIS_MODULE, |
| 1246 | .llseek = no_llseek, | 1281 | .llseek = no_llseek, |
| 1247 | 1282 | ||
| 1248 | .read = ep0_read, | 1283 | .read = ep0_read, |
| 1249 | .write = ep0_write, | 1284 | .write = ep0_write, |
| 1250 | .fasync = ep0_fasync, | 1285 | .fasync = ep0_fasync, |
| 1251 | // .poll = ep0_poll, | 1286 | .poll = ep0_poll, |
| 1252 | .ioctl = dev_ioctl, | 1287 | .ioctl = dev_ioctl, |
| 1253 | .release = dev_release, | 1288 | .release = dev_release, |
| 1254 | }; | 1289 | }; |
| @@ -1696,16 +1731,17 @@ gadgetfs_disconnect (struct usb_gadget *gadget) | |||
| 1696 | { | 1731 | { |
| 1697 | struct dev_data *dev = get_gadget_data (gadget); | 1732 | struct dev_data *dev = get_gadget_data (gadget); |
| 1698 | 1733 | ||
| 1734 | spin_lock (&dev->lock); | ||
| 1699 | if (dev->state == STATE_UNCONNECTED) { | 1735 | if (dev->state == STATE_UNCONNECTED) { |
| 1700 | DBG (dev, "already unconnected\n"); | 1736 | DBG (dev, "already unconnected\n"); |
| 1701 | return; | 1737 | goto exit; |
| 1702 | } | 1738 | } |
| 1703 | dev->state = STATE_UNCONNECTED; | 1739 | dev->state = STATE_UNCONNECTED; |
| 1704 | 1740 | ||
| 1705 | INFO (dev, "disconnected\n"); | 1741 | INFO (dev, "disconnected\n"); |
| 1706 | spin_lock (&dev->lock); | ||
| 1707 | next_event (dev, GADGETFS_DISCONNECT); | 1742 | next_event (dev, GADGETFS_DISCONNECT); |
| 1708 | ep0_readable (dev); | 1743 | ep0_readable (dev); |
| 1744 | exit: | ||
| 1709 | spin_unlock (&dev->lock); | 1745 | spin_unlock (&dev->lock); |
| 1710 | } | 1746 | } |
| 1711 | 1747 | ||
| @@ -1909,7 +1945,7 @@ fail: | |||
| 1909 | static int | 1945 | static int |
| 1910 | dev_open (struct inode *inode, struct file *fd) | 1946 | dev_open (struct inode *inode, struct file *fd) |
| 1911 | { | 1947 | { |
| 1912 | struct dev_data *dev = inode->u.generic_ip; | 1948 | struct dev_data *dev = inode->i_private; |
| 1913 | int value = -EBUSY; | 1949 | int value = -EBUSY; |
| 1914 | 1950 | ||
| 1915 | if (dev->state == STATE_DEV_DISABLED) { | 1951 | if (dev->state == STATE_DEV_DISABLED) { |
| @@ -1922,7 +1958,7 @@ dev_open (struct inode *inode, struct file *fd) | |||
| 1922 | return value; | 1958 | return value; |
| 1923 | } | 1959 | } |
| 1924 | 1960 | ||
| 1925 | static struct file_operations dev_init_operations = { | 1961 | static const struct file_operations dev_init_operations = { |
| 1926 | .owner = THIS_MODULE, | 1962 | .owner = THIS_MODULE, |
| 1927 | .llseek = no_llseek, | 1963 | .llseek = no_llseek, |
| 1928 | 1964 | ||
| @@ -1966,11 +2002,10 @@ gadgetfs_make_inode (struct super_block *sb, | |||
| 1966 | inode->i_mode = mode; | 2002 | inode->i_mode = mode; |
| 1967 | inode->i_uid = default_uid; | 2003 | inode->i_uid = default_uid; |
| 1968 | inode->i_gid = default_gid; | 2004 | inode->i_gid = default_gid; |
| 1969 | inode->i_blksize = PAGE_CACHE_SIZE; | ||
| 1970 | inode->i_blocks = 0; | 2005 | inode->i_blocks = 0; |
| 1971 | inode->i_atime = inode->i_mtime = inode->i_ctime | 2006 | inode->i_atime = inode->i_mtime = inode->i_ctime |
| 1972 | = CURRENT_TIME; | 2007 | = CURRENT_TIME; |
| 1973 | inode->u.generic_ip = data; | 2008 | inode->i_private = data; |
| 1974 | inode->i_fop = fops; | 2009 | inode->i_fop = fops; |
| 1975 | } | 2010 | } |
| 1976 | return inode; | 2011 | return inode; |
