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;