Re: Oops with dwc3 in device mode and functionfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Checking more, I think the 3 "do {...} while(--count)" loops in f_fs.c
are wrong: they should be "while(count--){...}" ("git format-patch"
attached, sorry, I'm on a dev-hostile mail client at the moment):
- count covers function-specific endpoint, so it is 0 when no endpoint
is declared, which leads to an integer underflow and exceeding eps
array end.
- a function enabling/disabling endpoint 0 does not make sense to me
(they are only supposed to care about their own descriptor, don't they
?)

On Tue, Jan 3, 2017 at 3:49 PM, Vincent Pelletier <plr.vincent@xxxxxxxxx> wrote:
> The functionfs side of things is a bit complicated, as I'm writing a
> python module[2] for it, and I am still very new to functionfs. It
> does not crash on 4.9-rc7 though.

As per the above, this was not the whole truth: a device declared with
2 endpoints does not crash on 4.9-rc7, crashes on 4.10-rc2, including
with the upcomming rc3 fixes. A zero endpoint version crashes *and*
made me realise the loop error.

Sadly, this fix alone is not enough to get a functional device. I did
not investigate much yet, and need to get some sleep.
-- 
Vincent Pelletier
From 85815ce5c82022ccfbb2c0184589c4766325b517 Mon Sep 17 00:00:00 2001
From: Vincent Pelletier <vincent@xxxxxxxxxx>
Date: Tue, 3 Jan 2017 16:47:23 +0100
Subject: [RFC] usb: gadget: f_fs: Fix iterations on endpoints.

When zero endpoints are declared for a function, there is no endpoint
to disable, enable or free, so replace do...while loops with while loops.
Change pre-decrement to post-decrement to iterate the same number of times
when there are endpoints to process.

Signed-off-by: Vincent Pelletier <vincent@xxxxxxxxxx>
---
 drivers/usb/gadget/function/f_fs.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 5e746adc8a2d..5490fc51638e 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1806,7 +1806,7 @@ static void ffs_func_eps_disable(struct ffs_function *func)
 	unsigned long flags;
 
 	spin_lock_irqsave(&func->ffs->eps_lock, flags);
-	do {
+	while (count--) {
 		/* pending requests get nuked */
 		if (likely(ep->ep))
 			usb_ep_disable(ep->ep);
@@ -1817,7 +1817,7 @@ static void ffs_func_eps_disable(struct ffs_function *func)
 			__ffs_epfile_read_buffer_free(epfile);
 			++epfile;
 		}
-	} while (--count);
+	}
 	spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
 }
 
@@ -1831,7 +1831,7 @@ static int ffs_func_eps_enable(struct ffs_function *func)
 	int ret = 0;
 
 	spin_lock_irqsave(&func->ffs->eps_lock, flags);
-	do {
+	while(count--) {
 		struct usb_endpoint_descriptor *ds;
 		int desc_idx;
 
@@ -1867,7 +1867,7 @@ static int ffs_func_eps_enable(struct ffs_function *func)
 
 		++ep;
 		++epfile;
-	} while (--count);
+	}
 	spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
 
 	return ret;
@@ -3448,12 +3448,12 @@ static void ffs_func_unbind(struct usb_configuration *c,
 
 	/* cleanup after autoconfig */
 	spin_lock_irqsave(&func->ffs->eps_lock, flags);
-	do {
+	while (count--) {
 		if (ep->ep && ep->req)
 			usb_ep_free_request(ep->ep, ep->req);
 		ep->req = NULL;
 		++ep;
-	} while (--count);
+	}
 	spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
 	kfree(func->eps);
 	func->eps = NULL;
-- 
2.11.0


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux