forked from luck/tmp_suning_uos_patched
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: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
3ff4fd94c8
commit
7489d14943
@ -98,16 +98,16 @@ enum ep0_state {
|
||||
* must always write descriptors to initialize the device, then
|
||||
* the device becomes UNCONNECTED until enumeration.
|
||||
*/
|
||||
STATE_OPENED,
|
||||
STATE_DEV_OPENED,
|
||||
|
||||
/* From then on, ep0 fd is in either of two basic modes:
|
||||
* - (UN)CONNECTED: read usb_gadgetfs_event(s) from it
|
||||
* - SETUP: read/write will transfer control data and succeed;
|
||||
* or if "wrong direction", performs protocol stall
|
||||
*/
|
||||
STATE_UNCONNECTED,
|
||||
STATE_CONNECTED,
|
||||
STATE_SETUP,
|
||||
STATE_DEV_UNCONNECTED,
|
||||
STATE_DEV_CONNECTED,
|
||||
STATE_DEV_SETUP,
|
||||
|
||||
/* UNBOUND means the driver closed ep0, so the device won't be
|
||||
* accessible again (DEV_DISABLED) until all fds are closed.
|
||||
@ -121,7 +121,7 @@ enum ep0_state {
|
||||
struct dev_data {
|
||||
spinlock_t lock;
|
||||
atomic_t count;
|
||||
enum ep0_state state;
|
||||
enum ep0_state state; /* P: lock */
|
||||
struct usb_gadgetfs_event event [N_EVENT];
|
||||
unsigned ev_next;
|
||||
struct fasync_struct *fasync;
|
||||
@ -942,8 +942,14 @@ static void ep0_complete (struct usb_ep *ep, struct usb_request *req)
|
||||
free = 0;
|
||||
dev->setup_out_ready = 1;
|
||||
ep0_readable (dev);
|
||||
} else if (dev->state == STATE_SETUP)
|
||||
dev->state = STATE_CONNECTED;
|
||||
} else {
|
||||
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 */
|
||||
if (free && req->buf != &dev->rbuf)
|
||||
@ -988,13 +994,13 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
||||
}
|
||||
|
||||
/* control DATA stage */
|
||||
if ((state = dev->state) == STATE_SETUP) {
|
||||
if ((state = dev->state) == STATE_DEV_SETUP) {
|
||||
|
||||
if (dev->setup_in) { /* stall IN */
|
||||
VDEBUG(dev, "ep0in stall\n");
|
||||
(void) usb_ep_set_halt (dev->gadget->ep0);
|
||||
retval = -EL2HLT;
|
||||
dev->state = STATE_CONNECTED;
|
||||
dev->state = STATE_DEV_CONNECTED;
|
||||
|
||||
} else if (len == 0) { /* ack SET_CONFIGURATION etc */
|
||||
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)
|
||||
|
||||
if ((retval = setup_req (ep, req, 0)) == 0)
|
||||
retval = usb_ep_queue (ep, req, GFP_ATOMIC);
|
||||
dev->state = STATE_CONNECTED;
|
||||
dev->state = STATE_DEV_CONNECTED;
|
||||
|
||||
/* assume that was SET_CONFIGURATION */
|
||||
if (dev->current_config) {
|
||||
@ -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));
|
||||
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++) {
|
||||
if (dev->event [i].type == GADGETFS_SETUP) {
|
||||
len = i + 1;
|
||||
@ -1088,7 +1094,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
||||
sizeof (struct usb_gadgetfs_event)
|
||||
* (tmp - len));
|
||||
if (n == 0)
|
||||
dev->state = STATE_SETUP;
|
||||
dev->state = STATE_DEV_SETUP;
|
||||
spin_unlock_irq (&dev->lock);
|
||||
}
|
||||
return retval;
|
||||
@ -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);
|
||||
retval = -ESRCH;
|
||||
break;
|
||||
case STATE_UNCONNECTED:
|
||||
case STATE_CONNECTED:
|
||||
case STATE_DEV_UNCONNECTED:
|
||||
case STATE_DEV_CONNECTED:
|
||||
spin_unlock_irq (&dev->lock);
|
||||
DBG (dev, "%s wait\n", __FUNCTION__);
|
||||
|
||||
@ -1131,7 +1137,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type)
|
||||
switch (type) {
|
||||
/* these events purge the queue */
|
||||
case GADGETFS_DISCONNECT:
|
||||
if (dev->state == STATE_SETUP)
|
||||
if (dev->state == STATE_DEV_SETUP)
|
||||
dev->setup_abort = 1;
|
||||
// FALL THROUGH
|
||||
case GADGETFS_CONNECT:
|
||||
@ -1178,7 +1184,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||
retval = -EIDRM;
|
||||
|
||||
/* 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 */
|
||||
if (dev->setup_in) {
|
||||
@ -1209,7 +1215,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||
VDEBUG(dev, "ep0out stall\n");
|
||||
(void) usb_ep_set_halt (dev->gadget->ep0);
|
||||
retval = -EL2HLT;
|
||||
dev->state = STATE_CONNECTED;
|
||||
dev->state = STATE_DEV_CONNECTED;
|
||||
} else {
|
||||
DBG(dev, "bogus ep0out stall!\n");
|
||||
}
|
||||
@ -1251,7 +1257,9 @@ dev_release (struct inode *inode, struct file *fd)
|
||||
put_dev (dev);
|
||||
|
||||
/* other endpoints were all decoupled from this device */
|
||||
spin_lock_irq(&dev->lock);
|
||||
dev->state = STATE_DEV_DISABLED;
|
||||
spin_unlock_irq(&dev->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1272,7 +1280,7 @@ ep0_poll (struct file *fd, poll_table *wait)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dev->state == STATE_SETUP) {
|
||||
if (dev->state == STATE_DEV_SETUP) {
|
||||
if (dev->setup_in || dev->setup_can_stall)
|
||||
mask = POLLOUT;
|
||||
} else {
|
||||
@ -1382,9 +1390,9 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||
|
||||
spin_lock (&dev->lock);
|
||||
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;
|
||||
|
||||
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
||||
@ -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
|
||||
* driver will have aborted pending i/o.
|
||||
*/
|
||||
} else if (dev->state == STATE_SETUP)
|
||||
} else if (dev->state == STATE_DEV_SETUP)
|
||||
dev->setup_abort = 1;
|
||||
|
||||
req->buf = dev->rbuf;
|
||||
@ -1550,7 +1558,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||
}
|
||||
|
||||
/* 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->zero = value < w_length;
|
||||
value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
|
||||
@ -1714,7 +1722,9 @@ gadgetfs_bind (struct usb_gadget *gadget)
|
||||
goto enomem;
|
||||
|
||||
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);
|
||||
return 0;
|
||||
|
||||
@ -1729,11 +1739,9 @@ gadgetfs_disconnect (struct usb_gadget *gadget)
|
||||
struct dev_data *dev = get_gadget_data (gadget);
|
||||
|
||||
spin_lock (&dev->lock);
|
||||
if (dev->state == STATE_UNCONNECTED) {
|
||||
DBG (dev, "already unconnected\n");
|
||||
if (dev->state == STATE_DEV_UNCONNECTED)
|
||||
goto exit;
|
||||
}
|
||||
dev->state = STATE_UNCONNECTED;
|
||||
dev->state = STATE_DEV_UNCONNECTED;
|
||||
|
||||
INFO (dev, "disconnected\n");
|
||||
next_event (dev, GADGETFS_DISCONNECT);
|
||||
@ -1750,9 +1758,9 @@ gadgetfs_suspend (struct usb_gadget *gadget)
|
||||
INFO (dev, "suspended from state %d\n", dev->state);
|
||||
spin_lock (&dev->lock);
|
||||
switch (dev->state) {
|
||||
case STATE_SETUP: // VERY odd... host died??
|
||||
case STATE_CONNECTED:
|
||||
case STATE_UNCONNECTED:
|
||||
case STATE_DEV_SETUP: // VERY odd... host died??
|
||||
case STATE_DEV_CONNECTED:
|
||||
case STATE_DEV_UNCONNECTED:
|
||||
next_event (dev, GADGETFS_SUSPEND);
|
||||
ep0_readable (dev);
|
||||
/* FALLTHROUGH */
|
||||
@ -1848,9 +1856,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||
u32 tag;
|
||||
char *kbuf;
|
||||
|
||||
if (dev->state != STATE_OPENED)
|
||||
return -EEXIST;
|
||||
|
||||
if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4))
|
||||
return -EINVAL;
|
||||
|
||||
@ -1942,13 +1947,15 @@ dev_open (struct inode *inode, struct file *fd)
|
||||
struct dev_data *dev = inode->i_private;
|
||||
int value = -EBUSY;
|
||||
|
||||
spin_lock_irq(&dev->lock);
|
||||
if (dev->state == STATE_DEV_DISABLED) {
|
||||
dev->ev_next = 0;
|
||||
dev->state = STATE_OPENED;
|
||||
dev->state = STATE_DEV_OPENED;
|
||||
fd->private_data = dev;
|
||||
get_dev (dev);
|
||||
value = 0;
|
||||
}
|
||||
spin_unlock_irq(&dev->lock);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user