Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 222155de authored by Jerry Zhang's avatar Jerry Zhang Committed by Felipe Balbi
Browse files

usb: gadget: function: f_fs: Let ffs_epfile_ioctl wait for enable.



This allows users to make an ioctl call as the first action on a
connection. Ex, some functions might want to get endpoint size
before making any i/os.

Previously, calling ioctls before read/write would depending on the
timing of endpoints being enabled.

ESHUTDOWN is now a possible return value and ENODEV is not, so change
docs accordingly.

Acked-by: default avatarMichal Nazarewicz <mina86@mina86.com>
Signed-off-by: default avatarJerry Zhang <zhangjerry@google.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 8a8b161d
Loading
Loading
Loading
Loading
+54 −39
Original line number Diff line number Diff line
@@ -1189,6 +1189,7 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
			     unsigned long value)
{
	struct ffs_epfile *epfile = file->private_data;
	struct ffs_ep *ep;
	int ret;

	ENTER();
@@ -1196,8 +1197,25 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
	if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
		return -ENODEV;

	/* Wait for endpoint to be enabled */
	ep = epfile->ep;
	if (!ep) {
		if (file->f_flags & O_NONBLOCK)
			return -EAGAIN;

		ret = wait_event_interruptible(epfile->wait, (ep = epfile->ep));
		if (ret)
			return -EINTR;
	}

	spin_lock_irq(&epfile->ffs->eps_lock);
	if (likely(epfile->ep)) {

	/* In the meantime, endpoint got disabled or changed. */
	if (epfile->ep != ep) {
		spin_unlock_irq(&epfile->ffs->eps_lock);
		return -ESHUTDOWN;
	}

	switch (code) {
	case FUNCTIONFS_FIFO_STATUS:
		ret = usb_ep_fifo_status(epfile->ep->ep);
@@ -1238,9 +1256,6 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
	default:
		ret = -ENOTTY;
	}
	} else {
		ret = -ENODEV;
	}
	spin_unlock_irq(&epfile->ffs->eps_lock);

	return ret;
+4 −3
Original line number Diff line number Diff line
@@ -275,13 +275,14 @@ struct usb_functionfs_event {
#define	FUNCTIONFS_INTERFACE_REVMAP	_IO('g', 128)

/*
 * Returns real bEndpointAddress of an endpoint.  If function is not
 * active returns -ENODEV.
 * Returns real bEndpointAddress of an endpoint. If endpoint shuts down
 * during the call, returns -ESHUTDOWN.
 */
#define	FUNCTIONFS_ENDPOINT_REVMAP	_IO('g', 129)

/*
 * Returns endpoint descriptor. If function is not active returns -ENODEV.
 * Returns endpoint descriptor. If endpoint shuts down during the call,
 * returns -ESHUTDOWN.
 */
#define	FUNCTIONFS_ENDPOINT_DESC	_IOR('g', 130, \
					     struct usb_endpoint_descriptor)