Module Name:    src
Committed By:   mrg
Date:           Sun Jul 15 21:13:31 UTC 2012

Modified Files:
        src/sys/dev/usb: usb_subr.c usbdi.c usbdi.h usbdivar.h

Log Message:
commit my workaround for PR 46648 for now, as the more involved
fix is not ready yet:

move the clear endpoint stall async call into the task thread,
to avoid trying to call kmem_alloc() from a softint thread.

XXX ideally moving callbacks into the task thread (or perhaps
a different high priority task thread) would be better than this
workaround, once that method is working.


To generate a diff of this commit:
cvs rdiff -u -r1.182 -r1.183 src/sys/dev/usb/usb_subr.c
cvs rdiff -u -r1.138 -r1.139 src/sys/dev/usb/usbdi.c
cvs rdiff -u -r1.83 -r1.84 src/sys/dev/usb/usbdi.h
cvs rdiff -u -r1.97 -r1.98 src/sys/dev/usb/usbdivar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/usb_subr.c
diff -u src/sys/dev/usb/usb_subr.c:1.182 src/sys/dev/usb/usb_subr.c:1.183
--- src/sys/dev/usb/usb_subr.c:1.182	Sun Jun 10 06:15:54 2012
+++ src/sys/dev/usb/usb_subr.c	Sun Jul 15 21:13:31 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: usb_subr.c,v 1.182 2012/06/10 06:15:54 mrg Exp $	*/
+/*	$NetBSD: usb_subr.c,v 1.183 2012/07/15 21:13:31 mrg Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $	*/
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.182 2012/06/10 06:15:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.183 2012/07/15 21:13:31 mrg Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_usbverbose.h"
@@ -765,6 +765,7 @@ usbd_setup_pipe(usbd_device_handle dev, 
 		free(p, M_USB);
 		return (err);
 	}
+	usb_init_task(&p->async_task, usbd_clear_endpoint_stall_async_cb, p);
 	*pipe = p;
 	return (USBD_NORMAL_COMPLETION);
 }
@@ -779,6 +780,7 @@ usbd_kill_pipe(usbd_pipe_handle pipe)
 	usbd_lock_pipe(pipe);
 	pipe->methods->close(pipe);
 	usbd_unlock_pipe(pipe);
+	usb_rem_task(pipe->device, &pipe->async_task);
 	pipe->endpoint->refcnt--;
 	free(pipe, M_USB);
 }

Index: src/sys/dev/usb/usbdi.c
diff -u src/sys/dev/usb/usbdi.c:1.138 src/sys/dev/usb/usbdi.c:1.139
--- src/sys/dev/usb/usbdi.c:1.138	Sun Jun 10 06:15:55 2012
+++ src/sys/dev/usb/usbdi.c	Sun Jul 15 21:13:31 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdi.c,v 1.138 2012/06/10 06:15:55 mrg Exp $	*/
+/*	$NetBSD: usbdi.c,v 1.139 2012/07/15 21:13:31 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.138 2012/06/10 06:15:55 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.139 2012/07/15 21:13:31 mrg Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_usb.h"
@@ -599,12 +599,12 @@ XXX should we do this?
 	return (err);
 }
 
-usbd_status
-usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe)
+void
+usbd_clear_endpoint_stall_async_cb(void *arg)
 {
+	usbd_pipe_handle pipe = arg;
 	usbd_device_handle dev = pipe->device;
 	usb_device_request_t req;
-	usbd_status err;
 
 	pipe->methods->cleartoggle(pipe);
 
@@ -613,8 +613,14 @@ usbd_clear_endpoint_stall_async(usbd_pip
 	USETW(req.wValue, UF_ENDPOINT_HALT);
 	USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
 	USETW(req.wLength, 0);
-	err = usbd_do_request_async(dev, &req, 0);
-	return (err);
+	(void)usbd_do_request_async(dev, &req, 0);
+}
+
+void
+usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe)
+{
+
+	usb_add_task(pipe->device, &pipe->async_task, USB_TASKQ_DRIVER);
 }
 
 void

Index: src/sys/dev/usb/usbdi.h
diff -u src/sys/dev/usb/usbdi.h:1.83 src/sys/dev/usb/usbdi.h:1.84
--- src/sys/dev/usb/usbdi.h:1.83	Sun Jun 10 06:15:55 2012
+++ src/sys/dev/usb/usbdi.h	Sun Jul 15 21:13:31 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdi.h,v 1.83 2012/06/10 06:15:55 mrg Exp $	*/
+/*	$NetBSD: usbdi.h,v 1.84 2012/07/15 21:13:31 mrg Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $	*/
 
 /*
@@ -113,12 +113,12 @@ usb_endpoint_descriptor_t *usbd_interfac
 usbd_status usbd_abort_pipe(usbd_pipe_handle);
 usbd_status usbd_abort_default_pipe(usbd_device_handle);
 usbd_status usbd_clear_endpoint_stall(usbd_pipe_handle);
-usbd_status usbd_clear_endpoint_stall_async(usbd_pipe_handle);
+void usbd_clear_endpoint_stall_async(usbd_pipe_handle);
 void usbd_clear_endpoint_toggle(usbd_pipe_handle);
 usbd_status usbd_endpoint_count(usbd_interface_handle, u_int8_t *);
 usbd_status usbd_interface_count(usbd_device_handle, u_int8_t *);
 void usbd_interface2device_handle(usbd_interface_handle,
-					 usbd_device_handle *);
+				  usbd_device_handle *);
 usbd_status usbd_device2interface_handle(usbd_device_handle,
 			      u_int8_t, usbd_interface_handle *);
 
@@ -188,6 +188,9 @@ typedef struct {
 void usb_desc_iter_init(usbd_device_handle, usbd_desc_iter_t *);
 const usb_descriptor_t *usb_desc_iter_next(usbd_desc_iter_t *);
 
+/* Used to clear endpoint stalls from the softint */
+void usbd_clear_endpoint_stall_async_cb(void *);
+
 /*
  * The usb_task structs form a queue of things to run in the USB event
  * thread.  Normally this is just device discovery when a connect/disconnect

Index: src/sys/dev/usb/usbdivar.h
diff -u src/sys/dev/usb/usbdivar.h:1.97 src/sys/dev/usb/usbdivar.h:1.98
--- src/sys/dev/usb/usbdivar.h:1.97	Sun Jun 10 06:15:55 2012
+++ src/sys/dev/usb/usbdivar.h	Sun Jul 15 21:13:31 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdivar.h,v 1.97 2012/06/10 06:15:55 mrg Exp $	*/
+/*	$NetBSD: usbdivar.h,v 1.98 2012/07/15 21:13:31 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
@@ -212,6 +212,7 @@ struct usbd_pipe {
 	char			aborting;
 	SIMPLEQ_HEAD(, usbd_xfer) queue;
 	LIST_ENTRY(usbd_pipe)	next;
+	struct usb_task		async_task;
 
 	usbd_xfer_handle	intrxfer; /* used for repeating requests */
 	char			repeat;

Reply via email to