Wed Feb 12 16:00:17 2020 UTC ()
New xfer state variables ux_timeout_set and ux_timeout_reset.

These are needed because:

- The host controller interrupt cannot wait for the callout or task
  to finish running.

- Nothing in the USBD API as is waits for the callout or task to
  finish running.

- Callers expect to be able to resubmit USB xfers from xfer callbacks
  without waiting for anything to finish running.

The variable ux_timeout_set can be used by a host controller to
decide on submission whether to schedule the callout or to ask an
already-scheduled callout or already-queued task to reschedule the
callout, by setting the variable ux_timeout_reset to true.

When the callout or task runs and sees that ux_timeout_reset is true,
rather than queue the task or abort the xfer, it can instead just
schedule the callout anew.


(riastradh)
diff -r1.190 -r1.191 src/sys/dev/usb/usbdi.c
diff -r1.120 -r1.121 src/sys/dev/usb/usbdivar.h

cvs diff -r1.190 -r1.191 src/sys/dev/usb/usbdi.c (expand / switch to unified diff)

--- src/sys/dev/usb/usbdi.c 2020/02/12 15:59:59 1.190
+++ src/sys/dev/usb/usbdi.c 2020/02/12 16:00:17 1.191
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: usbdi.c,v 1.190 2020/02/12 15:59:59 riastradh Exp $ */ 1/* $NetBSD: usbdi.c,v 1.191 2020/02/12 16:00:17 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology, Matthew R. Green (mrg@eterna.com.au), 9 * Carlstedt Research & Technology, Matthew R. Green (mrg@eterna.com.au),
10 * and Nick Hudson. 10 * and Nick Hudson.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.190 2020/02/12 15:59:59 riastradh Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.191 2020/02/12 16:00:17 riastradh Exp $");
36 36
37#ifdef _KERNEL_OPT 37#ifdef _KERNEL_OPT
38#include "opt_usb.h" 38#include "opt_usb.h"
39#include "opt_compat_netbsd.h" 39#include "opt_compat_netbsd.h"
40#include "usb_dma.h" 40#include "usb_dma.h"
41#endif 41#endif
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/device.h> 46#include <sys/device.h>
47#include <sys/kmem.h> 47#include <sys/kmem.h>
48#include <sys/proc.h> 48#include <sys/proc.h>
@@ -484,26 +484,27 @@ out: @@ -484,26 +484,27 @@ out:
484 484
485static usbd_status 485static usbd_status
486usbd_free_xfer(struct usbd_xfer *xfer) 486usbd_free_xfer(struct usbd_xfer *xfer)
487{ 487{
488 USBHIST_FUNC(); 488 USBHIST_FUNC();
489 USBHIST_CALLARGS(usbdebug, "%#jx", (uintptr_t)xfer, 0, 0, 0); 489 USBHIST_CALLARGS(usbdebug, "%#jx", (uintptr_t)xfer, 0, 0, 0);
490 490
491 if (xfer->ux_buf) { 491 if (xfer->ux_buf) {
492 usbd_free_buffer(xfer); 492 usbd_free_buffer(xfer);
493 } 493 }
494 494
495 /* Wait for any straggling timeout to complete. */ 495 /* Wait for any straggling timeout to complete. */
496 mutex_enter(xfer->ux_bus->ub_lock); 496 mutex_enter(xfer->ux_bus->ub_lock);
 497 xfer->ux_timeout_reset = false; /* do not resuscitate */
497 callout_halt(&xfer->ux_callout, xfer->ux_bus->ub_lock); 498 callout_halt(&xfer->ux_callout, xfer->ux_bus->ub_lock);
498 usb_rem_task_wait(xfer->ux_pipe->up_dev, &xfer->ux_aborttask, 499 usb_rem_task_wait(xfer->ux_pipe->up_dev, &xfer->ux_aborttask,
499 USB_TASKQ_HC, xfer->ux_bus->ub_lock); 500 USB_TASKQ_HC, xfer->ux_bus->ub_lock);
500 mutex_exit(xfer->ux_bus->ub_lock); 501 mutex_exit(xfer->ux_bus->ub_lock);
501 502
502 cv_destroy(&xfer->ux_cv); 503 cv_destroy(&xfer->ux_cv);
503 xfer->ux_bus->ub_methods->ubm_freex(xfer->ux_bus, xfer); 504 xfer->ux_bus->ub_methods->ubm_freex(xfer->ux_bus, xfer);
504 return USBD_NORMAL_COMPLETION; 505 return USBD_NORMAL_COMPLETION;
505} 506}
506 507
507int 508int
508usbd_create_xfer(struct usbd_pipe *pipe, size_t len, unsigned int flags, 509usbd_create_xfer(struct usbd_pipe *pipe, size_t len, unsigned int flags,
509 unsigned int nframes, struct usbd_xfer **xp) 510 unsigned int nframes, struct usbd_xfer **xp)

cvs diff -r1.120 -r1.121 src/sys/dev/usb/usbdivar.h (expand / switch to unified diff)

--- src/sys/dev/usb/usbdivar.h 2020/02/08 08:47:27 1.120
+++ src/sys/dev/usb/usbdivar.h 2020/02/12 16:00:17 1.121
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: usbdivar.h,v 1.120 2020/02/08 08:47:27 maxv Exp $ */ 1/* $NetBSD: usbdivar.h,v 1.121 2020/02/12 16:00:17 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology and Matthew R. Green (mrg@eterna.com.au). 9 * Carlstedt Research & Technology and Matthew R. Green (mrg@eterna.com.au).
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -278,26 +278,39 @@ struct usbd_xfer { @@ -278,26 +278,39 @@ struct usbd_xfer {
278 void *ux_buf; 278 void *ux_buf;
279 uint32_t ux_bufsize; 279 uint32_t ux_bufsize;
280 280
281 uint8_t ux_rqflags; 281 uint8_t ux_rqflags;
282#define URQ_REQUEST 0x01 282#define URQ_REQUEST 0x01
283 283
284 SIMPLEQ_ENTRY(usbd_xfer) 284 SIMPLEQ_ENTRY(usbd_xfer)
285 ux_next; 285 ux_next;
286 286
287 void *ux_hcpriv; /* private use by the HC driver */ 287 void *ux_hcpriv; /* private use by the HC driver */
288 288
289 struct usb_task ux_aborttask; 289 struct usb_task ux_aborttask;
290 struct callout ux_callout; 290 struct callout ux_callout;
 291
 292 /*
 293 * Protected by bus lock.
 294 *
 295 * - ux_timeout_set: The timeout is scheduled as a callout or
 296 * usb task, and has not yet acquired the bus lock.
 297 *
 298 * - ux_timeout_reset: The xfer completed, and was resubmitted
 299 * before the callout or task was able to acquire the bus
 300 * lock, so one or the other needs to schedule a new callout.
 301 */
 302 bool ux_timeout_set;
 303 bool ux_timeout_reset;
291}; 304};
292 305
293void usbd_init(void); 306void usbd_init(void);
294void usbd_finish(void); 307void usbd_finish(void);
295 308
296#if defined(USB_DEBUG) 309#if defined(USB_DEBUG)
297void usbd_dump_iface(struct usbd_interface *); 310void usbd_dump_iface(struct usbd_interface *);
298void usbd_dump_device(struct usbd_device *); 311void usbd_dump_device(struct usbd_device *);
299void usbd_dump_endpoint(struct usbd_endpoint *); 312void usbd_dump_endpoint(struct usbd_endpoint *);
300void usbd_dump_queue(struct usbd_pipe *); 313void usbd_dump_queue(struct usbd_pipe *);
301void usbd_dump_pipe(struct usbd_pipe *); 314void usbd_dump_pipe(struct usbd_pipe *);
302#endif 315#endif
303 316