[RFC PATCH for v3.5 2/2] usb: gadget: at91_udc: fix regression when connecting the usb cable

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

 



Revert "usb: gadget: at91_udc: fix endpoint descriptor dereference"
Revert "usb: gadget: Update at91_udc to use usb_endpoint_descriptor inside the struct usb_ep"

This reverts commit 5eaee54b1c52a83dc74445792cf49900a8050da8.
This reverts commit 5a6506f00efa4b38b181152b69a072e766c7ce92.

Tested using the Atmel AT91SAM9260EK board.
After connecting the cable the g_ether driver doesn't work as expected.

AT91SAM9260EK dmesg output with USB_GADGET_DEBUG defined:
udc: active
g_ether gadget: suspend
g_ether gadget: resume
g_ether gadget: suspend
g_ether gadget: resume
g_ether gadget: full-speed config #1: CDC Ethernet (ECM)
udc: bad ep or descriptor
g_ether gadget: init ecm
g_ether gadget: notify connect false
g_ether gadget: activate ecm
udc: bad ep or descriptor
usb0: enable ep1 --> -22
g_ether gadget: reset ecm
------------[ cut here ]------------
WARNING: at drivers/usb/gadget/u_ether.c:941 ecm_set_alt+0x60/0x1fc()
Modules linked in:
[<c00146e4>] (unwind_backtrace+0x0/0xf0) from [<c001d3a8>] (warn_slowpath_common+0x4c/0x64)
[<c001d3a8>] (warn_slowpath_common+0x4c/0x64) from [<c001d3dc>] (warn_slowpath_null+0x1c/0x24)
[<c001d3dc>] (warn_slowpath_null+0x1c/0x24) from [<c01e6714>] (ecm_set_alt+0x60/0x1fc)
[<c01e6714>] (ecm_set_alt+0x60/0x1fc) from [<c01e3554>] (composite_setup+0x198/0xc9c)
[<c01e3554>] (composite_setup+0x198/0xc9c) from [<c01df258>] (at91_udc_irq+0x4a0/0x878)
[<c01df258>] (at91_udc_irq+0x4a0/0x878) from [<c0054c74>] (handle_irq_event_percpu+0x50/0x1cc)
[<c0054c74>] (handle_irq_event_percpu+0x50/0x1cc) from [<c0054e18>] (handle_irq_event+0x28/0x38)
[<c0054e18>] (handle_irq_event+0x28/0x38) from [<c0056f40>] (handle_level_irq+0x80/0xdc)
[<c0056f40>] (handle_level_irq+0x80/0xdc) from [<c00545f0>] (generic_handle_irq+0x28/0x3c)
[<c00545f0>] (generic_handle_irq+0x28/0x3c) from [<c000fe0c>] (handle_IRQ+0x30/0x98)
[<c000fe0c>] (handle_IRQ+0x30/0x98) from [<c000ebb8>] (__irq_svc+0x38/0x60)
[<c000ebb8>] (__irq_svc+0x38/0x60) from [<c000ff64>] (default_idle+0x24/0x40)
[<c000ff64>] (default_idle+0x24/0x40) from [<c001012c>] (cpu_idle+0x8c/0xcc)
[<c001012c>] (cpu_idle+0x8c/0xcc) from [<c034271c>] (start_kernel+0x280/0x2d0)
---[ end trace 0980cb0ba7b8f3cd ]---
g_ether gadget: activate ecm
udc: bad ep or descriptor
usb0: enable ep1 --> -22

usb host pc linux Ubuntu 12.04:
[ 6972.812030] usb 4-2: new full-speed USB device number 8 using uhci_hcd
[ 6973.126106] cdc_subset: probe of 4-2:1.0 failed with error -22
[ 6973.228065] cdc_ether: probe of 4-2:1.0 failed with error -32
[ 6973.330068] cdc_subset: probe of 4-2:1.1 failed with error -32

Seems that another way to fix the regression is to remove the check:
@@ -475,7 +475,7 @@ static int at91_ep_enable(struct usb_ep *_ep,
        unsigned long   flags;

        if (!_ep || !ep
-                       || !desc || ep->ep.desc
+                       || !desc
                        || _ep->name == ep0name
                        || desc->bDescriptorType != USB_DT_ENDPOINT
                        || (maxpacket = usb_endpoint_maxp(desc)) == 0

Signed-off-by: Fabio Porcedda <fabio.porcedda@xxxxxxxxx>
Reported-And-Tested-by: Fabio Porcedda <fabio.porcedda@xxxxxxxxx>
Reported-by: Mario Jorge Isidoro <Mario.Isidoro@xxxxxxxxx>
Cc: linux-usb@xxxxxxxxxxxxxxx
Cc: Sebastian Andrzej Siewior <sebastian@xxxxxxxxxxxxx>
Cc: Felipe Balbi <balbi@xxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
Cc: Nicolas Ferre <nicolas.ferre@xxxxxxxxx>
Cc: Ido Shayevitz <idos@xxxxxxxxxxxxxx>
Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@xxxxxxxxxxxx>
---
 drivers/usb/gadget/at91_udc.c | 17 +++++++++--------
 drivers/usb/gadget/at91_udc.h |  3 +++
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 7687ccd..9d7bcd9 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -212,7 +212,7 @@ static int proc_udc_show(struct seq_file *s, void *unused)
 	if (udc->enabled && udc->vbus) {
 		proc_ep_show(s, &udc->ep[0]);
 		list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) {
-			if (ep->ep.desc)
+			if (ep->desc)
 				proc_ep_show(s, ep);
 		}
 	}
@@ -475,7 +475,7 @@ static int at91_ep_enable(struct usb_ep *_ep,
 	unsigned long	flags;
 
 	if (!_ep || !ep
-			|| !desc || ep->ep.desc
+			|| !desc || ep->desc
 			|| _ep->name == ep0name
 			|| desc->bDescriptorType != USB_DT_ENDPOINT
 			|| (maxpacket = usb_endpoint_maxp(desc)) == 0
@@ -530,7 +530,7 @@ ok:
 	tmp |= AT91_UDP_EPEDS;
 	__raw_writel(tmp, ep->creg);
 
-	ep->ep.desc = desc;
+	ep->desc = desc;
 	ep->ep.maxpacket = maxpacket;
 
 	/*
@@ -558,6 +558,7 @@ static int at91_ep_disable (struct usb_ep * _ep)
 	nuke(ep, -ESHUTDOWN);
 
 	/* restore the endpoint's pristine config */
+	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	ep->ep.maxpacket = ep->maxpacket;
 
@@ -617,7 +618,7 @@ static int at91_ep_queue(struct usb_ep *_ep,
 		return -EINVAL;
 	}
 
-	if (!_ep || (!ep->ep.desc && ep->ep.name != ep0name)) {
+	if (!_ep || (!ep->desc && ep->ep.name != ep0name)) {
 		DBG("invalid ep\n");
 		return -EINVAL;
 	}
@@ -832,7 +833,7 @@ static void udc_reinit(struct at91_udc *udc)
 
 		if (i != 0)
 			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
-		ep->ep.desc = NULL;
+		ep->desc = NULL;
 		ep->stopped = 0;
 		ep->fifo_bank = 0;
 		ep->ep.maxpacket = ep->maxpacket;
@@ -1171,7 +1172,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
 			| USB_REQ_GET_STATUS:
 		tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
 		ep = &udc->ep[tmp];
-		if (tmp >= NUM_ENDPOINTS || (tmp && !ep->ep.desc))
+		if (tmp >= NUM_ENDPOINTS || (tmp && !ep->desc))
 			goto stall;
 
 		if (tmp) {
@@ -1196,7 +1197,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
 		ep = &udc->ep[tmp];
 		if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS)
 			goto stall;
-		if (!ep->ep.desc || ep->is_iso)
+		if (!ep->desc || ep->is_iso)
 			goto stall;
 		if ((w_index & USB_DIR_IN)) {
 			if (!ep->is_in)
@@ -1217,7 +1218,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
 			goto stall;
 		if (tmp == 0)
 			goto succeed;
-		if (!ep->ep.desc || ep->is_iso)
+		if (!ep->desc || ep->is_iso)
 			goto stall;
 		if ((w_index & USB_DIR_IN)) {
 			if (!ep->is_in)
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h
index e647d1c..3c0315b 100644
--- a/drivers/usb/gadget/at91_udc.h
+++ b/drivers/usb/gadget/at91_udc.h
@@ -105,6 +105,9 @@ struct at91_ep {
 	unsigned			is_in:1;
 	unsigned			is_iso:1;
 	unsigned			fifo_bank:1;
+
+	const struct usb_endpoint_descriptor
+					*desc;
 };
 
 /*
-- 
1.7.11.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

  Powered by Linux