NetBSD Problem Report #32172

From darkstar@city-net.com  Sun Nov 27 03:53:58 2005
Return-Path: <darkstar@city-net.com>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by narn.netbsd.org (Postfix) with ESMTP id 669D763B871
	for <gnats-bugs@gnats.netbsd.org>; Sun, 27 Nov 2005 03:53:58 +0000 (UTC)
Message-Id: <Pine.BSF.4.51.0511262238320.68532@vegeta.city-net.com>
Date: Sat, 26 Nov 2005 22:40:49 -0500 (EST)
From: Matthew Orgass <darkstar@city-net.com>
To: gnats-bugs@netbsd.org
Subject: USB network drivers sleep in interrupt if stalled

>Number:         32172
>Category:       kern
>Synopsis:       USB network drivers sleep in interrupt if stalled
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Nov 27 03:54:01 +0000 2005
>Originator:     darkstar@city-net.com
>Release:        NetBSD 2.0_RC4
>Organization:
>Description:

  The USB network drivers will, if stalled, call usbd_clear_endpoint_stall
from the callback, which does a synchronous transfer, which sleeps.  The
callbacks are done in soft interrupts.

>How-To-Repeat:

  I hope this would be difficult or impossible to trigger without
explicitly setting stall.  I think it might also happen if the bus traffic
looks sufficiently messed up on the device side.

>Fix:

  This patch changes them to usbd_clear_endpoint_stall_async, but will not
restart the pipe (at least an ifconfig down/up should work).  It may make
sense to have usbd_clear_endpoint_stall_async restart the pipe or else have
another way to do automatic stall clearing (maybe before the callback of the
stalled transaction) for drivers that don't intend to do anything special
when stalled.

  A comment in usbd_clear_endpoint_stall would probably be a good idea too,
but is not included in this diff.

Index: if_aue.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_aue.c,v
retrieving revision 1.85.4.1
diff -u -r1.85.4.1 if_aue.c
--- if_aue.c	24 Jan 2005 21:42:10 -0000	1.85.4.1
+++ if_aue.c	27 Nov 2005 03:36:57 -0000
@@ -1058,7 +1058,7 @@
 			sc->aue_intr_errs = 0;
 		}
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
+			usbd_clear_endpoint_stall_async(sc->aue_ep[AUE_ENDPT_RX]);
 		return;
 	}

@@ -1103,7 +1103,7 @@
 			sc->aue_rx_errs = 0;
 		}
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
+			usbd_clear_endpoint_stall_async(sc->aue_ep[AUE_ENDPT_RX]);
 		goto done;
 	}

@@ -1204,7 +1204,7 @@
 		printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->aue_dev),
 		    usbd_errstr(status));
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_TX]);
+			usbd_clear_endpoint_stall_async(sc->aue_ep[AUE_ENDPT_TX]);
 		splx(s);
 		return;
 	}
Index: if_cue.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_cue.c,v
retrieving revision 1.40
diff -u -r1.40 if_cue.c
--- if_cue.c	11 Jul 2002 21:14:26 -0000	1.40
+++ if_cue.c	27 Nov 2005 03:36:59 -0000
@@ -797,7 +797,7 @@
 			sc->cue_rx_errs = 0;
 		}
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_RX]);
+			usbd_clear_endpoint_stall_async(sc->cue_ep[CUE_ENDPT_RX]);
 		goto done;
 	}

@@ -890,7 +890,7 @@
 		printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->cue_dev),
 		    usbd_errstr(status));
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]);
+			usbd_clear_endpoint_stall_async(sc->cue_ep[CUE_ENDPT_TX]);
 		splx(s);
 		return;
 	}
Index: if_kue.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_kue.c,v
retrieving revision 1.50
diff -u -r1.50 if_kue.c
--- if_kue.c	16 Jul 2002 22:00:31 -0000	1.50
+++ if_kue.c	27 Nov 2005 03:37:01 -0000
@@ -741,7 +741,7 @@
 			sc->kue_rx_errs = 0;
 		}
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_RX]);
+			usbd_clear_endpoint_stall_async(sc->kue_ep[KUE_ENDPT_RX]);
 		goto done;
 	}

@@ -842,7 +842,7 @@
 		printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->kue_dev),
 		    usbd_errstr(status));
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_TX]);
+			usbd_clear_endpoint_stall_async(sc->kue_ep[KUE_ENDPT_TX]);
 		splx(s);
 		return;
 	}
Index: if_uax.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/Attic/if_uax.c,v
retrieving revision 1.10
diff -u -r1.10 if_uax.c
--- if_uax.c	22 Dec 2003 10:27:51 -0000	1.10
+++ if_uax.c	27 Nov 2005 03:37:03 -0000
@@ -896,7 +896,7 @@
 		printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev),
 		    usbd_errstr(status));
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->sc_ep[UAX_ENDPT_TX]);
+			usbd_clear_endpoint_stall_async(sc->sc_ep[UAX_ENDPT_TX]);
 		splx(s);
 		return;
 	}
@@ -1089,7 +1089,7 @@
 			sc->sc_rx_errs = 0;
 		}
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->sc_ep[UAX_ENDPT_RX]);
+			usbd_clear_endpoint_stall_async(sc->sc_ep[UAX_ENDPT_RX]);
 		goto done;
 	}

@@ -1419,7 +1419,7 @@
 			sc->sc_intr_errs = 0;
 		}
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->sc_ep[UAX_ENDPT_RX]);
+			usbd_clear_endpoint_stall_async(sc->sc_ep[UAX_ENDPT_RX]);
 		return;
 	}

Index: if_udav.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_udav.c,v
retrieving revision 1.2.4.1
diff -u -r1.2.4.1 if_udav.c
--- if_udav.c	24 Jan 2005 21:37:45 -0000	1.2.4.1
+++ if_udav.c	27 Nov 2005 03:37:05 -0000
@@ -1086,7 +1086,7 @@
 		       usbd_errstr(status));
 		if (status == USBD_STALLED) {
 			sc->sc_refcnt++;
-			usbd_clear_endpoint_stall(sc->sc_pipe_tx);
+			usbd_clear_endpoint_stall_async(sc->sc_pipe_tx);
 			if (--sc->sc_refcnt < 0)
 				usb_detach_wakeup(USBDEV(sc->sc_dev));
 		}
@@ -1133,7 +1133,7 @@
 		}
 		if (status == USBD_STALLED) {
 			sc->sc_refcnt++;
-			usbd_clear_endpoint_stall(sc->sc_pipe_rx);
+			usbd_clear_endpoint_stall_async(sc->sc_pipe_rx);
 			if (--sc->sc_refcnt < 0)
 				usb_detach_wakeup(USBDEV(sc->sc_dev));
 		}
Index: if_upl.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_upl.c,v
retrieving revision 1.19
diff -u -r1.19 if_upl.c
--- if_upl.c	11 Jul 2002 21:14:26 -0000	1.19
+++ if_upl.c	27 Nov 2005 03:37:06 -0000
@@ -535,7 +535,7 @@
 			sc->sc_rx_errs = 0;
 		}
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]);
+			usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]);
 		goto done;
 	}

@@ -625,7 +625,7 @@
 		printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev),
 		    usbd_errstr(status));
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_TX]);
+			usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_TX]);
 		splx(s);
 		return;
 	}
@@ -841,7 +841,7 @@
 			sc->sc_intr_errs = 0;
 		}
 		if (status == USBD_STALLED)
-			usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]);
+			usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]);
 		return;
 	}

Index: if_url.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_url.c,v
retrieving revision 1.8.2.1.2.1
diff -u -r1.8.2.1.2.1 if_url.c
--- if_url.c	24 Jan 2005 21:42:31 -0000	1.8.2.1.2.1
+++ if_url.c	27 Nov 2005 03:37:09 -0000
@@ -966,7 +966,7 @@
 		       usbd_errstr(status));
 		if (status == USBD_STALLED) {
 			sc->sc_refcnt++;
-			usbd_clear_endpoint_stall(sc->sc_pipe_tx);
+			usbd_clear_endpoint_stall_async(sc->sc_pipe_tx);
 			if (--sc->sc_refcnt < 0)
 				usb_detach_wakeup(USBDEV(sc->sc_dev));
 		}
@@ -1013,7 +1013,7 @@
 		}
 		if (status == USBD_STALLED) {
 			sc->sc_refcnt++;
-			usbd_clear_endpoint_stall(sc->sc_pipe_rx);
+			usbd_clear_endpoint_stall_async(sc->sc_pipe_rx);
 			if (--sc->sc_refcnt < 0)
 				usb_detach_wakeup(USBDEV(sc->sc_dev));
 		}

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.