Module Name: src
Committed By: riastradh
Date: Sat Feb 15 01:21:56 UTC 2020
Modified Files:
src/sys/arch/mips/adm5120/dev: ahci.c
src/sys/dev/ic: sl811hs.c
src/sys/dev/usb: ehci.c motg.c ohci.c uhci.c vhci.c xhci.c
src/sys/external/bsd/dwc2: dwc2.c
Log Message:
Fix mistakes in previous sloppy change with root intr xfers.
- Make sure ux_status is set to USBD_IN_PROGRESS when started.
Otherwise, if it is still in flight when we abort the pipe,
usbd_ar_pipe will skip calling upm_abort.
- Initialize ux_status under the lock; in principle a completion
interrupt (or a delay) could race with the initialization.
- KASSERT that the xfer is in progress when we're about to complete
it.
Candidate fix for PR kern/54963 for other HCI drivers than uhci.
ok nick
ok phone
(This is the change that nick evidently MEANT to ok when he ok'd the
previous one!)
To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/mips/adm5120/dev/ahci.c
cvs rdiff -u -r1.102 -r1.103 src/sys/dev/ic/sl811hs.c
cvs rdiff -u -r1.272 -r1.273 src/sys/dev/usb/ehci.c
cvs rdiff -u -r1.26 -r1.27 src/sys/dev/usb/motg.c
cvs rdiff -u -r1.294 -r1.295 src/sys/dev/usb/ohci.c
cvs rdiff -u -r1.292 -r1.293 src/sys/dev/usb/uhci.c
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/usb/vhci.c
cvs rdiff -u -r1.117 -r1.118 src/sys/dev/usb/xhci.c
cvs rdiff -u -r1.68 -r1.69 src/sys/external/bsd/dwc2/dwc2.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/mips/adm5120/dev/ahci.c
diff -u src/sys/arch/mips/adm5120/dev/ahci.c:1.19 src/sys/arch/mips/adm5120/dev/ahci.c:1.20
--- src/sys/arch/mips/adm5120/dev/ahci.c:1.19 Wed Feb 12 16:02:01 2020
+++ src/sys/arch/mips/adm5120/dev/ahci.c Sat Feb 15 01:21:56 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ahci.c,v 1.19 2020/02/12 16:02:01 riastradh Exp $ */
+/* $NetBSD: ahci.c,v 1.20 2020/02/15 01:21:56 riastradh Exp $ */
/*-
* Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko.
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.19 2020/02/12 16:02:01 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.20 2020/02/15 01:21:56 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -438,6 +438,7 @@ ahci_poll_hub(void *arg)
xfer = sc->sc_intr_xfer;
if (xfer == NULL)
goto out;
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
/*
* If the intr xfer for which we were scheduled is done, and
@@ -754,11 +755,14 @@ ahci_root_intr_start(struct usbd_xfer *x
DPRINTF(D_TRACE, ("SLRIstart "));
+ mutex_enter(&sc->sc_lock);
KASSERT(sc->sc_intr_xfer == NULL);
-
sc->sc_interval = MS_TO_TICKS(xfer->ux_pipe->up_endpoint->ue_edesc->bInterval);
callout_schedule(&sc->sc_poll_handle, sc->sc_interval);
sc->sc_intr_xfer = xfer;
+ xfer->ux_status = USBD_IN_PROGRESS;
+ mutex_exit(&sc->sc_lock);
+
return USBD_IN_PROGRESS;
}
Index: src/sys/dev/ic/sl811hs.c
diff -u src/sys/dev/ic/sl811hs.c:1.102 src/sys/dev/ic/sl811hs.c:1.103
--- src/sys/dev/ic/sl811hs.c:1.102 Fri Dec 27 09:41:50 2019
+++ src/sys/dev/ic/sl811hs.c Sat Feb 15 01:21:56 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: sl811hs.c,v 1.102 2019/12/27 09:41:50 msaitoh Exp $ */
+/* $NetBSD: sl811hs.c,v 1.103 2020/02/15 01:21:56 riastradh Exp $ */
/*
* Not (c) 2007 Matthew Orgass
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.102 2019/12/27 09:41:50 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.103 2020/02/15 01:21:56 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_slhci.h"
@@ -1030,7 +1030,9 @@ slhci_root_start(struct usbd_xfer *xfer)
KASSERT(spipe->ptype == PT_ROOT_INTR);
mutex_enter(&sc->sc_intr_lock);
+ KASSERT(t->rootintr == NULL);
t->rootintr = xfer;
+ xfer->ux_status = USBD_IN_PROGRESS;
mutex_exit(&sc->sc_intr_lock);
return USBD_IN_PROGRESS;
@@ -2389,6 +2391,8 @@ slhci_callback(struct slhci_softc *sc)
if (t->rootintr != NULL) {
u_char *p;
+ KASSERT(t->rootintr->ux_status ==
+ USBD_IN_PROGRESS);
p = t->rootintr->ux_buf;
p[0] = 2;
t->rootintr->ux_actlen = 1;
Index: src/sys/dev/usb/ehci.c
diff -u src/sys/dev/usb/ehci.c:1.272 src/sys/dev/usb/ehci.c:1.273
--- src/sys/dev/usb/ehci.c:1.272 Wed Feb 12 16:02:01 2020
+++ src/sys/dev/usb/ehci.c Sat Feb 15 01:21:56 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ehci.c,v 1.272 2020/02/12 16:02:01 riastradh Exp $ */
+/* $NetBSD: ehci.c,v 1.273 2020/02/15 01:21:56 riastradh Exp $ */
/*
* Copyright (c) 2004-2012 The NetBSD Foundation, Inc.
@@ -53,7 +53,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.272 2020/02/12 16:02:01 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.273 2020/02/15 01:21:56 riastradh Exp $");
#include "ohci.h"
#include "uhci.h"
@@ -785,6 +785,7 @@ ehci_pcd(void *addr)
/* Just ignore the change. */
goto done;
}
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
p = xfer->ux_buf;
m = uimin(sc->sc_noport, xfer->ux_length * 8 - 1);
@@ -2724,11 +2725,11 @@ ehci_root_intr_start(struct usbd_xfer *x
mutex_enter(&sc->sc_lock);
KASSERT(sc->sc_intrxfer == NULL);
sc->sc_intrxfer = xfer;
+ xfer->ux_status = USBD_IN_PROGRESS;
if (!polling)
mutex_exit(&sc->sc_lock);
- xfer->ux_status = USBD_IN_PROGRESS;
- return xfer->ux_status;
+ return USBD_IN_PROGRESS;
}
/* Abort a root interrupt request. */
Index: src/sys/dev/usb/motg.c
diff -u src/sys/dev/usb/motg.c:1.26 src/sys/dev/usb/motg.c:1.27
--- src/sys/dev/usb/motg.c:1.26 Wed Feb 12 16:01:00 2020
+++ src/sys/dev/usb/motg.c Sat Feb 15 01:21:56 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: motg.c,v 1.26 2020/02/12 16:01:00 riastradh Exp $ */
+/* $NetBSD: motg.c,v 1.27 2020/02/15 01:21:56 riastradh Exp $ */
/*
* Copyright (c) 1998, 2004, 2011, 2012, 2014 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.26 2020/02/12 16:01:00 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.27 2020/02/15 01:21:56 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -991,8 +991,16 @@ motg_root_intr_abort(struct usbd_xfer *x
KASSERT(mutex_owned(&sc->sc_lock));
KASSERT(xfer->ux_pipe->up_intrxfer == xfer);
- sc->sc_intr_xfer = NULL;
+ /* If xfer has already completed, nothing to do here. */
+ if (sc->sc_intr_xfer == NULL)
+ return;
+ /*
+ * Otherwise, sc->sc_intr_xfer had better be this transfer.
+ * Cancel it.
+ */
+ KASSERT(sc->sc_intr_xfer == xfer);
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
xfer->ux_status = USBD_CANCELLED;
usb_transfer_complete(xfer);
}
@@ -1032,7 +1040,14 @@ motg_root_intr_start(struct usbd_xfer *x
if (sc->sc_dying)
return USBD_IOERROR;
+ if (!polling)
+ mutex_enter(&sc->sc_lock);
+ KASSERT(sc->sc_intr_xfer == NULL);
sc->sc_intr_xfer = xfer;
+ xfer->ux_status = USBD_IN_PROGRESS;
+ if (!polling)
+ mutex_exit(&sc->sc_lock);
+
return USBD_IN_PROGRESS;
}
@@ -1045,12 +1060,25 @@ motg_root_intr_close(struct usbd_pipe *p
KASSERT(mutex_owned(&sc->sc_lock));
- sc->sc_intr_xfer = NULL;
+ /*
+ * Caller must guarantee the xfer has completed first, by
+ * closing the pipe only after normal completion or an abort.
+ */
+ KASSERT(sc->sc_intr_xfer == NULL);
}
void
motg_root_intr_done(struct usbd_xfer *xfer)
{
+ struct motg_softc *sc = MOTG_PIPE2SC(pipe);
+ MOTGHIST_FUNC(); MOTGHIST_CALLED();
+
+ KASSERT(mutex_owned(&sc->sc_lock));
+
+ /* Claim the xfer so it doesn't get completed again. */
+ KASSERT(sc->sc_intr_xfer == xfer);
+ KASSERT(xfer->ux_status != USBD_IN_PROGRESS);
+ sc->sc_intr_xfer = NULL;
}
void
@@ -1101,6 +1129,7 @@ motg_hub_change(struct motg_softc *sc)
if (xfer == NULL)
return; /* the interrupt pipe is not open */
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
pipe = xfer->ux_pipe;
if (pipe->up_dev == NULL || pipe->up_dev->ud_bus == NULL)
Index: src/sys/dev/usb/ohci.c
diff -u src/sys/dev/usb/ohci.c:1.294 src/sys/dev/usb/ohci.c:1.295
--- src/sys/dev/usb/ohci.c:1.294 Wed Feb 12 16:02:01 2020
+++ src/sys/dev/usb/ohci.c Sat Feb 15 01:21:56 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ohci.c,v 1.294 2020/02/12 16:02:01 riastradh Exp $ */
+/* $NetBSD: ohci.c,v 1.295 2020/02/15 01:21:56 riastradh Exp $ */
/*
* Copyright (c) 1998, 2004, 2005, 2012 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.294 2020/02/12 16:02:01 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.295 2020/02/15 01:21:56 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -1698,6 +1698,8 @@ ohci_rhsc(ohci_softc_t *sc, struct usbd_
/* Just ignore the change. */
return;
}
+ KASSERT(xfer == sc->sc_intrxfer);
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
p = xfer->ux_buf;
m = uimin(sc->sc_noport, xfer->ux_length * 8 - 1);
@@ -2516,11 +2518,11 @@ ohci_root_intr_start(struct usbd_xfer *x
mutex_enter(&sc->sc_lock);
KASSERT(sc->sc_intrxfer == NULL);
sc->sc_intrxfer = xfer;
+ xfer->ux_status = USBD_IN_PROGRESS;
if (!polling)
mutex_exit(&sc->sc_lock);
- xfer->ux_status = USBD_IN_PROGRESS;
- return xfer->ux_status;
+ return USBD_IN_PROGRESS;
}
/* Abort a root interrupt request. */
Index: src/sys/dev/usb/uhci.c
diff -u src/sys/dev/usb/uhci.c:1.292 src/sys/dev/usb/uhci.c:1.293
--- src/sys/dev/usb/uhci.c:1.292 Fri Feb 14 16:47:28 2020
+++ src/sys/dev/usb/uhci.c Sat Feb 15 01:21:56 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: uhci.c,v 1.292 2020/02/14 16:47:28 riastradh Exp $ */
+/* $NetBSD: uhci.c,v 1.293 2020/02/15 01:21:56 riastradh Exp $ */
/*
* Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.292 2020/02/14 16:47:28 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.293 2020/02/15 01:21:56 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -1013,6 +1013,7 @@ uhci_poll_hub(void *addr)
xfer = sc->sc_intr_xfer;
if (xfer == NULL)
goto out;
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
/*
* If the intr xfer for which we were scheduled is done, and
@@ -3905,12 +3906,12 @@ uhci_root_intr_start(struct usbd_xfer *x
sc->sc_ival = mstohz(ival);
callout_schedule(&sc->sc_poll_handle, sc->sc_ival);
sc->sc_intr_xfer = xfer;
+ xfer->ux_status = USBD_IN_PROGRESS;
if (!polling)
mutex_exit(&sc->sc_lock);
- xfer->ux_status = USBD_IN_PROGRESS;
- return xfer->ux_status;
+ return USBD_IN_PROGRESS;
}
/* Close the root interrupt pipe. */
Index: src/sys/dev/usb/vhci.c
diff -u src/sys/dev/usb/vhci.c:1.5 src/sys/dev/usb/vhci.c:1.6
--- src/sys/dev/usb/vhci.c:1.5 Wed Feb 12 16:02:01 2020
+++ src/sys/dev/usb/vhci.c Sat Feb 15 01:21:56 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: vhci.c,v 1.5 2020/02/12 16:02:01 riastradh Exp $ */
+/* $NetBSD: vhci.c,v 1.6 2020/02/15 01:21:56 riastradh Exp $ */
/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vhci.c,v 1.5 2020/02/12 16:02:01 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vhci.c,v 1.6 2020/02/15 01:21:56 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -629,6 +629,7 @@ vhci_root_intr_start(struct usbd_xfer *x
mutex_enter(&sc->sc_lock);
KASSERT(sc->sc_intrxfer == NULL);
sc->sc_intrxfer = xfer;
+ xfer->ux_status = USBD_IN_PROGRESS;
if (!polling)
mutex_exit(&sc->sc_lock);
@@ -654,6 +655,7 @@ vhci_root_intr_abort(struct usbd_xfer *x
* Cancel it.
*/
KASSERT(sc->sc_intrxfer == xfer);
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
xfer->ux_status = USBD_CANCELLED;
usb_transfer_complete(xfer);
}
@@ -748,6 +750,7 @@ vhci_usb_attach(vhci_fd_t *vfd, struct v
ret = ENOBUFS;
goto done;
}
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
p = xfer->ux_buf;
memset(p, 0, xfer->ux_length);
@@ -823,6 +826,7 @@ vhci_usb_detach(vhci_fd_t *vfd, struct v
mutex_exit(&sc->sc_lock);
return ENOBUFS;
}
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
mutex_enter(&port->lock);
Index: src/sys/dev/usb/xhci.c
diff -u src/sys/dev/usb/xhci.c:1.117 src/sys/dev/usb/xhci.c:1.118
--- src/sys/dev/usb/xhci.c:1.117 Wed Feb 12 16:02:01 2020
+++ src/sys/dev/usb/xhci.c Sat Feb 15 01:21:56 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xhci.c,v 1.117 2020/02/12 16:02:01 riastradh Exp $ */
+/* $NetBSD: xhci.c,v 1.118 2020/02/15 01:21:56 riastradh Exp $ */
/*
* Copyright (c) 2013 Jonathan A. Kollasch
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.117 2020/02/12 16:02:01 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.118 2020/02/15 01:21:56 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -1879,6 +1879,7 @@ xhci_rhpsc(struct xhci_softc * const sc,
if (xfer == NULL)
return;
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
uint8_t *p = xfer->ux_buf;
memset(p, 0, xfer->ux_length);
@@ -3717,6 +3718,7 @@ xhci_root_intr_start(struct usbd_xfer *x
mutex_enter(&sc->sc_lock);
KASSERT(sc->sc_intrxfer[bn] == NULL);
sc->sc_intrxfer[bn] = xfer;
+ xfer->ux_status = USBD_IN_PROGRESS;
if (!polling)
mutex_exit(&sc->sc_lock);
Index: src/sys/external/bsd/dwc2/dwc2.c
diff -u src/sys/external/bsd/dwc2/dwc2.c:1.68 src/sys/external/bsd/dwc2/dwc2.c:1.69
--- src/sys/external/bsd/dwc2/dwc2.c:1.68 Wed Feb 12 16:02:01 2020
+++ src/sys/external/bsd/dwc2/dwc2.c Sat Feb 15 01:21:56 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: dwc2.c,v 1.68 2020/02/12 16:02:01 riastradh Exp $ */
+/* $NetBSD: dwc2.c,v 1.69 2020/02/15 01:21:56 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.68 2020/02/12 16:02:01 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.69 2020/02/15 01:21:56 riastradh Exp $");
#include "opt_usb.h"
@@ -301,6 +301,8 @@ dwc2_rhc(void *addr)
return;
}
+ KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
+
/* set port bit */
p = KERNADDR(&xfer->ux_dmabuf, 0);
@@ -646,11 +648,11 @@ dwc2_root_intr_start(struct usbd_xfer *x
mutex_enter(&sc->sc_lock);
KASSERT(sc->sc_intrxfer == NULL);
sc->sc_intrxfer = xfer;
+ xfer->ux_status = USBD_IN_PROGRESS;
if (!polling)
mutex_exit(&sc->sc_lock);
- xfer->ux_status = USBD_IN_PROGRESS;
- return xfer->ux_status;
+ return USBD_IN_PROGRESS;
}
/* Abort a root interrupt request. */