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; |