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

Commit 3bf67d40 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "USB: f_fs: Move ep completion out of stack"

parents 2a3af19b 44f86b53
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -141,6 +141,8 @@ struct ffs_data {
	struct usb_request		*ep0req;		/* P: mutex */
	struct completion		ep0req_completion;	/* P: mutex */
	int				ep0req_status;		/* P: mutex */
	struct completion		epin_completion;
	struct completion		epout_completion;

	/* reference counter */
	atomic_t			ref;
@@ -749,8 +751,11 @@ static const struct file_operations ffs_ep0_operations = {

static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req)
{
	struct ffs_ep *ep = _ep->driver_data;
	ENTER();
	if (likely(req->context)) {

	/* req may be freed during unbind */
	if (ep && ep->req && likely(req->context)) {
		struct ffs_ep *ep = _ep->driver_data;
		ep->status = req->status ? req->status : req->actual;
		complete(req->context);
@@ -762,6 +767,7 @@ static ssize_t ffs_epfile_io(struct file *file,
{
	struct ffs_epfile *epfile = file->private_data;
	struct ffs_ep *ep;
	struct ffs_data *ffs = epfile->ffs;
	char *data = NULL;
	ssize_t ret;
	int halt;
@@ -863,21 +869,27 @@ first_try:
		ret = -EBADMSG;
	} else {
		/* Fire the request */
		DECLARE_COMPLETION_ONSTACK(done);
		struct completion *done;

		struct usb_request *req = ep->req;
		req->context  = &done;
		req->complete = ffs_epfile_io_complete;
		req->buf      = data;
		req->length   = buffer_len;

		if (read) {
			INIT_COMPLETION(ffs->epout_completion);
			req->context  = done = &ffs->epout_completion;
		} else {
			INIT_COMPLETION(ffs->epin_completion);
			req->context  = done = &ffs->epin_completion;
		}
		ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC);

		spin_unlock_irq(&epfile->ffs->eps_lock);

		if (unlikely(ret < 0)) {
			ret = -EIO;
		} else if (unlikely(wait_for_completion_interruptible(&done))) {
		} else if (unlikely(wait_for_completion_interruptible(done))) {
			spin_lock_irq(&epfile->ffs->eps_lock);
			/*
			 * While we were acquiring lock endpoint got disabled
@@ -1369,6 +1381,8 @@ static struct ffs_data *ffs_data_new(void)
	spin_lock_init(&ffs->eps_lock);
	init_waitqueue_head(&ffs->ev.waitq);
	init_completion(&ffs->ep0req_completion);
	init_completion(&ffs->epout_completion);
	init_completion(&ffs->epin_completion);

	/* XXX REVISIT need to update it in some places, or do we? */
	ffs->ev.can_stall = 1;