diff mbox

usbnet: Activate the halt interrupt endpoint to fix endless "XactErr" error

Message ID CA+v9cxaLERjFKdE7joGgmpbxCUotdh=Nn4F4f-KeOXwp8nqMPg@mail.gmail.com
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

huajun li June 11, 2012, 2:41 p.m. UTC
On Fri, Jun 8, 2012 at 5:54 AM, David Miller <davem@davemloft.net> wrote:
> From: Huajun Li <huajun.li.lee@gmail.com>
> Date: Tue, 5 Jun 2012 22:12:17 +0800
>
>> There prints endless "XactErr" error msg once switch my device to the
>> configuration
>>  which needs cdc_ether driver, the root cause is the interrupt endpoint halts.
>> Maybe this is a common issue, so fix it by activating the endpoint
>> once the error occurs.
>>
>> Signed-off-by: Huajun Li <huajun.li.lee@gmail.com>
>
> A USB expert needs to review this as I lack the knowledge to adequately
> go over this patch.


Update the patch according to Ming and Alan's comments, it only
handles "-EPIPE" error of interrupt endpoint. Welcome comments:
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Bjørn Mork June 11, 2012, 8:47 p.m. UTC | #1
Huajun Li <huajun.li.lee@gmail.com> writes:

> diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
> index 76f4396..c0bcb61 100644
> --- a/include/linux/usb/usbnet.h
> +++ b/include/linux/usb/usbnet.h
> @@ -62,13 +62,14 @@ struct usbnet {
>  	unsigned long		flags;
>  #		define EVENT_TX_HALT	0
>  #		define EVENT_RX_HALT	1
> -#		define EVENT_RX_MEMORY	2
> -#		define EVENT_STS_SPLIT	3
> -#		define EVENT_LINK_RESET	4
> -#		define EVENT_RX_PAUSED	5
> -#		define EVENT_DEV_WAKING 6
> -#		define EVENT_DEV_ASLEEP 7
> -#		define EVENT_DEV_OPEN	8
> +#		define EVENT_STS_HALT	2
> +#		define EVENT_RX_MEMORY	3
> +#		define EVENT_STS_SPLIT	4
> +#		define EVENT_LINK_RESET	5
> +#		define EVENT_RX_PAUSED	6
> +#		define EVENT_DEV_WAKING 7
> +#		define EVENT_DEV_ASLEEP 8
> +#		define EVENT_DEV_OPEN	9
>  };

Why do you renumber all of these instead of adding the new
EVENT_STS_HALT to the end of the list?


Bjørn
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
huajun li June 12, 2012, 10:09 a.m. UTC | #2
On Tue, Jun 12, 2012 at 4:47 AM, Bjørn Mork <bjorn@mork.no> wrote:
> Huajun Li <huajun.li.lee@gmail.com> writes:
>
>> diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
>> index 76f4396..c0bcb61 100644
>> --- a/include/linux/usb/usbnet.h
>> +++ b/include/linux/usb/usbnet.h
>> @@ -62,13 +62,14 @@ struct usbnet {
>>       unsigned long           flags;
>>  #            define EVENT_TX_HALT    0
>>  #            define EVENT_RX_HALT    1
>> -#            define EVENT_RX_MEMORY  2
>> -#            define EVENT_STS_SPLIT  3
>> -#            define EVENT_LINK_RESET 4
>> -#            define EVENT_RX_PAUSED  5
>> -#            define EVENT_DEV_WAKING 6
>> -#            define EVENT_DEV_ASLEEP 7
>> -#            define EVENT_DEV_OPEN   8
>> +#            define EVENT_STS_HALT   2
>> +#            define EVENT_RX_MEMORY  3
>> +#            define EVENT_STS_SPLIT  4
>> +#            define EVENT_LINK_RESET 5
>> +#            define EVENT_RX_PAUSED  6
>> +#            define EVENT_DEV_WAKING 7
>> +#            define EVENT_DEV_ASLEEP 8
>> +#            define EVENT_DEV_OPEN   9
>>  };
>
> Why do you renumber all of these instead of adding the new
> EVENT_STS_HALT to the end of the list?
>

Thanks for your comments.

I think it's nice to sort these mask codes by their purposes.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

=============================================

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 9f58330..bd8ebef 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -537,6 +537,10 @@  static void intr_complete (struct urb *urb)
 			  "intr shutdown, code %d\n", status);
 		return;

+	case -EPIPE:
+		usbnet_defer_kevent(dev, EVENT_STS_HALT);
+		return;
+
 	/* NOTE:  not throttling like RX/TX, since this endpoint
 	 * already polls infrequently
 	 */
@@ -967,6 +971,33 @@  fail_halt:
 		}
 	}

+	if (test_bit(EVENT_STS_HALT, &dev->flags)) {
+		unsigned pipe;
+		struct usb_endpoint_descriptor *desc;
+
+		desc = &dev->status->desc;
+		pipe = usb_rcvintpipe(dev->udev,
+			desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+		status = usb_autopm_get_interface(dev->intf);
+		if (status < 0)
+			goto fail_sts;
+		status = usb_clear_halt(dev->udev, pipe);
+		if (status < 0) {
+			usb_autopm_put_interface(dev->intf);
+fail_sts:
+			netdev_err(dev->net,
+				"can't clear intr halt, status %d\n", status);
+		} else {
+			clear_bit(EVENT_STS_HALT, &dev->flags);
+			status = usb_submit_urb(dev->interrupt, GFP_KERNEL);
+			if (status != 0)
+				netif_err(dev, timer, dev->net,
+					"intr resubmit --> %d\n", status);
+
+			usb_autopm_put_interface(dev->intf);
+		}
+	}
+
 	/* tasklet could resubmit itself forever if memory is tight */
 	if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
 		struct urb	*urb = NULL;
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 76f4396..c0bcb61 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -62,13 +62,14 @@  struct usbnet {
 	unsigned long		flags;
 #		define EVENT_TX_HALT	0
 #		define EVENT_RX_HALT	1
-#		define EVENT_RX_MEMORY	2
-#		define EVENT_STS_SPLIT	3
-#		define EVENT_LINK_RESET	4
-#		define EVENT_RX_PAUSED	5
-#		define EVENT_DEV_WAKING 6
-#		define EVENT_DEV_ASLEEP 7
-#		define EVENT_DEV_OPEN	8
+#		define EVENT_STS_HALT	2
+#		define EVENT_RX_MEMORY	3
+#		define EVENT_STS_SPLIT	4
+#		define EVENT_LINK_RESET	5
+#		define EVENT_RX_PAUSED	6
+#		define EVENT_DEV_WAKING 7
+#		define EVENT_DEV_ASLEEP 8
+#		define EVENT_DEV_OPEN	9
 };

 static inline struct usb_driver *driver_of(struct usb_interface *intf)