Commit 7489d149 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

USB: gadgetfs cleanups

Minor gadgetfs cleanups:

 - EP0 state constants become consistently STATE_DEV_* rather than
   sometimes omitting the "DEV_"; STATE_EP_* were already consistent.

 - Comment that ep0 state is protected by the spinlock, and update
   code that was neglecting that rule.

None of this is expected to change behavior.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 3ff4fd94
...@@ -98,16 +98,16 @@ enum ep0_state { ...@@ -98,16 +98,16 @@ enum ep0_state {
* must always write descriptors to initialize the device, then * must always write descriptors to initialize the device, then
* the device becomes UNCONNECTED until enumeration. * the device becomes UNCONNECTED until enumeration.
*/ */
STATE_OPENED, STATE_DEV_OPENED,
/* From then on, ep0 fd is in either of two basic modes: /* From then on, ep0 fd is in either of two basic modes:
* - (UN)CONNECTED: read usb_gadgetfs_event(s) from it * - (UN)CONNECTED: read usb_gadgetfs_event(s) from it
* - SETUP: read/write will transfer control data and succeed; * - SETUP: read/write will transfer control data and succeed;
* or if "wrong direction", performs protocol stall * or if "wrong direction", performs protocol stall
*/ */
STATE_UNCONNECTED, STATE_DEV_UNCONNECTED,
STATE_CONNECTED, STATE_DEV_CONNECTED,
STATE_SETUP, STATE_DEV_SETUP,
/* UNBOUND means the driver closed ep0, so the device won't be /* UNBOUND means the driver closed ep0, so the device won't be
* accessible again (DEV_DISABLED) until all fds are closed. * accessible again (DEV_DISABLED) until all fds are closed.
...@@ -121,7 +121,7 @@ enum ep0_state { ...@@ -121,7 +121,7 @@ enum ep0_state {
struct dev_data { struct dev_data {
spinlock_t lock; spinlock_t lock;
atomic_t count; atomic_t count;
enum ep0_state state; enum ep0_state state; /* P: lock */
struct usb_gadgetfs_event event [N_EVENT]; struct usb_gadgetfs_event event [N_EVENT];
unsigned ev_next; unsigned ev_next;
struct fasync_struct *fasync; struct fasync_struct *fasync;
...@@ -942,8 +942,14 @@ static void ep0_complete (struct usb_ep *ep, struct usb_request *req) ...@@ -942,8 +942,14 @@ static void ep0_complete (struct usb_ep *ep, struct usb_request *req)
free = 0; free = 0;
dev->setup_out_ready = 1; dev->setup_out_ready = 1;
ep0_readable (dev); ep0_readable (dev);
} else if (dev->state == STATE_SETUP) } else {
dev->state = STATE_CONNECTED; unsigned long flags;
spin_lock_irqsave(&dev->lock, flags);
if (dev->state == STATE_DEV_SETUP)
dev->state = STATE_DEV_CONNECTED;
spin_unlock_irqrestore(&dev->lock, flags);
}
/* clean up as appropriate */ /* clean up as appropriate */
if (free && req->buf != &dev->rbuf) 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,13 +994,13 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
} }
/* control DATA stage */ /* control DATA stage */
if ((state = dev->state) == STATE_SETUP) { if ((state = dev->state) == STATE_DEV_SETUP) {
if (dev->setup_in) { /* stall IN */ if (dev->setup_in) { /* stall IN */
VDEBUG(dev, "ep0in stall\n"); VDEBUG(dev, "ep0in stall\n");
(void) usb_ep_set_halt (dev->gadget->ep0); (void) usb_ep_set_halt (dev->gadget->ep0);
retval = -EL2HLT; retval = -EL2HLT;
dev->state = STATE_CONNECTED; dev->state = STATE_DEV_CONNECTED;
} else if (len == 0) { /* ack SET_CONFIGURATION etc */ } else if (len == 0) { /* ack SET_CONFIGURATION etc */
struct usb_ep *ep = dev->gadget->ep0; 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,7 +1008,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
if ((retval = setup_req (ep, req, 0)) == 0) if ((retval = setup_req (ep, req, 0)) == 0)
retval = usb_ep_queue (ep, req, GFP_ATOMIC); retval = usb_ep_queue (ep, req, GFP_ATOMIC);
dev->state = STATE_CONNECTED; dev->state = STATE_DEV_CONNECTED;
/* assume that was SET_CONFIGURATION */ /* assume that was SET_CONFIGURATION */
if (dev->current_config) { if (dev->current_config) {
...@@ -1061,7 +1067,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) ...@@ -1061,7 +1067,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
len = min (len, tmp * sizeof (struct usb_gadgetfs_event)); len = min (len, tmp * sizeof (struct usb_gadgetfs_event));
n = len / sizeof (struct usb_gadgetfs_event); n = len / sizeof (struct usb_gadgetfs_event);
/* ep0 can't deliver events when STATE_SETUP */ /* ep0 can't deliver events when STATE_DEV_SETUP */
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (dev->event [i].type == GADGETFS_SETUP) { if (dev->event [i].type == GADGETFS_SETUP) {
len = i + 1; len = i + 1;
...@@ -1088,7 +1094,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) ...@@ -1088,7 +1094,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
sizeof (struct usb_gadgetfs_event) sizeof (struct usb_gadgetfs_event)
* (tmp - len)); * (tmp - len));
if (n == 0) if (n == 0)
dev->state = STATE_SETUP; dev->state = STATE_DEV_SETUP;
spin_unlock_irq (&dev->lock); spin_unlock_irq (&dev->lock);
} }
return retval; return retval;
...@@ -1103,8 +1109,8 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) ...@@ -1103,8 +1109,8 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
DBG (dev, "fail %s, state %d\n", __FUNCTION__, state); DBG (dev, "fail %s, state %d\n", __FUNCTION__, state);
retval = -ESRCH; retval = -ESRCH;
break; break;
case STATE_UNCONNECTED: case STATE_DEV_UNCONNECTED:
case STATE_CONNECTED: case STATE_DEV_CONNECTED:
spin_unlock_irq (&dev->lock); spin_unlock_irq (&dev->lock);
DBG (dev, "%s wait\n", __FUNCTION__); DBG (dev, "%s wait\n", __FUNCTION__);
...@@ -1131,7 +1137,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) ...@@ -1131,7 +1137,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type)
switch (type) { switch (type) {
/* these events purge the queue */ /* these events purge the queue */
case GADGETFS_DISCONNECT: case GADGETFS_DISCONNECT:
if (dev->state == STATE_SETUP) if (dev->state == STATE_DEV_SETUP)
dev->setup_abort = 1; dev->setup_abort = 1;
// FALL THROUGH // FALL THROUGH
case GADGETFS_CONNECT: case GADGETFS_CONNECT:
...@@ -1178,7 +1184,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) ...@@ -1178,7 +1184,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
retval = -EIDRM; retval = -EIDRM;
/* data and/or status stage for control request */ /* data and/or status stage for control request */
} else if (dev->state == STATE_SETUP) { } else if (dev->state == STATE_DEV_SETUP) {
/* IN DATA+STATUS caller makes len <= wLength */ /* IN DATA+STATUS caller makes len <= wLength */
if (dev->setup_in) { if (dev->setup_in) {
...@@ -1209,7 +1215,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) ...@@ -1209,7 +1215,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
VDEBUG(dev, "ep0out stall\n"); VDEBUG(dev, "ep0out stall\n");
(void) usb_ep_set_halt (dev->gadget->ep0); (void) usb_ep_set_halt (dev->gadget->ep0);
retval = -EL2HLT; retval = -EL2HLT;
dev->state = STATE_CONNECTED; dev->state = STATE_DEV_CONNECTED;
} else { } else {
DBG(dev, "bogus ep0out stall!\n"); DBG(dev, "bogus ep0out stall!\n");
} }
...@@ -1251,7 +1257,9 @@ dev_release (struct inode *inode, struct file *fd) ...@@ -1251,7 +1257,9 @@ dev_release (struct inode *inode, struct file *fd)
put_dev (dev); put_dev (dev);
/* other endpoints were all decoupled from this device */ /* other endpoints were all decoupled from this device */
spin_lock_irq(&dev->lock);
dev->state = STATE_DEV_DISABLED; dev->state = STATE_DEV_DISABLED;
spin_unlock_irq(&dev->lock);
return 0; return 0;
} }
...@@ -1272,7 +1280,7 @@ ep0_poll (struct file *fd, poll_table *wait) ...@@ -1272,7 +1280,7 @@ ep0_poll (struct file *fd, poll_table *wait)
goto out; goto out;
} }
if (dev->state == STATE_SETUP) { if (dev->state == STATE_DEV_SETUP) {
if (dev->setup_in || dev->setup_can_stall) if (dev->setup_in || dev->setup_can_stall)
mask = POLLOUT; mask = POLLOUT;
} else { } else {
...@@ -1382,9 +1390,9 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1382,9 +1390,9 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
spin_lock (&dev->lock); spin_lock (&dev->lock);
dev->setup_abort = 0; dev->setup_abort = 0;
if (dev->state == STATE_UNCONNECTED) { if (dev->state == STATE_DEV_UNCONNECTED) {
dev->state = STATE_CONNECTED; dev->state = STATE_DEV_CONNECTED;
dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket;
#ifdef CONFIG_USB_GADGET_DUALSPEED #ifdef CONFIG_USB_GADGET_DUALSPEED
...@@ -1404,7 +1412,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1404,7 +1412,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
* then ep0_{read,write} will report the wrong status. controller * then ep0_{read,write} will report the wrong status. controller
* driver will have aborted pending i/o. * driver will have aborted pending i/o.
*/ */
} else if (dev->state == STATE_SETUP) } else if (dev->state == STATE_DEV_SETUP)
dev->setup_abort = 1; dev->setup_abort = 1;
req->buf = dev->rbuf; req->buf = dev->rbuf;
...@@ -1550,7 +1558,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1550,7 +1558,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
} }
/* proceed with data transfer and status phases? */ /* proceed with data transfer and status phases? */
if (value >= 0 && dev->state != STATE_SETUP) { if (value >= 0 && dev->state != STATE_DEV_SETUP) {
req->length = value; req->length = value;
req->zero = value < w_length; req->zero = value < w_length;
value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
...@@ -1714,7 +1722,9 @@ gadgetfs_bind (struct usb_gadget *gadget) ...@@ -1714,7 +1722,9 @@ gadgetfs_bind (struct usb_gadget *gadget)
goto enomem; goto enomem;
INFO (dev, "bound to %s driver\n", gadget->name); INFO (dev, "bound to %s driver\n", gadget->name);
dev->state = STATE_UNCONNECTED; spin_lock_irq(&dev->lock);
dev->state = STATE_DEV_UNCONNECTED;
spin_unlock_irq(&dev->lock);
get_dev (dev); get_dev (dev);
return 0; return 0;
...@@ -1729,11 +1739,9 @@ gadgetfs_disconnect (struct usb_gadget *gadget) ...@@ -1729,11 +1739,9 @@ gadgetfs_disconnect (struct usb_gadget *gadget)
struct dev_data *dev = get_gadget_data (gadget); struct dev_data *dev = get_gadget_data (gadget);
spin_lock (&dev->lock); spin_lock (&dev->lock);
if (dev->state == STATE_UNCONNECTED) { if (dev->state == STATE_DEV_UNCONNECTED)
DBG (dev, "already unconnected\n");
goto exit; goto exit;
} dev->state = STATE_DEV_UNCONNECTED;
dev->state = STATE_UNCONNECTED;
INFO (dev, "disconnected\n"); INFO (dev, "disconnected\n");
next_event (dev, GADGETFS_DISCONNECT); next_event (dev, GADGETFS_DISCONNECT);
...@@ -1750,9 +1758,9 @@ gadgetfs_suspend (struct usb_gadget *gadget) ...@@ -1750,9 +1758,9 @@ gadgetfs_suspend (struct usb_gadget *gadget)
INFO (dev, "suspended from state %d\n", dev->state); INFO (dev, "suspended from state %d\n", dev->state);
spin_lock (&dev->lock); spin_lock (&dev->lock);
switch (dev->state) { switch (dev->state) {
case STATE_SETUP: // VERY odd... host died?? case STATE_DEV_SETUP: // VERY odd... host died??
case STATE_CONNECTED: case STATE_DEV_CONNECTED:
case STATE_UNCONNECTED: case STATE_DEV_UNCONNECTED:
next_event (dev, GADGETFS_SUSPEND); next_event (dev, GADGETFS_SUSPEND);
ep0_readable (dev); ep0_readable (dev);
/* FALLTHROUGH */ /* FALLTHROUGH */
...@@ -1848,9 +1856,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) ...@@ -1848,9 +1856,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
u32 tag; u32 tag;
char *kbuf; char *kbuf;
if (dev->state != STATE_OPENED)
return -EEXIST;
if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4))
return -EINVAL; return -EINVAL;
...@@ -1942,13 +1947,15 @@ dev_open (struct inode *inode, struct file *fd) ...@@ -1942,13 +1947,15 @@ dev_open (struct inode *inode, struct file *fd)
struct dev_data *dev = inode->i_private; struct dev_data *dev = inode->i_private;
int value = -EBUSY; int value = -EBUSY;
spin_lock_irq(&dev->lock);
if (dev->state == STATE_DEV_DISABLED) { if (dev->state == STATE_DEV_DISABLED) {
dev->ev_next = 0; dev->ev_next = 0;
dev->state = STATE_OPENED; dev->state = STATE_DEV_OPENED;
fd->private_data = dev; fd->private_data = dev;
get_dev (dev); get_dev (dev);
value = 0; value = 0;
} }
spin_unlock_irq(&dev->lock);
return value; return value;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment