diff options
Diffstat (limited to 'drivers/usb/gadget/inode.c')
-rw-r--r-- | drivers/usb/gadget/inode.c | 75 |
1 files changed, 41 insertions, 34 deletions
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 0f00249720b..cbdcb3c10c5 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -98,16 +98,16 @@ enum ep0_state { | |||
98 | * must always write descriptors to initialize the device, then | 98 | * must always write descriptors to initialize the device, then |
99 | * the device becomes UNCONNECTED until enumeration. | 99 | * the device becomes UNCONNECTED until enumeration. |
100 | */ | 100 | */ |
101 | STATE_OPENED, | 101 | STATE_DEV_OPENED, |
102 | 102 | ||
103 | /* From then on, ep0 fd is in either of two basic modes: | 103 | /* From then on, ep0 fd is in either of two basic modes: |
104 | * - (UN)CONNECTED: read usb_gadgetfs_event(s) from it | 104 | * - (UN)CONNECTED: read usb_gadgetfs_event(s) from it |
105 | * - SETUP: read/write will transfer control data and succeed; | 105 | * - SETUP: read/write will transfer control data and succeed; |
106 | * or if "wrong direction", performs protocol stall | 106 | * or if "wrong direction", performs protocol stall |
107 | */ | 107 | */ |
108 | STATE_UNCONNECTED, | 108 | STATE_DEV_UNCONNECTED, |
109 | STATE_CONNECTED, | 109 | STATE_DEV_CONNECTED, |
110 | STATE_SETUP, | 110 | STATE_DEV_SETUP, |
111 | 111 | ||
112 | /* UNBOUND means the driver closed ep0, so the device won't be | 112 | /* UNBOUND means the driver closed ep0, so the device won't be |
113 | * accessible again (DEV_DISABLED) until all fds are closed. | 113 | * accessible again (DEV_DISABLED) until all fds are closed. |
@@ -121,7 +121,7 @@ enum ep0_state { | |||
121 | struct dev_data { | 121 | struct dev_data { |
122 | spinlock_t lock; | 122 | spinlock_t lock; |
123 | atomic_t count; | 123 | atomic_t count; |
124 | enum ep0_state state; | 124 | enum ep0_state state; /* P: lock */ |
125 | struct usb_gadgetfs_event event [N_EVENT]; | 125 | struct usb_gadgetfs_event event [N_EVENT]; |
126 | unsigned ev_next; | 126 | unsigned ev_next; |
127 | struct fasync_struct *fasync; | 127 | struct fasync_struct *fasync; |
@@ -942,8 +942,14 @@ static void ep0_complete (struct usb_ep *ep, struct usb_request *req) | |||
942 | free = 0; | 942 | free = 0; |
943 | dev->setup_out_ready = 1; | 943 | dev->setup_out_ready = 1; |
944 | ep0_readable (dev); | 944 | ep0_readable (dev); |
945 | } else if (dev->state == STATE_SETUP) | 945 | } else { |
946 | dev->state = STATE_CONNECTED; | 946 | unsigned long flags; |
947 | |||
948 | spin_lock_irqsave(&dev->lock, flags); | ||
949 | if (dev->state == STATE_DEV_SETUP) | ||
950 | dev->state = STATE_DEV_CONNECTED; | ||
951 | spin_unlock_irqrestore(&dev->lock, flags); | ||
952 | } | ||
947 | 953 | ||
948 | /* clean up as appropriate */ | 954 | /* clean up as appropriate */ |
949 | if (free && req->buf != &dev->rbuf) | 955 | if (free && req->buf != &dev->rbuf) |
@@ -988,13 +994,13 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
988 | } | 994 | } |
989 | 995 | ||
990 | /* control DATA stage */ | 996 | /* control DATA stage */ |
991 | if ((state = dev->state) == STATE_SETUP) { | 997 | if ((state = dev->state) == STATE_DEV_SETUP) { |
992 | 998 | ||
993 | if (dev->setup_in) { /* stall IN */ | 999 | if (dev->setup_in) { /* stall IN */ |
994 | VDEBUG(dev, "ep0in stall\n"); | 1000 | VDEBUG(dev, "ep0in stall\n"); |
995 | (void) usb_ep_set_halt (dev->gadget->ep0); | 1001 | (void) usb_ep_set_halt (dev->gadget->ep0); |
996 | retval = -EL2HLT; | 1002 | retval = -EL2HLT; |
997 | dev->state = STATE_CONNECTED; | 1003 | dev->state = STATE_DEV_CONNECTED; |
998 | 1004 | ||
999 | } else if (len == 0) { /* ack SET_CONFIGURATION etc */ | 1005 | } else if (len == 0) { /* ack SET_CONFIGURATION etc */ |
1000 | struct usb_ep *ep = dev->gadget->ep0; | 1006 | struct usb_ep *ep = dev->gadget->ep0; |
@@ -1002,7 +1008,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
1002 | 1008 | ||
1003 | if ((retval = setup_req (ep, req, 0)) == 0) | 1009 | if ((retval = setup_req (ep, req, 0)) == 0) |
1004 | retval = usb_ep_queue (ep, req, GFP_ATOMIC); | 1010 | retval = usb_ep_queue (ep, req, GFP_ATOMIC); |
1005 | dev->state = STATE_CONNECTED; | 1011 | dev->state = STATE_DEV_CONNECTED; |
1006 | 1012 | ||
1007 | /* assume that was SET_CONFIGURATION */ | 1013 | /* assume that was SET_CONFIGURATION */ |
1008 | if (dev->current_config) { | 1014 | if (dev->current_config) { |
@@ -1061,7 +1067,7 @@ scan: | |||
1061 | len = min (len, tmp * sizeof (struct usb_gadgetfs_event)); | 1067 | len = min (len, tmp * sizeof (struct usb_gadgetfs_event)); |
1062 | n = len / sizeof (struct usb_gadgetfs_event); | 1068 | n = len / sizeof (struct usb_gadgetfs_event); |
1063 | 1069 | ||
1064 | /* ep0 can't deliver events when STATE_SETUP */ | 1070 | /* ep0 can't deliver events when STATE_DEV_SETUP */ |
1065 | for (i = 0; i < n; i++) { | 1071 | for (i = 0; i < n; i++) { |
1066 | if (dev->event [i].type == GADGETFS_SETUP) { | 1072 | if (dev->event [i].type == GADGETFS_SETUP) { |
1067 | len = i + 1; | 1073 | len = i + 1; |
@@ -1088,7 +1094,7 @@ scan: | |||
1088 | sizeof (struct usb_gadgetfs_event) | 1094 | sizeof (struct usb_gadgetfs_event) |
1089 | * (tmp - len)); | 1095 | * (tmp - len)); |
1090 | if (n == 0) | 1096 | if (n == 0) |
1091 | dev->state = STATE_SETUP; | 1097 | dev->state = STATE_DEV_SETUP; |
1092 | spin_unlock_irq (&dev->lock); | 1098 | spin_unlock_irq (&dev->lock); |
1093 | } | 1099 | } |
1094 | return retval; | 1100 | return retval; |
@@ -1103,8 +1109,8 @@ scan: | |||
1103 | DBG (dev, "fail %s, state %d\n", __FUNCTION__, state); | 1109 | DBG (dev, "fail %s, state %d\n", __FUNCTION__, state); |
1104 | retval = -ESRCH; | 1110 | retval = -ESRCH; |
1105 | break; | 1111 | break; |
1106 | case STATE_UNCONNECTED: | 1112 | case STATE_DEV_UNCONNECTED: |
1107 | case STATE_CONNECTED: | 1113 | case STATE_DEV_CONNECTED: |
1108 | spin_unlock_irq (&dev->lock); | 1114 | spin_unlock_irq (&dev->lock); |
1109 | DBG (dev, "%s wait\n", __FUNCTION__); | 1115 | DBG (dev, "%s wait\n", __FUNCTION__); |
1110 | 1116 | ||
@@ -1131,7 +1137,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) | |||
1131 | switch (type) { | 1137 | switch (type) { |
1132 | /* these events purge the queue */ | 1138 | /* these events purge the queue */ |
1133 | case GADGETFS_DISCONNECT: | 1139 | case GADGETFS_DISCONNECT: |
1134 | if (dev->state == STATE_SETUP) | 1140 | if (dev->state == STATE_DEV_SETUP) |
1135 | dev->setup_abort = 1; | 1141 | dev->setup_abort = 1; |
1136 | // FALL THROUGH | 1142 | // FALL THROUGH |
1137 | case GADGETFS_CONNECT: | 1143 | case GADGETFS_CONNECT: |
@@ -1178,7 +1184,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1178 | retval = -EIDRM; | 1184 | retval = -EIDRM; |
1179 | 1185 | ||
1180 | /* data and/or status stage for control request */ | 1186 | /* data and/or status stage for control request */ |
1181 | } else if (dev->state == STATE_SETUP) { | 1187 | } else if (dev->state == STATE_DEV_SETUP) { |
1182 | 1188 | ||
1183 | /* IN DATA+STATUS caller makes len <= wLength */ | 1189 | /* IN DATA+STATUS caller makes len <= wLength */ |
1184 | if (dev->setup_in) { | 1190 | if (dev->setup_in) { |
@@ -1209,7 +1215,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1209 | VDEBUG(dev, "ep0out stall\n"); | 1215 | VDEBUG(dev, "ep0out stall\n"); |
1210 | (void) usb_ep_set_halt (dev->gadget->ep0); | 1216 | (void) usb_ep_set_halt (dev->gadget->ep0); |
1211 | retval = -EL2HLT; | 1217 | retval = -EL2HLT; |
1212 | dev->state = STATE_CONNECTED; | 1218 | dev->state = STATE_DEV_CONNECTED; |
1213 | } else { | 1219 | } else { |
1214 | DBG(dev, "bogus ep0out stall!\n"); | 1220 | DBG(dev, "bogus ep0out stall!\n"); |
1215 | } | 1221 | } |
@@ -1251,7 +1257,9 @@ dev_release (struct inode *inode, struct file *fd) | |||
1251 | put_dev (dev); | 1257 | put_dev (dev); |
1252 | 1258 | ||
1253 | /* other endpoints were all decoupled from this device */ | 1259 | /* other endpoints were all decoupled from this device */ |
1260 | spin_lock_irq(&dev->lock); | ||
1254 | dev->state = STATE_DEV_DISABLED; | 1261 | dev->state = STATE_DEV_DISABLED; |
1262 | spin_unlock_irq(&dev->lock); | ||
1255 | return 0; | 1263 | return 0; |
1256 | } | 1264 | } |
1257 | 1265 | ||
@@ -1272,7 +1280,7 @@ ep0_poll (struct file *fd, poll_table *wait) | |||
1272 | goto out; | 1280 | goto out; |
1273 | } | 1281 | } |
1274 | 1282 | ||
1275 | if (dev->state == STATE_SETUP) { | 1283 | if (dev->state == STATE_DEV_SETUP) { |
1276 | if (dev->setup_in || dev->setup_can_stall) | 1284 | if (dev->setup_in || dev->setup_can_stall) |
1277 | mask = POLLOUT; | 1285 | mask = POLLOUT; |
1278 | } else { | 1286 | } else { |
@@ -1382,9 +1390,9 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1382 | 1390 | ||
1383 | spin_lock (&dev->lock); | 1391 | spin_lock (&dev->lock); |
1384 | dev->setup_abort = 0; | 1392 | dev->setup_abort = 0; |
1385 | if (dev->state == STATE_UNCONNECTED) { | 1393 | if (dev->state == STATE_DEV_UNCONNECTED) { |
1386 | 1394 | ||
1387 | dev->state = STATE_CONNECTED; | 1395 | dev->state = STATE_DEV_CONNECTED; |
1388 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; | 1396 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; |
1389 | 1397 | ||
1390 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1398 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
@@ -1404,7 +1412,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1404 | * then ep0_{read,write} will report the wrong status. controller | 1412 | * then ep0_{read,write} will report the wrong status. controller |
1405 | * driver will have aborted pending i/o. | 1413 | * driver will have aborted pending i/o. |
1406 | */ | 1414 | */ |
1407 | } else if (dev->state == STATE_SETUP) | 1415 | } else if (dev->state == STATE_DEV_SETUP) |
1408 | dev->setup_abort = 1; | 1416 | dev->setup_abort = 1; |
1409 | 1417 | ||
1410 | req->buf = dev->rbuf; | 1418 | req->buf = dev->rbuf; |
@@ -1550,7 +1558,7 @@ delegate: | |||
1550 | } | 1558 | } |
1551 | 1559 | ||
1552 | /* proceed with data transfer and status phases? */ | 1560 | /* proceed with data transfer and status phases? */ |
1553 | if (value >= 0 && dev->state != STATE_SETUP) { | 1561 | if (value >= 0 && dev->state != STATE_DEV_SETUP) { |
1554 | req->length = value; | 1562 | req->length = value; |
1555 | req->zero = value < w_length; | 1563 | req->zero = value < w_length; |
1556 | value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); | 1564 | value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); |
@@ -1714,7 +1722,9 @@ gadgetfs_bind (struct usb_gadget *gadget) | |||
1714 | goto enomem; | 1722 | goto enomem; |
1715 | 1723 | ||
1716 | INFO (dev, "bound to %s driver\n", gadget->name); | 1724 | INFO (dev, "bound to %s driver\n", gadget->name); |
1717 | dev->state = STATE_UNCONNECTED; | 1725 | spin_lock_irq(&dev->lock); |
1726 | dev->state = STATE_DEV_UNCONNECTED; | ||
1727 | spin_unlock_irq(&dev->lock); | ||
1718 | get_dev (dev); | 1728 | get_dev (dev); |
1719 | return 0; | 1729 | return 0; |
1720 | 1730 | ||
@@ -1729,11 +1739,9 @@ gadgetfs_disconnect (struct usb_gadget *gadget) | |||
1729 | struct dev_data *dev = get_gadget_data (gadget); | 1739 | struct dev_data *dev = get_gadget_data (gadget); |
1730 | 1740 | ||
1731 | spin_lock (&dev->lock); | 1741 | spin_lock (&dev->lock); |
1732 | if (dev->state == STATE_UNCONNECTED) { | 1742 | if (dev->state == STATE_DEV_UNCONNECTED) |
1733 | DBG (dev, "already unconnected\n"); | ||
1734 | goto exit; | 1743 | goto exit; |
1735 | } | 1744 | dev->state = STATE_DEV_UNCONNECTED; |
1736 | dev->state = STATE_UNCONNECTED; | ||
1737 | 1745 | ||
1738 | INFO (dev, "disconnected\n"); | 1746 | INFO (dev, "disconnected\n"); |
1739 | next_event (dev, GADGETFS_DISCONNECT); | 1747 | next_event (dev, GADGETFS_DISCONNECT); |
@@ -1750,9 +1758,9 @@ gadgetfs_suspend (struct usb_gadget *gadget) | |||
1750 | INFO (dev, "suspended from state %d\n", dev->state); | 1758 | INFO (dev, "suspended from state %d\n", dev->state); |
1751 | spin_lock (&dev->lock); | 1759 | spin_lock (&dev->lock); |
1752 | switch (dev->state) { | 1760 | switch (dev->state) { |
1753 | case STATE_SETUP: // VERY odd... host died?? | 1761 | case STATE_DEV_SETUP: // VERY odd... host died?? |
1754 | case STATE_CONNECTED: | 1762 | case STATE_DEV_CONNECTED: |
1755 | case STATE_UNCONNECTED: | 1763 | case STATE_DEV_UNCONNECTED: |
1756 | next_event (dev, GADGETFS_SUSPEND); | 1764 | next_event (dev, GADGETFS_SUSPEND); |
1757 | ep0_readable (dev); | 1765 | ep0_readable (dev); |
1758 | /* FALLTHROUGH */ | 1766 | /* FALLTHROUGH */ |
@@ -1848,9 +1856,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1848 | u32 tag; | 1856 | u32 tag; |
1849 | char *kbuf; | 1857 | char *kbuf; |
1850 | 1858 | ||
1851 | if (dev->state != STATE_OPENED) | ||
1852 | return -EEXIST; | ||
1853 | |||
1854 | if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) | 1859 | if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) |
1855 | return -EINVAL; | 1860 | return -EINVAL; |
1856 | 1861 | ||
@@ -1942,13 +1947,15 @@ dev_open (struct inode *inode, struct file *fd) | |||
1942 | struct dev_data *dev = inode->i_private; | 1947 | struct dev_data *dev = inode->i_private; |
1943 | int value = -EBUSY; | 1948 | int value = -EBUSY; |
1944 | 1949 | ||
1950 | spin_lock_irq(&dev->lock); | ||
1945 | if (dev->state == STATE_DEV_DISABLED) { | 1951 | if (dev->state == STATE_DEV_DISABLED) { |
1946 | dev->ev_next = 0; | 1952 | dev->ev_next = 0; |
1947 | dev->state = STATE_OPENED; | 1953 | dev->state = STATE_DEV_OPENED; |
1948 | fd->private_data = dev; | 1954 | fd->private_data = dev; |
1949 | get_dev (dev); | 1955 | get_dev (dev); |
1950 | value = 0; | 1956 | value = 0; |
1951 | } | 1957 | } |
1958 | spin_unlock_irq(&dev->lock); | ||
1952 | return value; | 1959 | return value; |
1953 | } | 1960 | } |
1954 | 1961 | ||