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

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
Loading
Loading
Loading
Loading
+41 −34
Original line number Diff line number Diff line
@@ -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 @@ scan:
		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 @@ scan:
					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 @@ scan:
		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 @@ delegate:
	}

	/* 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;
}