Module Name:    src
Committed By:   mrg
Date:           Thu May  9 02:43:35 UTC 2019

Modified Files:
        src/sys/dev/usb: u3g.c uark.c ubsa.c ubsa_common.c ubsavar.h uchcom.c
            ucom.c ucomvar.h uftdi.c ugensa.c uhmodem.c uipaq.c ukyopon.c
            umcs.c umct.c umodem.c umodem_common.c umodemvar.h uplcom.c uslsa.c
            uvisor.c uvscom.c

Log Message:
clean up ucom parents some more:
- it's always "bool sc_dying" now, with true/false
- heavy use of static functions
- remove all ucom parent ca_activate callbacks.  they're never called.
- callbacks should generally do little to nothing if sc_dying is set
- open resources should be released in detach after setting sc_dying
- don't complain about usbd_abort_pipe() or usbd_close_pipe() failure
- when releasing resources, zero the softc member as well
- remove ucom_methods members no longer destined to be filled in
- generally, DPRINTF() before sc_dying short circuit
- use EIO when dying, not ENXIO or 0
- add some ucom_open() callbacks that simply return EIO if dying


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/sys/dev/usb/u3g.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/usb/uark.c
cvs rdiff -u -r1.37 -r1.38 src/sys/dev/usb/ubsa.c
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/usb/ubsa_common.c \
    src/sys/dev/usb/umodemvar.h
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/usb/ubsavar.h
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/usb/uchcom.c
cvs rdiff -u -r1.124 -r1.125 src/sys/dev/usb/ucom.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/usb/ucomvar.h
cvs rdiff -u -r1.69 -r1.70 src/sys/dev/usb/uftdi.c
cvs rdiff -u -r1.38 -r1.39 src/sys/dev/usb/ugensa.c src/sys/dev/usb/umct.c
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/usb/uhmodem.c
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/usb/uipaq.c
cvs rdiff -u -r1.23 -r1.24 src/sys/dev/usb/ukyopon.c
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/usb/umcs.c
cvs rdiff -u -r1.71 -r1.72 src/sys/dev/usb/umodem.c
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/usb/umodem_common.c
cvs rdiff -u -r1.83 -r1.84 src/sys/dev/usb/uplcom.c
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/usb/uslsa.c
cvs rdiff -u -r1.50 -r1.51 src/sys/dev/usb/uvisor.c
cvs rdiff -u -r1.34 -r1.35 src/sys/dev/usb/uvscom.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/dev/usb/u3g.c
diff -u src/sys/dev/usb/u3g.c:1.36 src/sys/dev/usb/u3g.c:1.37
--- src/sys/dev/usb/u3g.c:1.36	Sat May  4 08:04:13 2019
+++ src/sys/dev/usb/u3g.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: u3g.c,v 1.36 2019/05/04 08:04:13 mrg Exp $	*/
+/*	$NetBSD: u3g.c,v 1.37 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: u3g.c,v 1.36 2019/05/04 08:04:13 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: u3g.c,v 1.37 2019/05/09 02:43:35 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -148,11 +148,10 @@ struct u3g_softc {
 static int u3g_match(device_t, cfdata_t, void *);
 static void u3g_attach(device_t, device_t, void *);
 static int u3g_detach(device_t, int);
-static int u3g_activate(device_t, enum devact);
 static void u3g_childdet(device_t, device_t);
 
 CFATTACH_DECL2_NEW(u3g, sizeof(struct u3g_softc), u3g_match,
-    u3g_attach, u3g_detach, u3g_activate, NULL, u3g_childdet);
+    u3g_attach, u3g_detach, NULL, NULL, u3g_childdet);
 
 
 static void u3g_intr(struct usbd_xfer *, void *, usbd_status);
@@ -348,7 +347,6 @@ u3g_attach(device_t parent, device_t sel
 	ucaa.ucaa_portno = -1;
 	ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1;
 
-
 	sc->sc_ifaceno = uiaa->uiaa_ifaceno;
 	intr_address = -1;
 	intr_size = 0;
@@ -431,25 +429,13 @@ static int
 u3g_detach(device_t self, int flags)
 {
 	struct u3g_softc *sc = device_private(self);
-	int rv;
-
-	if (sc->sc_dying)
-		return 0;
-
-	pmf_device_deregister(self);
+	int rv = 0;
 
-	for (size_t i = 0; i < sc->sc_ncom; i++)
-		if (sc->sc_com[i].c_dev != NULL) {
-			rv = config_detach(sc->sc_com[i].c_dev, flags);
-			if (rv != 0) {
-				aprint_verbose_dev(self, "Can't deallocate "
-				    "port (%d)", rv);
-			}
-		}
+	sc->sc_dying = true;
 
 	if (sc->sc_intr_pipe != NULL) {
-		(void) usbd_abort_pipe(sc->sc_intr_pipe);
-		(void) usbd_close_pipe(sc->sc_intr_pipe);
+		usbd_abort_pipe(sc->sc_intr_pipe);
+		usbd_close_pipe(sc->sc_intr_pipe);
 		sc->sc_intr_pipe = NULL;
 	}
 	if (sc->sc_intr_buff != NULL) {
@@ -457,7 +443,22 @@ u3g_detach(device_t self, int flags)
 		sc->sc_intr_buff = NULL;
 	}
 
-	return 0;
+	for (size_t i = 0; i < sc->sc_ncom; i++)
+		if (sc->sc_com[i].c_dev != NULL) {
+			int port_rv;
+
+			port_rv = config_detach(sc->sc_com[i].c_dev, flags);
+			if (port_rv != 0) {
+				aprint_verbose_dev(self, "Can't deallocate "
+				    "port (%d)", port_rv);
+			}
+			rv |= port_rv;
+			sc->sc_com[i].c_dev = NULL;
+		}
+
+	pmf_device_deregister(self);
+
+	return rv;
 }
 
 static void
@@ -470,29 +471,6 @@ u3g_childdet(device_t self, device_t chi
 			    sc->sc_com[i].c_dev = NULL;
 }
 
-static int
-u3g_activate(device_t self, enum devact act)
-{
-	struct u3g_softc *sc = device_private(self);
-	int rv = 0;
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		for (size_t i = 0; i < sc->sc_ncom; i++)
-			if (sc->sc_com[i].c_dev != NULL &&
-			    config_deactivate(sc->sc_com[i].c_dev) && rv == 0)
-			rv = -1;
-		else
-			rv = 0;
-		break;
-
-	default:
-		break;
-	}
-
-	return rv;
-}
-
 static void
 u3g_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
 {
@@ -602,7 +580,7 @@ u3g_open(void *arg, int portno)
 	int i, nin;
 
 	if (sc->sc_dying)
-		return 0;
+ 		return EIO;
 
 	err = usbd_device2interface_handle(sc->sc_udev, sc->sc_ifaceno, &ih);
 	if (err)

Index: src/sys/dev/usb/uark.c
diff -u src/sys/dev/usb/uark.c:1.14 src/sys/dev/usb/uark.c:1.15
--- src/sys/dev/usb/uark.c:1.14	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/uark.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uark.c,v 1.14 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: uark.c,v 1.15 2019/05/09 02:43:35 mrg Exp $	*/
 /*	$OpenBSD: uark.c,v 1.13 2009/10/13 19:33:17 pirofti Exp $	*/
 
 /*
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uark.c,v 1.14 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uark.c,v 1.15 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -75,34 +75,35 @@ struct uark_softc {
 	u_char			sc_msr;
 	u_char			sc_lsr;
 
-	u_char			sc_dying;
+	bool			sc_dying;
 };
 
-void	uark_get_status(void *, int portno, u_char *lsr, u_char *msr);
-void	uark_set(void *, int, int, int);
-int	uark_param(void *, int, struct termios *);
-void	uark_break(void *, int, int);
-int	uark_cmd(struct uark_softc *, uint16_t, uint16_t);
+static void	uark_get_status(void *, int portno, u_char *lsr, u_char *msr);
+static void	uark_set(void *, int, int, int);
+static int	uark_param(void *, int, struct termios *);
+static int	uark_open(void *, int);
+static void	uark_break(void *, int, int);
+static int	uark_cmd(struct uark_softc *, uint16_t, uint16_t);
 
 struct ucom_methods uark_methods = {
 	.ucom_get_status = uark_get_status,
 	.ucom_set = uark_set,
 	.ucom_param = uark_param,
+	.ucom_open = uark_open,
 };
 
 static const struct usb_devno uark_devs[] = {
 	{ USB_VENDOR_ARKMICROCHIPS, USB_PRODUCT_ARKMICROCHIPS_USBSERIAL },
 };
 
-int             uark_match(device_t, cfdata_t, void *);
-void            uark_attach(device_t, device_t, void *);
-int             uark_detach(device_t, int);
-int             uark_activate(device_t, enum devact);
+static int	uark_match(device_t, cfdata_t, void *);
+static void	uark_attach(device_t, device_t, void *);
+static int	uark_detach(device_t, int);
 
 CFATTACH_DECL_NEW(uark, sizeof(struct uark_softc), uark_match, uark_attach,
-    uark_detach, uark_activate);
+    uark_detach, NULL);
 
-int
+static int
 uark_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct usb_attach_arg *uaa = aux;
@@ -111,7 +112,7 @@ uark_match(device_t parent, cfdata_t mat
 	    != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
 }
 
-void
+static void
 uark_attach(device_t parent, device_t self, void *aux)
 {
 	struct uark_softc *sc = device_private(self);
@@ -134,10 +135,11 @@ uark_attach(device_t parent, device_t se
 	usbd_devinfo_free(devinfop);
 
 	sc->sc_udev = dev;
+	sc->sc_dying = false;
 
 	if (usbd_set_config_index(sc->sc_udev, UARK_CONFIG_NO, 1) != 0) {
 		aprint_error_dev(self, "could not set configuration no\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -146,7 +148,7 @@ uark_attach(device_t parent, device_t se
 	    &sc->sc_iface);
 	if (error != 0) {
 		aprint_error_dev(self, "could not get interface handle\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -158,7 +160,7 @@ uark_attach(device_t parent, device_t se
 		if (ed == NULL) {
 			aprint_error_dev(self,
 			    "no endpoint descriptor found for %d\n", i);
-			sc->sc_dying = 1;
+			sc->sc_dying = true;
 			return;
 		}
 
@@ -172,7 +174,7 @@ uark_attach(device_t parent, device_t se
 
 	if (ucaa.ucaa_bulkin == -1 || ucaa.ucaa_bulkout == -1) {
 		aprint_error_dev(self, "missing endpoint\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -194,13 +196,14 @@ uark_attach(device_t parent, device_t se
 	return;
 }
 
-int
+static int
 uark_detach(device_t self, int flags)
 {
 	struct uark_softc *sc = device_private(self);
 	int rv = 0;
 
-	sc->sc_dying = 1;
+	sc->sc_dying = true;
+
 	if (sc->sc_subdev != NULL) {
 		rv = config_detach(sc->sc_subdev, flags);
 		sc->sc_subdev = NULL;
@@ -211,27 +214,14 @@ uark_detach(device_t self, int flags)
 	return rv;
 }
 
-int
-uark_activate(device_t self, enum devact act)
-{
-	struct uark_softc *sc = device_private(self);
-	int rv = 0;
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		if (sc->sc_subdev != NULL)
-			rv = config_deactivate(sc->sc_subdev);
-		sc->sc_dying = 1;
-		break;
-	}
-	return rv;
-}
-
-void
+static void
 uark_set(void *vsc, int portno, int reg, int onoff)
 {
 	struct uark_softc *sc = vsc;
 
+	if (sc->sc_dying)
+		return;
+
 	switch (reg) {
 	case UCOM_SET_BREAK:
 		uark_break(sc, portno, onoff);
@@ -243,12 +233,15 @@ uark_set(void *vsc, int portno, int reg,
 	}
 }
 
-int
+static int
 uark_param(void *vsc, int portno, struct termios *t)
 {
 	struct uark_softc *sc = (struct uark_softc *)vsc;
 	int data;
 
+	if (sc->sc_dying)
+		return EIO;
+
 	switch (t->c_ospeed) {
 	case 300:
 	case 600:
@@ -303,7 +296,7 @@ uark_param(void *vsc, int portno, struct
 
 #if 0
 	/* XXX flow control */
-	if (ISSET(t->c_cflag, CRTSCTS))
+	if (ISSET(t->c_cflag, CRTSCTS)) {
 		/*  rts/cts flow ctl */
 	} else if (ISSET(t->c_iflag, IXON|IXOFF)) {
 		/*  xon/xoff flow ctl */
@@ -315,21 +308,38 @@ uark_param(void *vsc, int portno, struct
 	return 0;
 }
 
-void
+static int
+uark_open(void *arg, int portno)
+{
+	struct uark_softc *sc = arg;
+
+	if (sc->sc_dying)
+		return EIO;
+
+	return 0;
+}
+
+static void
 uark_get_status(void *vsc, int portno, u_char *lsr, u_char *msr)
 {
 	struct uark_softc *sc = vsc;
 
+	if (sc->sc_dying)
+		return;
+
 	*msr = sc->sc_msr;
 	*lsr = sc->sc_lsr;
 }
 
-void
+static void
 uark_break(void *vsc, int portno, int onoff)
 {
 #if 0
 	struct uark_softc *sc = vsc;
 
+	if (sc->sc_dying)
+		return;
+
 #ifdef UARK_DEBUG
 	aprint_normal_dev(sc->sc_dev, "break %s!\n", onoff ? "on" : "off");
 #endif
@@ -342,7 +352,7 @@ uark_break(void *vsc, int portno, int on
 #endif
 }
 
-int
+static int
 uark_cmd(struct uark_softc *sc, uint16_t index, uint16_t value)
 {
 	usb_device_request_t req;

Index: src/sys/dev/usb/ubsa.c
diff -u src/sys/dev/usb/ubsa.c:1.37 src/sys/dev/usb/ubsa.c:1.38
--- src/sys/dev/usb/ubsa.c:1.37	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/ubsa.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,5 @@
-/*	$NetBSD: ubsa.c,v 1.37 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: ubsa.c,v 1.38 2019/05/09 02:43:35 mrg Exp $	*/
+
 /*-
  * Copyright (c) 2002, Alexander Kabaev <kan.FreeBSD.org>.
  * All rights reserved.
@@ -54,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ubsa.c,v 1.37 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ubsa.c,v 1.38 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -130,12 +131,9 @@ int ubsa_match(device_t, cfdata_t, void 
 void ubsa_attach(device_t, device_t, void *);
 void ubsa_childdet(device_t, device_t);
 int ubsa_detach(device_t, int);
-int ubsa_activate(device_t, enum devact);
-
-
 
 CFATTACH_DECL2_NEW(ubsa, sizeof(struct ubsa_softc),
-    ubsa_match, ubsa_attach, ubsa_detach, ubsa_activate, NULL, ubsa_childdet);
+    ubsa_match, ubsa_attach, ubsa_detach, NULL, NULL, ubsa_childdet);
 
 int
 ubsa_match(device_t parent, cfdata_t match, void *aux)
@@ -161,6 +159,7 @@ ubsa_attach(device_t parent, device_t se
 	int i;
 
 	sc->sc_dev = self;
+	sc->sc_dying = false;
 
 	aprint_naive("\n");
 	aprint_normal("\n");
@@ -202,7 +201,6 @@ ubsa_attach(device_t parent, device_t se
 		aprint_error_dev(self,
 		    "failed to set configuration: %s\n",
 		    usbd_errstr(err));
-		sc->sc_dying = 1;
 		goto error;
 	}
 
@@ -212,7 +210,6 @@ ubsa_attach(device_t parent, device_t se
 	if (cdesc == NULL) {
 		aprint_error_dev(self,
 		    "failed to get configuration descriptor\n");
-		sc->sc_dying = 1;
 		goto error;
 	}
 
@@ -224,7 +221,6 @@ ubsa_attach(device_t parent, device_t se
 			 &sc->sc_iface[0]);
 	if (err) {
 		/* can not get main interface */
-		sc->sc_dying = 1;
 		goto error;
 	}
 
@@ -260,19 +256,16 @@ ubsa_attach(device_t parent, device_t se
 
 	if (sc->sc_intr_number == -1) {
 		aprint_error_dev(self, "Could not find interrupt in\n");
-		sc->sc_dying = 1;
 		goto error;
 	}
 
 	if (ucaa.ucaa_bulkin == -1) {
 		aprint_error_dev(self, "Could not find data bulk in\n");
-		sc->sc_dying = 1;
 		goto error;
 	}
 
 	if (ucaa.ucaa_bulkout == -1) {
 		aprint_error_dev(self, "Could not find data bulk out\n");
-		sc->sc_dying = 1;
 		goto error;
 	}
 
@@ -295,6 +288,7 @@ ubsa_attach(device_t parent, device_t se
 	return;
 
 error:
+	sc->sc_dying = true;
 	return;
 }
 
@@ -320,37 +314,20 @@ ubsa_detach(device_t self, int flags)
 	int i;
 	int rv = 0;
 
-
 	DPRINTF(("ubsa_detach: sc = %p\n", sc));
 
-	if (sc->sc_intr_pipe != NULL) {
-		usbd_abort_pipe(sc->sc_intr_pipe);
-		usbd_close_pipe(sc->sc_intr_pipe);
-		kmem_free(sc->sc_intr_buf, sc->sc_isize);
-		sc->sc_intr_pipe = NULL;
-	}
+	sc->sc_dying = true;
+
+	ubsa_close_pipe(sc);
 
-	sc->sc_dying = 1;
 	for (i = 0; i < sc->sc_numif; i++) {
-		if (sc->sc_subdevs[i] != NULL)
+		if (sc->sc_subdevs[i] != NULL) {
 			rv |= config_detach(sc->sc_subdevs[i], flags);
+			sc->sc_subdevs[i] = NULL;
+		}
 	}
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
 
 	return rv;
 }
-
-int
-ubsa_activate(device_t self, enum devact act)
-{
-	struct ubsa_softc *sc = device_private(self);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}

Index: src/sys/dev/usb/ubsa_common.c
diff -u src/sys/dev/usb/ubsa_common.c:1.11 src/sys/dev/usb/ubsa_common.c:1.12
--- src/sys/dev/usb/ubsa_common.c:1.11	Sat May  4 08:04:13 2019
+++ src/sys/dev/usb/ubsa_common.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ubsa_common.c,v 1.11 2019/05/04 08:04:13 mrg Exp $	*/
+/*	$NetBSD: ubsa_common.c,v 1.12 2019/05/09 02:43:35 mrg Exp $	*/
 /*-
  * Copyright (c) 2002, Alexander Kabaev <kan.FreeBSD.org>.
  * All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ubsa_common.c,v 1.11 2019/05/04 08:04:13 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ubsa_common.c,v 1.12 2019/05/09 02:43:35 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -182,15 +182,20 @@ ubsa_break(struct ubsa_softc *sc, int po
 {
 	DPRINTF(("ubsa_rts: onoff = %d\n", onoff));
 
+	if (sc->sc_dying) 
+		return;
+
 	ubsa_request(sc, portno, UBSA_SET_BREAK, onoff ? 1 : 0);
 }
 
 void
 ubsa_set(void *addr, int portno, int reg, int onoff)
 {
-	struct ubsa_softc *sc;
+	struct ubsa_softc *sc = addr;
+
+	if (sc->sc_dying)
+		return;
 
-	sc = addr;
 	switch (reg) {
 	case UCOM_SET_DTR:
 		if (sc->sc_quadumts)
@@ -322,6 +327,9 @@ ubsa_param(void *addr, int portno, struc
 {
 	struct ubsa_softc *sc = addr;
 
+	if (sc->sc_dying)
+		return EIO;
+
 	DPRINTF(("ubsa_param: sc = %p\n", sc));
 
 	if (!sc->sc_quadumts) {
@@ -342,7 +350,7 @@ ubsa_open(void *addr, int portno)
 	int err;
 
 	if (sc->sc_dying)
-		return ENXIO;
+		return EIO;
 
 	if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
 		sc->sc_intr_buf = kmem_alloc(sc->sc_isize, KM_SLEEP);
@@ -369,30 +377,31 @@ ubsa_open(void *addr, int portno)
 }
 
 void
+ubsa_close_pipe(struct ubsa_softc *sc)
+{
+
+	if (sc->sc_intr_pipe != NULL) {
+		usbd_abort_pipe(sc->sc_intr_pipe);
+		usbd_close_pipe(sc->sc_intr_pipe);
+		sc->sc_intr_pipe = NULL;
+	}
+	if (sc->sc_intr_buf) {
+		kmem_free(sc->sc_intr_buf, sc->sc_isize);
+		sc->sc_intr_buf = NULL;
+	}
+}
+
+void
 ubsa_close(void *addr, int portno)
 {
 	struct ubsa_softc *sc = addr;
-	int err;
+
+	DPRINTF(("ubsa_close: close\n"));
 
 	if (sc->sc_dying)
 		return;
 
-	DPRINTF(("ubsa_close: close\n"));
-
-	if (sc->sc_intr_pipe != NULL) {
-		err = usbd_abort_pipe(sc->sc_intr_pipe);
-		if (err)
-			printf("%s: abort interrupt pipe failed: %s\n",
-			    device_xname(sc->sc_dev),
-			    usbd_errstr(err));
-		err = usbd_close_pipe(sc->sc_intr_pipe);
-		if (err)
-			printf("%s: close interrupt pipe failed: %s\n",
-			    device_xname(sc->sc_dev),
-			    usbd_errstr(err));
-		kmem_free(sc->sc_intr_buf, sc->sc_isize);
-		sc->sc_intr_pipe = NULL;
-	}
+	ubsa_close_pipe(sc);
 }
 
 void
Index: src/sys/dev/usb/umodemvar.h
diff -u src/sys/dev/usb/umodemvar.h:1.11 src/sys/dev/usb/umodemvar.h:1.12
--- src/sys/dev/usb/umodemvar.h:1.11	Mon May  6 23:47:39 2019
+++ src/sys/dev/usb/umodemvar.h	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: umodemvar.h,v 1.11 2019/05/06 23:47:39 mrg Exp $	*/
+/*	$NetBSD: umodemvar.h,v 1.12 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -73,5 +73,4 @@ int	umodem_param(void *, int, struct ter
 int	umodem_ioctl(void *, int, u_long, void *, int, proc_t *);
 int	umodem_open(void *, int);
 void	umodem_close(void *, int);
-int	umodem_common_activate(struct umodem_softc *, enum devact);
 int	umodem_common_detach(struct umodem_softc *, int);

Index: src/sys/dev/usb/ubsavar.h
diff -u src/sys/dev/usb/ubsavar.h:1.10 src/sys/dev/usb/ubsavar.h:1.11
--- src/sys/dev/usb/ubsavar.h:1.10	Sat Apr 23 10:15:32 2016
+++ src/sys/dev/usb/ubsavar.h	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ubsavar.h,v 1.10 2016/04/23 10:15:32 skrll Exp $	*/
+/*	$NetBSD: ubsavar.h,v 1.11 2019/05/09 02:43:35 mrg Exp $	*/
 /*-
  * Copyright (c) 2002, Alexander Kabaev <kan.FreeBSD.org>.
  * All rights reserved.
@@ -133,7 +133,7 @@ struct	ubsa_softc {
 	device_t		sc_subdevs[UBSA_MAXCONN]; /* ucom device */
 	int			sc_numif;	/* number of interfaces */
 
-	u_char			sc_dying;	/* disconnecting */
+	bool			sc_dying;	/* disconnecting */
 	u_char			sc_quadumts;
 	uint16_t		sc_devflags;
 };
@@ -146,6 +146,7 @@ void ubsa_set(void *, int, int, int);
 int  ubsa_param(void *, int, struct termios *);
 int  ubsa_open(void *, int);
 void ubsa_close(void *, int);
+void ubsa_close_pipe(struct ubsa_softc *);
 
 void ubsa_break(struct ubsa_softc *, int, int);
 int  ubsa_request(struct ubsa_softc *, int, uint8_t, uint16_t);

Index: src/sys/dev/usb/uchcom.c
diff -u src/sys/dev/usb/uchcom.c:1.32 src/sys/dev/usb/uchcom.c:1.33
--- src/sys/dev/usb/uchcom.c:1.32	Mon May  6 23:46:25 2019
+++ src/sys/dev/usb/uchcom.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uchcom.c,v 1.32 2019/05/06 23:46:25 mrg Exp $	*/
+/*	$NetBSD: uchcom.c,v 1.33 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.32 2019/05/06 23:46:25 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.33 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -193,20 +193,17 @@ struct	ucom_methods uchcom_methods = {
 	.ucom_close		= uchcom_close,
 };
 
-int uchcom_match(device_t, cfdata_t, void *);
-void uchcom_attach(device_t, device_t, void *);
-void uchcom_childdet(device_t, device_t);
-int uchcom_detach(device_t, int);
-int uchcom_activate(device_t, enum devact);
-
-
+static int	uchcom_match(device_t, cfdata_t, void *);
+static void	uchcom_attach(device_t, device_t, void *);
+static void	uchcom_childdet(device_t, device_t);
+static int	uchcom_detach(device_t, int);
 
 CFATTACH_DECL2_NEW(uchcom,
     sizeof(struct uchcom_softc),
     uchcom_match,
     uchcom_attach,
     uchcom_detach,
-    uchcom_activate,
+    NULL,
     NULL,
     uchcom_childdet);
 
@@ -214,7 +211,7 @@ CFATTACH_DECL2_NEW(uchcom,
  * driver entry points
  */
 
-int
+static int
 uchcom_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct usb_attach_arg *uaa = aux;
@@ -223,7 +220,7 @@ uchcom_match(device_t parent, cfdata_t m
 		UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
 }
 
-void
+static void
 uchcom_attach(device_t parent, device_t self, void *aux)
 {
 	struct uchcom_softc *sc = device_private(self);
@@ -241,7 +238,7 @@ uchcom_attach(device_t parent, device_t 
 	usbd_devinfo_free(devinfop);
 
 	sc->sc_dev = self;
-        sc->sc_udev = dev;
+	sc->sc_udev = dev;
 	sc->sc_dying = false;
 	sc->sc_dtr = sc->sc_rts = -1;
 	sc->sc_lsr = sc->sc_msr = 0;
@@ -286,7 +283,7 @@ failed:
 	return;
 }
 
-void
+static void
 uchcom_childdet(device_t self, device_t child)
 {
 	struct uchcom_softc *sc = device_private(self);
@@ -295,7 +292,7 @@ uchcom_childdet(device_t self, device_t 
 	sc->sc_subdev = NULL;
 }
 
-int
+static int
 uchcom_detach(device_t self, int flags)
 {
 	struct uchcom_softc *sc = device_private(self);
@@ -307,29 +304,16 @@ uchcom_detach(device_t self, int flags)
 
 	sc->sc_dying = true;
 
-	if (sc->sc_subdev != NULL)
+	if (sc->sc_subdev != NULL) {
 		rv = config_detach(sc->sc_subdev, flags);
+		sc->sc_subdev = NULL;
+	}
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
 
 	return rv;
 }
 
-int
-uchcom_activate(device_t self, enum devact act)
-{
-	struct uchcom_softc *sc = device_private(self);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		close_intr_pipe(sc);
-		sc->sc_dying = true;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
 static int
 set_config(struct uchcom_softc *sc)
 {
@@ -903,7 +887,7 @@ uchcom_param(void *arg, int portno, stru
 	int ret;
 
 	if (sc->sc_dying)
-		return 0;
+		return EIO;
 
 	ret = set_line_control(sc, t->c_cflag);
 	if (ret)

Index: src/sys/dev/usb/ucom.c
diff -u src/sys/dev/usb/ucom.c:1.124 src/sys/dev/usb/ucom.c:1.125
--- src/sys/dev/usb/ucom.c:1.124	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/ucom.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ucom.c,v 1.124 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: ucom.c,v 1.125 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.124 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.125 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -245,10 +245,9 @@ static void	ucom_softintr(void *);
 int ucom_match(device_t, cfdata_t, void *);
 void ucom_attach(device_t, device_t, void *);
 int ucom_detach(device_t, int);
-int ucom_activate(device_t, enum devact);
 
 CFATTACH_DECL_NEW(ucom, sizeof(struct ucom_softc), ucom_match, ucom_attach,
-    ucom_detach, ucom_activate);
+    ucom_detach, NULL);
 
 int
 ucom_match(device_t parent, cfdata_t match, void *aux)
@@ -499,26 +498,6 @@ ucom_detach(device_t self, int flags)
 	return 0;
 }
 
-int
-ucom_activate(device_t self, enum devact act)
-{
-	struct ucom_softc *sc = device_private(self);
-
-	UCOMHIST_FUNC(); UCOMHIST_CALLED();
-
-	DPRINTFN(5, "%jd", act, 0, 0, 0);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		mutex_enter(&sc->sc_lock);
-		sc->sc_dying = true;
-		mutex_exit(&sc->sc_lock);
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
 void
 ucom_shutdown(struct ucom_softc *sc)
 {

Index: src/sys/dev/usb/ucomvar.h
diff -u src/sys/dev/usb/ucomvar.h:1.22 src/sys/dev/usb/ucomvar.h:1.23
--- src/sys/dev/usb/ucomvar.h:1.22	Sat May  4 08:04:13 2019
+++ src/sys/dev/usb/ucomvar.h	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ucomvar.h,v 1.22 2019/05/04 08:04:13 mrg Exp $	*/
+/*	$NetBSD: ucomvar.h,v 1.23 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -37,6 +37,24 @@
 struct	ucom_softc;
 
 /*
+ * USB detach requires ensuring that outstanding operations and
+ * open devices are properly closed before detach can return.
+ *
+ * ucom parents rely upon ucom(4) itself doing any safety here.
+ * The standard method is:
+ *
+ * 1. device softc has a "bool sc_dying" member, that may be set
+ *    in attach or other run-time for general failure, and set
+ *    early in the detach callback
+ *
+ * 2. if sc_dying is set, most functions should perform as close
+ *    to zero operations as possible
+ *
+ * 3. detach callback sets sc_dying to true and then cleans up
+ *    any local state and calls config_detach() on each child
+ */
+
+/*
  * The first argument to the ucom callbacks is the passed in ucaa_arg
  * member of the attach args, typically the parent softc pointer.
  *

Index: src/sys/dev/usb/uftdi.c
diff -u src/sys/dev/usb/uftdi.c:1.69 src/sys/dev/usb/uftdi.c:1.70
--- src/sys/dev/usb/uftdi.c:1.69	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/uftdi.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uftdi.c,v 1.69 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: uftdi.c,v 1.70 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uftdi.c,v 1.69 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uftdi.c,v 1.70 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -93,26 +93,25 @@ struct uftdi_softc {
 
 	device_t		sc_subdev;
 
-	u_char			sc_dying;
+	bool			sc_dying;
 
 	u_int			last_lcr;
 
 };
 
-Static void	uftdi_get_status(void *, int, u_char *, u_char *);
-Static void	uftdi_set(void *, int, int, int);
-Static int	uftdi_param(void *, int, struct termios *);
-Static int	uftdi_open(void *, int);
-Static void	uftdi_read(void *, int, u_char **, uint32_t *);
-Static void	uftdi_write(void *, int, u_char *, u_char *, uint32_t *);
-Static void	uftdi_break(void *, int, int);
+static void	uftdi_get_status(void *, int, u_char *, u_char *);
+static void	uftdi_set(void *, int, int, int);
+static int	uftdi_param(void *, int, struct termios *);
+static int	uftdi_open(void *, int);
+static void	uftdi_read(void *, int, u_char **, uint32_t *);
+static void	uftdi_write(void *, int, u_char *, u_char *, uint32_t *);
+static void	uftdi_break(void *, int, int);
 
 struct ucom_methods uftdi_methods = {
 	.ucom_get_status = uftdi_get_status,
 	.ucom_set = uftdi_set,
 	.ucom_param = uftdi_param,
 	.ucom_open = uftdi_open,
-	.ucom_close = NULL,
 	.ucom_read = uftdi_read,
 	.ucom_write = uftdi_write,
 };
@@ -174,16 +173,15 @@ static const struct usb_devno uftdi_devs
 };
 #define uftdi_lookup(v, p) usb_lookup(uftdi_devs, v, p)
 
-int uftdi_match(device_t, cfdata_t, void *);
-void uftdi_attach(device_t, device_t, void *);
-void uftdi_childdet(device_t, device_t);
-int uftdi_detach(device_t, int);
-int uftdi_activate(device_t, enum devact);
+static int	uftdi_match(device_t, cfdata_t, void *);
+static void	uftdi_attach(device_t, device_t, void *);
+static void	uftdi_childdet(device_t, device_t);
+static int	uftdi_detach(device_t, int);
 
 CFATTACH_DECL2_NEW(uftdi, sizeof(struct uftdi_softc), uftdi_match,
-    uftdi_attach, uftdi_detach, uftdi_activate, NULL, uftdi_childdet);
+    uftdi_attach, uftdi_detach, NULL, NULL, uftdi_childdet);
 
-int
+static int
 uftdi_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct usbif_attach_arg *uiaa = aux;
@@ -198,7 +196,7 @@ uftdi_match(device_t parent, cfdata_t ma
 		UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE;
 }
 
-void
+static void
 uftdi_attach(device_t parent, device_t self, void *aux)
 {
 	struct uftdi_softc *sc = device_private(self);
@@ -223,6 +221,7 @@ uftdi_attach(device_t parent, device_t s
 
 	sc->sc_dev = self;
 	sc->sc_udev = dev;
+	sc->sc_dying = false;
 	sc->sc_iface_no = uiaa->uiaa_ifaceno;
 	sc->sc_type = UFTDI_TYPE_8U232AM; /* most devices are post-8U232AM */
 	sc->sc_hdrlen = 0;
@@ -311,25 +310,11 @@ uftdi_attach(device_t parent, device_t s
 
 bad:
 	DPRINTF(("uftdi_attach: ATTACH ERROR\n"));
-	sc->sc_dying = 1;
+	sc->sc_dying = true;
 	return;
 }
 
-int
-uftdi_activate(device_t self, enum devact act)
-{
-	struct uftdi_softc *sc = device_private(self);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
-void
+static void
 uftdi_childdet(device_t self, device_t child)
 {
 	struct uftdi_softc *sc = device_private(self);
@@ -338,22 +323,27 @@ uftdi_childdet(device_t self, device_t c
 	sc->sc_subdev = NULL;
 }
 
-int
+static int
 uftdi_detach(device_t self, int flags)
 {
 	struct uftdi_softc *sc = device_private(self);
+	int rv = 0;
 
 	DPRINTF(("uftdi_detach: sc=%p flags=%d\n", sc, flags));
-	sc->sc_dying = 1;
-	if (sc->sc_subdev != NULL)
-		config_detach(sc->sc_subdev, flags);
+
+	sc->sc_dying = true;
+
+	if (sc->sc_subdev != NULL) {
+		rv = config_detach(sc->sc_subdev, flags);
+		sc->sc_subdev = NULL;
+	}
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
 
-	return 0;
+	return rv;
 }
 
-Static int
+static int
 uftdi_open(void *vsc, int portno)
 {
 	struct uftdi_softc *sc = vsc;
@@ -394,7 +384,7 @@ uftdi_open(void *vsc, int portno)
 	return 0;
 }
 
-Static void
+static void
 uftdi_read(void *vsc, int portno, u_char **ptr, uint32_t *count)
 {
 	struct uftdi_softc *sc = vsc;
@@ -426,7 +416,7 @@ uftdi_read(void *vsc, int portno, u_char
 	*ptr += 2;
 }
 
-Static void
+static void
 uftdi_write(void *vsc, int portno, u_char *to, u_char *from, uint32_t *count)
 {
 	struct uftdi_softc *sc = vsc;
@@ -442,7 +432,7 @@ uftdi_write(void *vsc, int portno, u_cha
 	*count += sc->sc_hdrlen;
 }
 
-Static void
+static void
 uftdi_set(void *vsc, int portno, int reg, int onoff)
 {
 	struct uftdi_softc *sc = vsc;
@@ -452,6 +442,9 @@ uftdi_set(void *vsc, int portno, int reg
 	DPRINTF(("uftdi_set: sc=%p, port=%d reg=%d onoff=%d\n", vsc, portno,
 		 reg, onoff));
 
+	if (sc->sc_dying)
+		return;
+
 	switch (reg) {
 	case UCOM_SET_DTR:
 		ctl = onoff ? FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW;
@@ -476,7 +469,7 @@ uftdi_set(void *vsc, int portno, int reg
 	(void)usbd_do_request(sc->sc_udev, &req, NULL);
 }
 
-Static int
+static int
 uftdi_param(void *vsc, int portno, struct termios *t)
 {
 	struct uftdi_softc *sc = vsc;
@@ -611,7 +604,7 @@ uftdi_param(void *vsc, int portno, struc
 	return 0;
 }
 
-void
+static void
 uftdi_get_status(void *vsc, int portno, u_char *lsr, u_char *msr)
 {
 	struct uftdi_softc *sc = vsc;
@@ -619,11 +612,14 @@ uftdi_get_status(void *vsc, int portno, 
 	DPRINTF(("uftdi_status: msr=0x%02x lsr=0x%02x\n",
 		 sc->sc_msr, sc->sc_lsr));
 
+	if (sc->sc_dying)
+		return;
+
 	*msr = sc->sc_msr;
 	*lsr = sc->sc_lsr;
 }
 
-void
+static void
 uftdi_break(void *vsc, int portno, int onoff)
 {
 	struct uftdi_softc *sc = vsc;

Index: src/sys/dev/usb/ugensa.c
diff -u src/sys/dev/usb/ugensa.c:1.38 src/sys/dev/usb/ugensa.c:1.39
--- src/sys/dev/usb/ugensa.c:1.38	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/ugensa.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ugensa.c,v 1.38 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: ugensa.c,v 1.39 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ugensa.c,v 1.38 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ugensa.c,v 1.39 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -68,12 +68,10 @@ struct ugensa_softc {
 	device_t		sc_subdev;
 	int			sc_numcon;
 
-	u_char			sc_dying;
+	bool			sc_dying;
 };
 
-struct ucom_methods ugensa_methods = {
-	.ucom_get_status = NULL,
-};
+struct ucom_methods ugensa_methods = { 0 };
 
 #define UGENSA_CONFIG_INDEX	0
 #define UGENSA_IFACE_INDEX	0
@@ -107,16 +105,15 @@ static const struct ugensa_type ugensa_d
 #define ugensa_lookup(v, p) \
 	((const struct ugensa_type *)usb_lookup(ugensa_devs, v, p))
 
-int ugensa_match(device_t, cfdata_t, void *);
-void ugensa_attach(device_t, device_t, void *);
-void ugensa_childdet(device_t, device_t);
-int ugensa_detach(device_t, int);
-int ugensa_activate(device_t, enum devact);
+static int	ugensa_match(device_t, cfdata_t, void *);
+static void	ugensa_attach(device_t, device_t, void *);
+static void	ugensa_childdet(device_t, device_t);
+static int	ugensa_detach(device_t, int);
 
 CFATTACH_DECL2_NEW(ugensa, sizeof(struct ugensa_softc), ugensa_match,
-    ugensa_attach, ugensa_detach, ugensa_activate, NULL, ugensa_childdet);
+    ugensa_attach, ugensa_detach, NULL, NULL, ugensa_childdet);
 
-int
+static int
 ugensa_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct usb_attach_arg *uaa = aux;
@@ -128,7 +125,7 @@ ugensa_match(device_t parent, cfdata_t m
 		UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
 }
 
-void
+static void
 ugensa_attach(device_t parent, device_t self, void *aux)
 {
 	struct ugensa_softc *sc = device_private(self);
@@ -146,6 +143,7 @@ ugensa_attach(device_t parent, device_t 
 	DPRINTFN(10,("\nugensa_attach: sc=%p\n", sc));
 
 	sc->sc_dev = self;
+	sc->sc_dying = false;
 
 	aprint_naive("\n");
 	aprint_normal("\n");
@@ -240,11 +238,11 @@ ugensa_attach(device_t parent, device_t 
 
 bad:
 	DPRINTF(("ugensa_attach: ATTACH ERROR\n"));
-	sc->sc_dying = 1;
+	sc->sc_dying = true;
 	return;
 }
 
-void
+static void
 ugensa_childdet(device_t self, device_t child)
 {
 	struct ugensa_softc *sc = device_private(self);
@@ -253,23 +251,7 @@ ugensa_childdet(device_t self, device_t 
 	sc->sc_subdev = NULL;
 }
 
-int
-ugensa_activate(device_t self, enum devact act)
-{
-	struct ugensa_softc *sc = device_private(self);
-
-	DPRINTF(("ugensa_activate: sc=%p\n", sc));
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
-int
+static int
 ugensa_detach(device_t self, int flags)
 {
 	struct ugensa_softc *sc = device_private(self);
@@ -277,13 +259,16 @@ ugensa_detach(device_t self, int flags)
 
 	DPRINTF(("ugensa_detach: sc=%p flags=%d\n", sc, flags));
 
-	sc->sc_dying = 1;
-	pmf_device_deregister(self);
+	sc->sc_dying = true;
 
-	if (sc->sc_subdev != NULL)
+	if (sc->sc_subdev != NULL) {
 		rv = config_detach(sc->sc_subdev, flags);
+		sc->sc_subdev = NULL;
+	}
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
 
+	pmf_device_deregister(self);
+
 	return rv;
 }
Index: src/sys/dev/usb/umct.c
diff -u src/sys/dev/usb/umct.c:1.38 src/sys/dev/usb/umct.c:1.39
--- src/sys/dev/usb/umct.c:1.38	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/umct.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: umct.c,v 1.38 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: umct.c,v 1.39 2019/05/09 02:43:35 mrg Exp $	*/
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umct.c,v 1.38 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umct.c,v 1.39 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -97,7 +97,7 @@ struct	umct_softc {
 
 	device_t		sc_subdev;	/* ucom device */
 
-	u_char			sc_dying;	/* disconnecting */
+	bool			sc_dying;	/* disconnecting */
 
 	u_char			sc_lsr;		/* Local status register */
 	u_char			sc_msr;		/* umct status register */
@@ -112,20 +112,20 @@ struct	umct_softc {
 #define UMCTIBUFSIZE 256
 #define UMCTOBUFSIZE 256
 
-Static	void umct_init(struct umct_softc *);
-Static	void umct_set_baudrate(struct umct_softc *, u_int);
-Static	void umct_set_lcr(struct umct_softc *, u_int);
-Static	void umct_intr(struct usbd_xfer *, void *, usbd_status);
-
-Static	void umct_set(void *, int, int, int);
-Static	void umct_dtr(struct umct_softc *, int);
-Static	void umct_rts(struct umct_softc *, int);
-Static	void umct_break(struct umct_softc *, int);
-Static	void umct_set_line_state(struct umct_softc *);
-Static	void umct_get_status(void *, int, u_char *, u_char *);
-Static	int  umct_param(void *, int, struct termios *);
-Static	int  umct_open(void *, int);
-Static	void umct_close(void *, int);
+static	void umct_init(struct umct_softc *);
+static	void umct_set_baudrate(struct umct_softc *, u_int);
+static	void umct_set_lcr(struct umct_softc *, u_int);
+static	void umct_intr(struct usbd_xfer *, void *, usbd_status);
+
+static	void umct_set(void *, int, int, int);
+static	void umct_dtr(struct umct_softc *, int);
+static	void umct_rts(struct umct_softc *, int);
+static	void umct_break(struct umct_softc *, int);
+static	void umct_set_line_state(struct umct_softc *);
+static	void umct_get_status(void *, int, u_char *, u_char *);
+static	int  umct_param(void *, int, struct termios *);
+static	int  umct_open(void *, int);
+static	void umct_close(void *, int);
 
 struct	ucom_methods umct_methods = {
 	.ucom_get_status = umct_get_status,
@@ -147,16 +147,15 @@ static const struct usb_devno umct_devs[
 };
 #define umct_lookup(v, p) usb_lookup(umct_devs, v, p)
 
-int umct_match(device_t, cfdata_t, void *);
-void umct_attach(device_t, device_t, void *);
-void umct_childdet(device_t, device_t);
-int umct_detach(device_t, int);
-int umct_activate(device_t, enum devact);
+static int	umct_match(device_t, cfdata_t, void *);
+static void	umct_attach(device_t, device_t, void *);
+static void	umct_childdet(device_t, device_t);
+static int	umct_detach(device_t, int);
 
 CFATTACH_DECL2_NEW(umct, sizeof(struct umct_softc), umct_match,
-    umct_attach, umct_detach, umct_activate, NULL, umct_childdet);
+    umct_attach, umct_detach, NULL, NULL, umct_childdet);
 
-int
+static int
 umct_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct usb_attach_arg *uaa = aux;
@@ -165,7 +164,7 @@ umct_match(device_t parent, cfdata_t mat
 		UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
 }
 
-void
+static void
 umct_attach(device_t parent, device_t self, void *aux)
 {
 	struct umct_softc *sc = device_private(self);
@@ -181,6 +180,7 @@ umct_attach(device_t parent, device_t se
 	struct ucom_attach_args ucaa;
 
 	sc->sc_dev = self;
+	sc->sc_dying = false;
 
 	aprint_naive("\n");
 	aprint_normal("\n");
@@ -204,7 +204,7 @@ umct_attach(device_t parent, device_t se
 	if (err) {
 		aprint_error_dev(self, "failed to set configuration, err=%s\n",
 		    usbd_errstr(err));
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -214,7 +214,7 @@ umct_attach(device_t parent, device_t se
 	if (cdesc == NULL) {
 		aprint_error_dev(self,
 		    "failed to get configuration descriptor\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -224,7 +224,7 @@ umct_attach(device_t parent, device_t se
 	if (err) {
 		aprint_error_dev(self, "failed to get interface, err=%s\n",
 		    usbd_errstr(err));
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -238,7 +238,7 @@ umct_attach(device_t parent, device_t se
 		if (ed == NULL) {
 			aprint_error_dev(self,
 			    "no endpoint descriptor for %d\n", i);
-			sc->sc_dying = 1;
+			sc->sc_dying = true;
 			return;
 		}
 
@@ -263,19 +263,19 @@ umct_attach(device_t parent, device_t se
 
 	if (ucaa.ucaa_bulkin == -1) {
 		aprint_error_dev(self, "Could not find data bulk in\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
 	if (ucaa.ucaa_bulkout == -1) {
 		aprint_error_dev(self, "Could not find data bulk out\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
 	if (sc->sc_intr_number == -1) {
 		aprint_error_dev(self, "Could not find interrupt in\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -307,7 +307,7 @@ umct_attach(device_t parent, device_t se
 	return;
 }
 
-void
+static void
 umct_childdet(device_t self, device_t child)
 {
 	struct umct_softc *sc = device_private(self);
@@ -316,45 +316,44 @@ umct_childdet(device_t self, device_t ch
 	sc->sc_subdev = NULL;
 }
 
-int
-umct_detach(device_t self, int flags)
+static void
+umct_close_pipe(struct umct_softc *sc)
 {
-	struct umct_softc *sc = device_private(self);
-	int rv = 0;
-
-	DPRINTF(("umct_detach: sc=%p flags=%d\n", sc, flags));
 
 	if (sc->sc_intr_pipe != NULL) {
 		usbd_abort_pipe(sc->sc_intr_pipe);
 		usbd_close_pipe(sc->sc_intr_pipe);
-		kmem_free(sc->sc_intr_buf, sc->sc_isize);
 		sc->sc_intr_pipe = NULL;
 	}
-
-	sc->sc_dying = 1;
-	if (sc->sc_subdev != NULL)
-		rv = config_detach(sc->sc_subdev, flags);
-
-	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
-
-	return rv;
+	if (sc->sc_intr_buf != NULL) {
+		kmem_free(sc->sc_intr_buf, sc->sc_isize);
+		sc->sc_intr_buf = NULL;
+	}
 }
 
-int
-umct_activate(device_t self, enum devact act)
+static int
+umct_detach(device_t self, int flags)
 {
 	struct umct_softc *sc = device_private(self);
+	int rv = 0;
 
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
+	DPRINTF(("umct_detach: sc=%p flags=%d\n", sc, flags));
+
+	sc->sc_dying = true;
+
+	umct_close_pipe(sc);
+
+	if (sc->sc_subdev != NULL) {
+		rv = config_detach(sc->sc_subdev, flags);
+		sc->sc_subdev = NULL;
 	}
+
+	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
+
+	return rv;
 }
 
-void
+static void
 umct_set_line_state(struct umct_softc *sc)
 {
 	usb_device_request_t req;
@@ -375,11 +374,14 @@ umct_set_line_state(struct umct_softc *s
 	(void)usbd_do_request(sc->sc_udev, &req, &ls);
 }
 
-void
+static void
 umct_set(void *addr, int portno, int reg, int onoff)
 {
 	struct umct_softc *sc = addr;
 
+	if (sc->sc_dying)
+		return;
+
 	switch (reg) {
 	case UCOM_SET_DTR:
 		umct_dtr(sc, onoff);
@@ -481,22 +483,23 @@ umct_set_baudrate(struct umct_softc *sc,
 	(void)usbd_do_request(sc->sc_udev, &req, arate); /* XXX should check */
 }
 
-void
+static void
 umct_init(struct umct_softc *sc)
 {
 	umct_set_baudrate(sc, 9600);
 	umct_set_lcr(sc, LCR_DATA_BITS_8 | LCR_PARITY_NONE | LCR_STOP_BITS_1);
 }
 
-int
+static int
 umct_param(void *addr, int portno, struct termios *t)
 {
 	struct umct_softc *sc = addr;
 	u_int data = 0;
 
-	DPRINTF(("umct_param: sc=%p\n", sc));
+	DPRINTF(("umct_param: sc=%p BAUDRATE=%d\n", sc, t->c_ospeed));
 
-	DPRINTF(("umct_param: BAUDRATE=%d\n", t->c_ospeed));
+	if (sc->sc_dying)
+		return EIO;
 
 	if (ISSET(t->c_cflag, CSTOPB))
 		data |= LCR_STOP_BITS_2;
@@ -538,11 +541,11 @@ umct_open(void *addr, int portno)
 	struct umct_softc *sc = addr;
 	int err, lcr_data;
 
+	DPRINTF(("umct_open: sc=%p\n", sc));
+
 	if (sc->sc_dying)
 		return EIO;
 
-	DPRINTF(("umct_open: sc=%p\n", sc));
-
 	/* initialize LCR */
 	lcr_data = LCR_DATA_BITS_8 | LCR_PARITY_NONE |
 	    LCR_STOP_BITS_1;
@@ -558,7 +561,7 @@ umct_open(void *addr, int portno)
 		if (err) {
 			DPRINTF(("%s: cannot open interrupt pipe (addr %d)\n",
 				device_xname(sc->sc_dev), sc->sc_intr_number));
-					return EIO;
+			return EIO;
 		}
 	}
 
@@ -569,25 +572,12 @@ void
 umct_close(void *addr, int portno)
 {
 	struct umct_softc *sc = addr;
-	int err;
-
-	if (sc->sc_dying)
-		return;
 
 	DPRINTF(("umct_close: close\n"));
 
-	if (sc->sc_intr_pipe != NULL) {
-		err = usbd_abort_pipe(sc->sc_intr_pipe);
-		if (err)
-			printf("%s: abort interrupt pipe failed: %s\n",
-				device_xname(sc->sc_dev), usbd_errstr(err));
-		err = usbd_close_pipe(sc->sc_intr_pipe);
-		if (err)
-			printf("%s: close interrupt pipe failed: %s\n",
-				device_xname(sc->sc_dev), usbd_errstr(err));
-		kmem_free(sc->sc_intr_buf, sc->sc_isize);
-		sc->sc_intr_pipe = NULL;
-	}
+	if (sc->sc_dying)
+		return;
+	umct_close_pipe(sc);
 }
 
 void
@@ -630,6 +620,9 @@ umct_get_status(void *addr, int portno, 
 
 	DPRINTF(("umct_get_status:\n"));
 
+	if (sc->sc_dying)
+		return;
+
 	*lsr = sc->sc_lsr;
 	*msr = sc->sc_msr;
 }

Index: src/sys/dev/usb/uhmodem.c
diff -u src/sys/dev/usb/uhmodem.c:1.18 src/sys/dev/usb/uhmodem.c:1.19
--- src/sys/dev/usb/uhmodem.c:1.18	Sat May  4 23:36:14 2019
+++ src/sys/dev/usb/uhmodem.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhmodem.c,v 1.18 2019/05/04 23:36:14 mrg Exp $	*/
+/*	$NetBSD: uhmodem.c,v 1.19 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 2008 Yojiro UO <y...@nui.org>.
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhmodem.c,v 1.18 2019/05/04 23:36:14 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhmodem.c,v 1.19 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -167,10 +167,9 @@ static int	uhmodem_match(device_t, cfdat
 static void	uhmodem_attach(device_t, device_t, void *);
 static void	uhmodem_childdet(device_t, device_t);
 static int	uhmodem_detach(device_t, int);
-static int	uhmodem_activate(device_t, enum devact);
 
 CFATTACH_DECL2_NEW(uhmodem, sizeof(struct ubsa_softc), uhmodem_match,
-    uhmodem_attach, uhmodem_detach, uhmodem_activate, NULL, uhmodem_childdet);
+    uhmodem_attach, uhmodem_detach, NULL, NULL, uhmodem_childdet);
 
 static int
 uhmodem_match(device_t parent, cfdata_t match, void *aux)
@@ -211,7 +210,8 @@ uhmodem_attach(device_t parent, device_t
 	sc->sc_dev = self;
 	sc->sc_udev = dev;
 	sc->sc_config_index = UBSA_DEFAULT_CONFIG_INDEX;
-	sc->sc_numif = 1; /* defaut device has one interface */
+	sc->sc_numif = 1; /* default device has one interface */
+	sc->sc_dying = false;
 
 	/* Hauwei E220 need special request to change its mode to modem */
 	if ((uiaa->uiaa_ifaceno == 0) && (uiaa->uiaa_class != 255)) {
@@ -219,12 +219,10 @@ uhmodem_attach(device_t parent, device_t
 		if (err) {
 			aprint_error_dev(self, "failed to change mode: %s\n",
 				usbd_errstr(err));
-			sc->sc_dying = 1;
 			goto error;
 		}
 		aprint_error_dev(self,
 		    "mass storage only mode, reattach to enable modem\n");
-		sc->sc_dying = 1;
 		goto error;
 	}
 
@@ -247,7 +245,6 @@ uhmodem_attach(device_t parent, device_t
 	if (err) {
 		aprint_error_dev(self, "failed to set configuration: %s\n",
 		    usbd_errstr(err));
-		sc->sc_dying = 1;
 		goto error;
 	}
 
@@ -256,7 +253,6 @@ uhmodem_attach(device_t parent, device_t
 	if (cdesc == NULL) {
 		aprint_error_dev(self,
 		    "failed to get configuration descriptor\n");
-		sc->sc_dying = 1;
 		goto error;
 	}
 
@@ -270,7 +266,6 @@ uhmodem_attach(device_t parent, device_t
 		if (err) {
 			if (i == 0){
 				/* can not get main interface */
-				sc->sc_dying = 1;
 				goto error;
 			} else
 				break;
@@ -311,7 +306,6 @@ uhmodem_attach(device_t parent, device_t
 			    "to enable modem function\n");
 			if (i == 0) {
 				/* could not get intr for main tty */
-				sc->sc_dying = 1;
 				goto error;
 			} else
 				break;
@@ -319,14 +313,12 @@ uhmodem_attach(device_t parent, device_t
 		if (ucaa.ucaa_bulkin == -1) {
 			aprint_error_dev(self,
 			    "Could not find data bulk in\n");
-			sc->sc_dying = 1;
 			goto error;
 		}
 
 		if (ucaa.ucaa_bulkout == -1) {
 			aprint_error_dev(self,
 			    "Could not find data bulk out\n");
-			sc->sc_dying = 1;
 			goto error;
 		}
 
@@ -376,6 +368,7 @@ uhmodem_attach(device_t parent, device_t
 	return;
 
 error:
+	sc->sc_dying = true;
 	return;
 }
 
@@ -402,17 +395,15 @@ uhmodem_detach(device_t self, int flags)
 
 	DPRINTF(("uhmodem_detach: sc = %p\n", sc));
 
-	if (sc->sc_intr_pipe != NULL) {
-		usbd_abort_pipe(sc->sc_intr_pipe);
-		usbd_close_pipe(sc->sc_intr_pipe);
-		kmem_free(sc->sc_intr_buf, sc->sc_isize);
-		sc->sc_intr_pipe = NULL;
-	}
+	sc->sc_dying = true;
+
+	ubsa_close_pipe(sc);
 
-	sc->sc_dying = 1;
 	for (i = 0; i < sc->sc_numif; i++) {
-		if (sc->sc_subdevs[i] != NULL)
+		if (sc->sc_subdevs[i] != NULL) {
 			rv |= config_detach(sc->sc_subdevs[i], flags);
+			sc->sc_subdevs[i] = NULL;
+		}
 	}
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
@@ -422,49 +413,38 @@ uhmodem_detach(device_t self, int flags)
 }
 
 static int
-uhmodem_activate(device_t self, enum devact act)
-{
-	struct ubsa_softc *sc = device_private(self);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
-static int
 uhmodem_open(void *addr, int portno)
 {
 	struct ubsa_softc *sc = addr;
 	usbd_status err;
 
-	if (sc->sc_dying)
-		return ENXIO;
-
 	DPRINTF(("%s: sc = %p\n", __func__, sc));
 
+	if (sc->sc_dying)
+		return EIO;
+
 	err = uhmodem_endpointhalt(sc, 0);
-	if (err)
+	if (err) {
 		aprint_error("%s: endpointhalt fail\n", __func__);
-	else
+		return EIO;
+	} else
 		usbd_delay_ms(sc->sc_udev, 50);
 
 	if (sc->sc_devflags & A2502) {
 		err = a2502_init(sc->sc_udev);
-		if (err)
+		if (err) {
 			aprint_error("%s: a2502init fail\n", __func__);
-		else
+			return EIO;
+		} else
 			usbd_delay_ms(sc->sc_udev, 50);
 	}
 #if 0 /* currently disabled */
 	if (sc->sc_devflags & E220) {
 		err = e220_init(sc->sc_udev);
-		if (err)
+		if (err) {
 			aprint_error("%s: e220init fail\n", __func__);
-		else
+			return EIO;
+		} else
 			usbd_delay_ms(sc->sc_udev, 50);
 	}
 #endif

Index: src/sys/dev/usb/uipaq.c
diff -u src/sys/dev/usb/uipaq.c:1.24 src/sys/dev/usb/uipaq.c:1.25
--- src/sys/dev/usb/uipaq.c:1.24	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/uipaq.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipaq.c,v 1.24 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: uipaq.c,v 1.25 2019/05/09 02:43:35 mrg Exp $	*/
 /*	$OpenBSD: uipaq.c,v 1.1 2005/06/17 23:50:33 deraadt Exp $	*/
 
 /*
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipaq.c,v 1.24 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipaq.c,v 1.25 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -90,22 +90,24 @@ struct uipaq_softc {
 
 	uint16_t		sc_flags;
 
-	u_char			sc_dying;
+	bool			sc_dying;
 };
 
 /* Callback routines */
-Static void	uipaq_set(void *, int, int, int);
+static void	uipaq_set(void *, int, int, int);
+static int	uipaq_open(void *, int);
 
 
 /* Support routines. */
 /* based on uppc module by Sam Lawrance */
-Static void	uipaq_dtr(struct uipaq_softc *, int);
-Static void	uipaq_rts(struct uipaq_softc *, int);
-Static void	uipaq_break(struct uipaq_softc *, int);
+static void	uipaq_dtr(struct uipaq_softc *, int);
+static void	uipaq_rts(struct uipaq_softc *, int);
+static void	uipaq_break(struct uipaq_softc *, int);
 
 
 struct ucom_methods uipaq_methods = {
 	.ucom_set = uipaq_set,
+	.ucom_open = uipaq_open,
 };
 
 struct uipaq_type {
@@ -128,10 +130,9 @@ int uipaq_match(device_t, cfdata_t, void
 void uipaq_attach(device_t, device_t, void *);
 void uipaq_childdet(device_t, device_t);
 int uipaq_detach(device_t, int);
-int uipaq_activate(device_t, enum devact);
 
 CFATTACH_DECL2_NEW(uipaq, sizeof(struct uipaq_softc), uipaq_match,
-    uipaq_attach, uipaq_detach, uipaq_activate, NULL, uipaq_childdet);
+    uipaq_attach, uipaq_detach, NULL, NULL, uipaq_childdet);
 
 int
 uipaq_match(device_t parent, cfdata_t match, void *aux)
@@ -163,6 +164,7 @@ uipaq_attach(device_t parent, device_t s
 	DPRINTFN(10,("\nuipaq_attach: sc=%p\n", sc));
 
 	sc->sc_dev = self;
+	sc->sc_dying = false;
 
 	aprint_naive("\n");
 	aprint_normal("\n");
@@ -242,7 +244,7 @@ uipaq_attach(device_t parent, device_t s
 
 bad:
 	DPRINTF(("uipaq_attach: ATTACH ERROR\n"));
-	sc->sc_dying = 1;
+	sc->sc_dying = true;
 	return;
 }
 
@@ -342,6 +344,9 @@ uipaq_set(void *addr, int portno, int re
 {
 	struct uipaq_softc* sc = addr;
 
+	if (sc->sc_dying)
+		return;
+
 	switch (reg) {
 	case UCOM_SET_DTR:
 		uipaq_dtr(addr, onoff);
@@ -359,19 +364,15 @@ uipaq_set(void *addr, int portno, int re
 	}
 }
 
-
-int
-uipaq_activate(device_t self, enum devact act)
+static int
+uipaq_open(void *arg, int portno)
 {
-	struct uipaq_softc *sc = device_private(self);
+	struct uipaq_softc *sc = arg;
 
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
+	if (sc->sc_dying)
+		return EIO;
+
+	return 0;
 }
 
 void
@@ -390,12 +391,15 @@ uipaq_detach(device_t self, int flags)
 	int rv = 0;
 
 	DPRINTF(("uipaq_detach: sc=%p flags=%d\n", sc, flags));
-	sc->sc_dying = 1;
-	if (sc->sc_subdev != NULL)
+
+	sc->sc_dying = true;
+
+	if (sc->sc_subdev != NULL) {
 		rv |= config_detach(sc->sc_subdev, flags);
+		sc->sc_subdev = NULL;
+	}
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
 
 	return rv;
 }
-

Index: src/sys/dev/usb/ukyopon.c
diff -u src/sys/dev/usb/ukyopon.c:1.23 src/sys/dev/usb/ukyopon.c:1.24
--- src/sys/dev/usb/ukyopon.c:1.23	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/ukyopon.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ukyopon.c,v 1.23 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: ukyopon.c,v 1.24 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998, 2005 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ukyopon.c,v 1.23 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ukyopon.c,v 1.24 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -105,10 +105,9 @@ static struct ucom_methods ukyopon_metho
 static int	ukyopon_match(device_t, cfdata_t, void *);
 static void	ukyopon_attach(device_t, device_t, void *);
 static int	ukyopon_detach(device_t, int);
-static int	ukyopon_activate(device_t, enum devact);
 
 CFATTACH_DECL_NEW(ukyopon, sizeof(struct ukyopon_softc), ukyopon_match,
-    ukyopon_attach, ukyopon_detach, ukyopon_activate);
+    ukyopon_attach, ukyopon_detach, NULL);
 
 static int
 ukyopon_match(device_t parent, cfdata_t match, void *aux)
@@ -154,7 +153,7 @@ ukyopon_get_status(void *addr, int portn
 	if ((sc->sc_umodem.sc_msr & UMSR_DCD) == 0)
 		sc->sc_umodem.sc_msr |= UMSR_DCD;
 
-	umodem_get_status(addr, portno, lsr, msr);
+	umodem_get_status(&sc->sc_umodem, portno, lsr, msr);
 }
 
 static void
@@ -209,7 +208,7 @@ ukyopon_ioctl(void *addr, int portno, u_
 		break;
 
 	default:
-		error = umodem_ioctl(addr, portno, cmd, data, flag, p);
+		error = umodem_ioctl(&sc->sc_umodem, portno, cmd, data, flag, p);
 		break;
 	}
 
@@ -217,14 +216,6 @@ ukyopon_ioctl(void *addr, int portno, u_
 }
 
 int
-ukyopon_activate(device_t self, enum devact act)
-{
-	struct ukyopon_softc *sc = device_private(self);
-
-	return umodem_common_activate(&sc->sc_umodem, act);
-}
-
-int
 ukyopon_detach(device_t self, int flags)
 {
 	struct ukyopon_softc *sc = device_private(self);

Index: src/sys/dev/usb/umcs.c
diff -u src/sys/dev/usb/umcs.c:1.12 src/sys/dev/usb/umcs.c:1.13
--- src/sys/dev/usb/umcs.c:1.12	Fri Aug  3 13:19:33 2018
+++ src/sys/dev/usb/umcs.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: umcs.c,v 1.12 2018/08/03 13:19:33 skrll Exp $ */
+/* $NetBSD: umcs.c,v 1.13 2019/05/09 02:43:35 mrg Exp $ */
 /* $FreeBSD: head/sys/dev/usb/serial/umcs.c 260559 2014-01-12 11:44:28Z hselasky $ */
 
 /*-
@@ -41,7 +41,7 @@
  *
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umcs.c,v 1.12 2018/08/03 13:19:33 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umcs.c,v 1.13 2019/05/09 02:43:35 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -113,7 +113,6 @@ static void umcs7840_attach(device_t, de
 static int umcs7840_detach(device_t, int);
 static void umcs7840_intr(struct usbd_xfer *, void *, usbd_status);
 static void umcs7840_change_task(void *arg);
-static int umcs7840_activate(device_t, enum devact);
 static void umcs7840_childdet(device_t, device_t);
 
 static void umcs7840_get_status(void *, int, u_char *, u_char *);
@@ -140,7 +139,7 @@ static const struct usb_devno umcs7840_d
 #define umcs7840_lookup(v, p) usb_lookup(umcs7840_devs, v, p)
 
 CFATTACH_DECL2_NEW(umcs, sizeof(struct umcs7840_softc), umcs7840_match,
-    umcs7840_attach, umcs7840_detach, umcs7840_activate, NULL,
+    umcs7840_attach, umcs7840_detach, NULL, NULL,
     umcs7840_childdet);
 
 static inline int
@@ -193,9 +192,11 @@ umcs7840_attach(device_t parent, device_
 
 	sc->sc_dev = self;
 	sc->sc_udev = uaa->uaa_device;
+	sc->sc_dying = false;
 
 	if (usbd_set_config_index(sc->sc_udev, MCS7840_CONFIG_INDEX, 1) != 0) {
 		aprint_error(": could not set configuration no\n");
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -204,6 +205,7 @@ umcs7840_attach(device_t parent, device_
 	    &sc->sc_iface);
 	if (error != 0) {
 		aprint_error(": could not get interface handle\n");
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -266,6 +268,7 @@ umcs7840_attach(device_t parent, device_
 	}
 	if (intr_addr < 0) {
 		aprint_error_dev(self, "interrupt pipe not found\n");
+		sc->sc_dying = true;
 		return;
 	}
 	sc->sc_intr_buf = kmem_alloc(sc->sc_intr_buflen, KM_SLEEP);
@@ -276,6 +279,7 @@ umcs7840_attach(device_t parent, device_
 	if (error) {
 		aprint_error_dev(self, "cannot open interrupt pipe "
 		    "(addr %d)\n", intr_addr);
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -310,6 +314,7 @@ umcs7840_attach(device_t parent, device_
 		if (ed == NULL) {
 			aprint_error_dev(self,
 			    "no bulk in endpoint found for %d\n", i);
+			sc->sc_dying = true;
 			return;
 		}
 		ucaa.ucaa_bulkin = ed->bEndpointAddress;
@@ -504,29 +509,23 @@ umcs7840_detach(device_t self, int flags
 
 	/* close interrupt pipe */
 	if (sc->sc_intr_pipe != NULL) {
-		rv = usbd_abort_pipe(sc->sc_intr_pipe);
-		if (rv)
-			aprint_error_dev(sc->sc_dev,
-			    "abort interrupt pipe failed: %s\n",
-			    usbd_errstr(rv));
-		rv = usbd_close_pipe(sc->sc_intr_pipe);
-		if (rv)
-			aprint_error_dev(sc->sc_dev,
-			    "failed to close interrupt pipe: %s\n",
-			    usbd_errstr(rv));
-		kmem_free(sc->sc_intr_buf, sc->sc_intr_buflen);
+		usbd_abort_pipe(sc->sc_intr_pipe);
+		usbd_close_pipe(sc->sc_intr_pipe);
 		sc->sc_intr_pipe = NULL;
 	}
+	if (sc->sc_intr_buf != NULL) {
+		kmem_free(sc->sc_intr_buf, sc->sc_intr_buflen);
+		sc->sc_intr_buf = NULL;
+	}
 	usb_rem_task_wait(sc->sc_udev, &sc->sc_change_task, USB_TASKQ_DRIVER,
 	    NULL);
 
 	/* detach children */
 	for (i = 0; i < sc->sc_numports; i++) {
 		if (sc->sc_ports[i].sc_port_ucom) {
-			rv = config_detach(sc->sc_ports[i].sc_port_ucom,
+			rv |= config_detach(sc->sc_ports[i].sc_port_ucom,
 			    flags);
-			if (rv)
-				break;
+			sc->sc_ports[i].sc_port_ucom = NULL;
 		}
 	}
 
@@ -535,20 +534,6 @@ umcs7840_detach(device_t self, int flags
 	return rv;
 }
 
-int
-umcs7840_activate(device_t self, enum devact act)
-{
-	struct umcs7840_softc *sc = device_private(self);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = true;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
 static void
 umcs7840_childdet(device_t self, device_t child)
 {
@@ -613,6 +598,9 @@ umcs7840_param(void *self, int portno, s
 	uint8_t lcr = sc->sc_ports[portno].sc_port_lcr;
 	uint8_t mcr = sc->sc_ports[portno].sc_port_mcr;
 
+	if (sc->sc_dying)
+		return EIO;
+
 	if (t->c_cflag & CSTOPB) {
 		lcr |= MCS7840_UART_LCR_STOPB2;
 	} else {
@@ -860,6 +848,9 @@ umcs7840_intr(struct usbd_xfer *xfer, vo
 	int actlen;
 	int subunit;
 
+	if (sc->sc_dying)
+		return;
+
 	if (status == USBD_NOT_STARTED || status == USBD_CANCELLED
 	    || status == USBD_IOERROR)
 		return;

Index: src/sys/dev/usb/umodem.c
diff -u src/sys/dev/usb/umodem.c:1.71 src/sys/dev/usb/umodem.c:1.72
--- src/sys/dev/usb/umodem.c:1.71	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/umodem.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: umodem.c,v 1.71 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: umodem.c,v 1.72 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umodem.c,v 1.71 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umodem.c,v 1.72 2019/05/09 02:43:35 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -79,17 +79,16 @@ Static struct ucom_methods umodem_method
 	.ucom_close = umodem_close,
 };
 
-int	umodem_match(device_t, cfdata_t, void *);
-void	umodem_attach(device_t, device_t, void *);
-int	umodem_detach(device_t, int);
-int	umodem_activate(device_t, enum devact);
+static int	umodem_match(device_t, cfdata_t, void *);
+static void	umodem_attach(device_t, device_t, void *);
+static int	umodem_detach(device_t, int);
 
 
 
 CFATTACH_DECL_NEW(umodem, sizeof(struct umodem_softc), umodem_match,
-    umodem_attach, umodem_detach, umodem_activate);
+    umodem_attach, umodem_detach, NULL);
 
-int
+static int
 umodem_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct usbif_attach_arg *uiaa = aux;
@@ -107,8 +106,8 @@ umodem_match(device_t parent, cfdata_t m
 
 	return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO;
 }
-//
-void
+
+static void
 umodem_attach(device_t parent, device_t self, void *aux)
 {
 	struct umodem_softc *sc = device_private(self);
@@ -127,15 +126,7 @@ umodem_attach(device_t parent, device_t 
 	return;
 }
 
-int
-umodem_activate(device_t self, enum devact act)
-{
-	struct umodem_softc *sc = device_private(self);
-
-	return umodem_common_activate(sc, act);
-}
-
-int
+static int
 umodem_detach(device_t self, int flags)
 {
 	struct umodem_softc *sc = device_private(self);

Index: src/sys/dev/usb/umodem_common.c
diff -u src/sys/dev/usb/umodem_common.c:1.29 src/sys/dev/usb/umodem_common.c:1.30
--- src/sys/dev/usb/umodem_common.c:1.29	Mon May  6 23:47:39 2019
+++ src/sys/dev/usb/umodem_common.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: umodem_common.c,v 1.29 2019/05/06 23:47:39 mrg Exp $	*/
+/*	$NetBSD: umodem_common.c,v 1.30 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umodem_common.c,v 1.29 2019/05/06 23:47:39 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umodem_common.c,v 1.30 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -288,6 +288,17 @@ umodem_open(void *addr, int portno)
 	return 0;
 }
 
+static void
+umodem_close_pipe(struct umodem_softc *sc)
+{
+
+	if (sc->sc_notify_pipe != NULL) {
+		usbd_abort_pipe(sc->sc_notify_pipe);
+		usbd_close_pipe(sc->sc_notify_pipe);
+		sc->sc_notify_pipe = NULL;
+	}
+}
+
 void
 umodem_close(void *addr, int portno)
 {
@@ -298,11 +309,7 @@ umodem_close(void *addr, int portno)
 	if (sc->sc_dying)
 		return;
 
-	if (sc->sc_notify_pipe != NULL) {
-		usbd_abort_pipe(sc->sc_notify_pipe);
-		usbd_close_pipe(sc->sc_notify_pipe);
-		sc->sc_notify_pipe = NULL;
-	}
+	umodem_close_pipe(sc);
 }
 
 static void
@@ -436,11 +443,11 @@ umodem_param(void *addr, int portno, str
 	usbd_status err;
 	usb_cdc_line_state_t ls;
 
+	DPRINTF(("umodem_param: sc=%p\n", sc));
+
 	if (sc->sc_dying)
 		return EIO;
 
-	DPRINTF(("umodem_param: sc=%p\n", sc));
-
 	USETDW(ls.dwDTERate, t->c_ospeed);
 	if (ISSET(t->c_cflag, CSTOPB))
 		ls.bCharFormat = UCDC_STOP_BIT_2;
@@ -483,11 +490,11 @@ umodem_ioctl(void *addr, int portno, u_l
 	struct umodem_softc *sc = addr;
 	int error = 0;
 
+	DPRINTF(("umodem_ioctl: cmd=0x%08lx\n", cmd));
+
 	if (sc->sc_dying)
 		return EIO;
 
-	DPRINTF(("umodem_ioctl: cmd=0x%08lx\n", cmd));
-
 	switch (cmd) {
 	case USB_GET_CM_OVER_DATA:
 		*(int *)data = sc->sc_cm_over_data;
@@ -652,18 +659,6 @@ umodem_set_comm_feature(struct umodem_so
 	return USBD_NORMAL_COMPLETION;
 }
 
-int
-umodem_common_activate(struct umodem_softc *sc, enum devact act)
-{
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = true;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
 void
 umodem_common_childdet(struct umodem_softc *sc, device_t child)
 {
@@ -680,8 +675,12 @@ umodem_common_detach(struct umodem_softc
 
 	sc->sc_dying = true;
 
-	if (sc->sc_subdev != NULL)
+	umodem_close_pipe(sc);
+
+	if (sc->sc_subdev != NULL) {
 		rv = config_detach(sc->sc_subdev, flags);
+		sc->sc_subdev = NULL;
+	}
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
 

Index: src/sys/dev/usb/uplcom.c
diff -u src/sys/dev/usb/uplcom.c:1.83 src/sys/dev/usb/uplcom.c:1.84
--- src/sys/dev/usb/uplcom.c:1.83	Tue May  7 05:17:22 2019
+++ src/sys/dev/usb/uplcom.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uplcom.c,v 1.83 2019/05/07 05:17:22 mrg Exp $	*/
+/*	$NetBSD: uplcom.c,v 1.84 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uplcom.c,v 1.83 2019/05/07 05:17:22 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uplcom.c,v 1.84 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -141,7 +141,7 @@ struct	uplcom_softc {
 
 	device_t		sc_subdev;	/* ucom device */
 
-	u_char			sc_dying;	/* disconnecting */
+	bool			sc_dying;	/* disconnecting */
 
 	u_char			sc_lsr;		/* Local status register */
 	u_char			sc_msr;		/* uplcom status register */
@@ -156,25 +156,26 @@ struct	uplcom_softc {
 #define UPLCOMIBUFSIZE 256
 #define UPLCOMOBUFSIZE 256
 
-Static	usbd_status uplcom_reset(struct uplcom_softc *);
-Static	usbd_status uplcom_set_line_coding(struct uplcom_softc *,
+static	usbd_status uplcom_reset(struct uplcom_softc *);
+static	usbd_status uplcom_set_line_coding(struct uplcom_softc *,
 					   usb_cdc_line_state_t *);
-Static	usbd_status uplcom_set_crtscts(struct uplcom_softc *);
-Static	void uplcom_intr(struct usbd_xfer *, void *, usbd_status);
+static	usbd_status uplcom_set_crtscts(struct uplcom_softc *);
+static	void uplcom_intr(struct usbd_xfer *, void *, usbd_status);
 
-Static	void uplcom_set(void *, int, int, int);
-Static	void uplcom_dtr(struct uplcom_softc *, int);
-Static	void uplcom_rts(struct uplcom_softc *, int);
-Static	void uplcom_break(struct uplcom_softc *, int);
-Static	void uplcom_set_line_state(struct uplcom_softc *);
-Static	void uplcom_get_status(void *, int, u_char *, u_char *);
+static	void uplcom_set(void *, int, int, int);
+static	void uplcom_dtr(struct uplcom_softc *, int);
+static	void uplcom_rts(struct uplcom_softc *, int);
+static	void uplcom_break(struct uplcom_softc *, int);
+static	void uplcom_set_line_state(struct uplcom_softc *);
+static	void uplcom_get_status(void *, int, u_char *, u_char *);
 #if TODO
-Static	int  uplcom_ioctl(void *, int, u_long, void *, int, proc_t *);
+static	int  uplcom_ioctl(void *, int, u_long, void *, int, proc_t *);
 #endif
-Static	int  uplcom_param(void *, int, struct termios *);
-Static	int  uplcom_open(void *, int);
-Static	void uplcom_close(void *, int);
-Static usbd_status uplcom_vendor_control_write(struct usbd_device *, uint16_t, uint16_t);
+static	int  uplcom_param(void *, int, struct termios *);
+static	int  uplcom_open(void *, int);
+static	void uplcom_close(void *, int);
+static usbd_status uplcom_vendor_control_write(struct usbd_device *, uint16_t, uint16_t);
+static void uplcom_close_pipe(struct uplcom_softc *);
 
 struct	ucom_methods uplcom_methods = {
 	.ucom_get_status = uplcom_get_status,
@@ -239,10 +240,9 @@ int uplcom_match(device_t, cfdata_t, voi
 void uplcom_attach(device_t, device_t, void *);
 void uplcom_childdet(device_t, device_t);
 int uplcom_detach(device_t, int);
-int uplcom_activate(device_t, enum devact);
 
 CFATTACH_DECL2_NEW(uplcom, sizeof(struct uplcom_softc), uplcom_match,
-    uplcom_attach, uplcom_detach, uplcom_activate, NULL, uplcom_childdet);
+    uplcom_attach, uplcom_detach, NULL, NULL, uplcom_childdet);
 
 int
 uplcom_match(device_t parent, cfdata_t match, void *aux)
@@ -273,6 +273,7 @@ uplcom_attach(device_t parent, device_t 
 	DPRINTF("sc=%p", sc, 0, 0, 0);
 
 	sc->sc_dev = self;
+	sc->sc_dying = false;
 
 	aprint_naive("\n");
 	aprint_normal("\n");
@@ -293,7 +294,7 @@ uplcom_attach(device_t parent, device_t 
 	if (err) {
 		aprint_error("\n%s: failed to set configuration, err=%s\n",
 			devname, usbd_errstr(err));
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -317,7 +318,7 @@ uplcom_attach(device_t parent, device_t 
 	if (err) {
 		aprint_error_dev(self, "failed to set configuration: %s\n",
 		    usbd_errstr(err));
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -327,7 +328,7 @@ uplcom_attach(device_t parent, device_t 
 	if (cdesc == NULL) {
 		aprint_error_dev(self,
 		    "failed to get configuration descriptor\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -337,7 +338,7 @@ uplcom_attach(device_t parent, device_t 
 	if (err) {
 		aprint_error("\n%s: failed to get interface, err=%s\n",
 			devname, usbd_errstr(err));
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -351,7 +352,7 @@ uplcom_attach(device_t parent, device_t 
 		if (ed == NULL) {
 			aprint_error_dev(self,
 			    "no endpoint descriptor for %d\n", i);
-			sc->sc_dying = 1;
+			sc->sc_dying = true;
 			return;
 		}
 
@@ -364,7 +365,7 @@ uplcom_attach(device_t parent, device_t 
 
 	if (sc->sc_intr_number== -1) {
 		aprint_error_dev(self, "Could not find interrupt in\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -389,7 +390,7 @@ uplcom_attach(device_t parent, device_t 
 		if (err) {
 			aprint_error("\n%s: failed to get second interface, "
 			    "err=%s\n", devname, usbd_errstr(err));
-			sc->sc_dying = 1;
+			sc->sc_dying = true;
 			return;
 		}
 	}
@@ -404,7 +405,7 @@ uplcom_attach(device_t parent, device_t 
 		if (ed == NULL) {
 			aprint_error_dev(self,
 			    "no endpoint descriptor for %d\n", i);
-			sc->sc_dying = 1;
+			sc->sc_dying = true;
 			return;
 		}
 
@@ -419,13 +420,13 @@ uplcom_attach(device_t parent, device_t 
 
 	if (ucaa.ucaa_bulkin == -1) {
 		aprint_error_dev(self, "Could not find data bulk in\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
 	if (ucaa.ucaa_bulkout == -1) {
 		aprint_error_dev(self, "Could not find data bulk out\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -446,7 +447,7 @@ uplcom_attach(device_t parent, device_t 
 
 	if (err) {
 		aprint_error_dev(self, "reset failed, %s\n", usbd_errstr(err));
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -474,6 +475,21 @@ uplcom_childdet(device_t self, device_t 
 	sc->sc_subdev = NULL;
 }
  
+static void
+uplcom_close_pipe(struct uplcom_softc *sc)
+{
+
+	if (sc->sc_intr_pipe != NULL) {
+		usbd_abort_pipe(sc->sc_intr_pipe);
+		usbd_close_pipe(sc->sc_intr_pipe);
+		sc->sc_intr_pipe = NULL;
+	}
+	if (sc->sc_intr_buf != NULL) {
+		kmem_free(sc->sc_intr_buf, sc->sc_isize);
+		sc->sc_intr_buf = NULL;
+	}
+}
+
 int
 uplcom_detach(device_t self, int flags)
 {
@@ -483,39 +499,22 @@ uplcom_detach(device_t self, int flags)
 	UPLCOMHIST_FUNC(); UPLCOMHIST_CALLED();
 	DPRINTF("sc=%p flags=%d", sc, flags, 0, 0);
 
-	if (sc->sc_intr_pipe != NULL) {
-		usbd_abort_pipe(sc->sc_intr_pipe);
-		usbd_close_pipe(sc->sc_intr_pipe);
-		kmem_free(sc->sc_intr_buf, sc->sc_isize);
-		sc->sc_intr_pipe = NULL;
-	}
+	sc->sc_dying = true;
+ 
+	uplcom_close_pipe(sc);
 
-	sc->sc_dying = 1;
-	if (sc->sc_subdev != NULL)
+	if (sc->sc_subdev != NULL) {
 		rv = config_detach(sc->sc_subdev, flags);
+		sc->sc_subdev = NULL;
+	}
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
 
-	if (rv == 0)
-		pmf_device_deregister(self);
+	pmf_device_deregister(self);
 
 	return rv;
 }
 
-int
-uplcom_activate(device_t self, enum devact act)
-{
-	struct uplcom_softc *sc = device_private(self);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
 usbd_status
 uplcom_reset(struct uplcom_softc *sc)
 {
@@ -592,7 +591,7 @@ uplcom_pl2303x_init(struct uplcom_softc 
 	return 0;
 }
 
-void
+static void
 uplcom_set_line_state(struct uplcom_softc *sc)
 {
 	usb_device_request_t req;
@@ -616,11 +615,14 @@ uplcom_set_line_state(struct uplcom_soft
 	(void)usbd_do_request(sc->sc_udev, &req, 0);
 }
 
-void
+static void
 uplcom_set(void *addr, int portno, int reg, int onoff)
 {
 	struct uplcom_softc *sc = addr;
 
+	if (sc->sc_dying)
+		return;
+
 	switch (reg) {
 	case UCOM_SET_DTR:
 		uplcom_dtr(sc, onoff);
@@ -636,7 +638,7 @@ uplcom_set(void *addr, int portno, int r
 	}
 }
 
-void
+static void
 uplcom_dtr(struct uplcom_softc *sc, int onoff)
 {
 
@@ -651,7 +653,7 @@ uplcom_dtr(struct uplcom_softc *sc, int 
 	uplcom_set_line_state(sc);
 }
 
-void
+static void
 uplcom_rts(struct uplcom_softc *sc, int onoff)
 {
 	UPLCOMHIST_FUNC(); UPLCOMHIST_CALLED();
@@ -665,7 +667,7 @@ uplcom_rts(struct uplcom_softc *sc, int 
 	uplcom_set_line_state(sc);
 }
 
-void
+static void
 uplcom_break(struct uplcom_softc *sc, int onoff)
 {
 	usb_device_request_t req;
@@ -682,7 +684,7 @@ uplcom_break(struct uplcom_softc *sc, in
 	(void)usbd_do_request(sc->sc_udev, &req, 0);
 }
 
-usbd_status
+static usbd_status
 uplcom_set_crtscts(struct uplcom_softc *sc)
 {
 	usb_device_request_t req;
@@ -708,7 +710,7 @@ uplcom_set_crtscts(struct uplcom_softc *
 	return USBD_NORMAL_COMPLETION;
 }
 
-usbd_status
+static usbd_status
 uplcom_set_line_coding(struct uplcom_softc *sc, usb_cdc_line_state_t *state)
 {
 	usb_device_request_t req;
@@ -742,7 +744,7 @@ uplcom_set_line_coding(struct uplcom_sof
 	return USBD_NORMAL_COMPLETION;
 }
 
-int
+static int
 uplcom_param(void *addr, int portno, struct termios *t)
 {
 	struct uplcom_softc *sc = addr;
@@ -752,6 +754,9 @@ uplcom_param(void *addr, int portno, str
 	UPLCOMHIST_FUNC(); UPLCOMHIST_CALLED();
 	DPRINTF("sc=%p", sc, 0, 0, 0);
 
+	if (sc->sc_dying)
+		return EIO;
+
 	USETDW(ls.dwDTERate, t->c_ospeed);
 	if (ISSET(t->c_cflag, CSTOPB))
 		ls.bCharFormat = UCDC_STOP_BIT_2;
@@ -799,7 +804,7 @@ uplcom_param(void *addr, int portno, str
 	return 0;
 }
 
-usbd_status
+static usbd_status
 uplcom_vendor_control_write(struct usbd_device *dev, uint16_t value,
     uint16_t index)
 {
@@ -823,11 +828,11 @@ uplcom_vendor_control_write(struct usbd_
 	return err;
 }
 
-int
+static int
 uplcom_open(void *addr, int portno)
 {
 	struct uplcom_softc *sc = addr;
-	usbd_status err;
+	usbd_status err = 0;
  
 	UPLCOMHIST_FUNC(); UPLCOMHIST_CALLED();
 	DPRINTF("sc=%p", sc, 0, 0, 0);
@@ -853,17 +858,16 @@ uplcom_open(void *addr, int portno)
 		}
 	}
 
-	if (sc->sc_type == UPLCOM_TYPE_HX)
-		return uplcom_pl2303x_init(sc);
+	if (err == 0 && sc->sc_type == UPLCOM_TYPE_HX)
+		err = uplcom_pl2303x_init(sc);
 
-	return 0;
+	return err;
 }
 
-void
+static void
 uplcom_close(void *addr, int portno)
 {
 	struct uplcom_softc *sc = addr;
-	int err;
 
 	UPLCOMHIST_FUNC(); UPLCOMHIST_CALLED();
 	DPRINTF("sc=%p", sc, 0, 0, 0);
@@ -871,21 +875,10 @@ uplcom_close(void *addr, int portno)
 	if (sc->sc_dying)
 		return;
 
-	if (sc->sc_intr_pipe != NULL) {
-		err = usbd_abort_pipe(sc->sc_intr_pipe);
-		if (err)
-			printf("%s: abort interrupt pipe failed: %s\n",
-				device_xname(sc->sc_dev), usbd_errstr(err));
-		err = usbd_close_pipe(sc->sc_intr_pipe);
-		if (err)
-			printf("%s: close interrupt pipe failed: %s\n",
-				device_xname(sc->sc_dev), usbd_errstr(err));
-		kmem_free(sc->sc_intr_buf, sc->sc_isize);
-		sc->sc_intr_pipe = NULL;
-	}
+	uplcom_close_pipe(sc);
 }
 
-void
+static void
 uplcom_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
 {
 	struct uplcom_softc *sc = priv;
@@ -921,19 +914,22 @@ uplcom_intr(struct usbd_xfer *xfer, void
 	ucom_status_change(device_private(sc->sc_subdev));
 }
 
-void
+static void
 uplcom_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
 {
 	struct uplcom_softc *sc = addr;
 
 	UPLCOMHIST_FUNC(); UPLCOMHIST_CALLED();
 
+	if (sc->sc_dying)
+		return;
+
 	*lsr = sc->sc_lsr;
 	*msr = sc->sc_msr;
 }
 
 #if TODO
-int
+static int
 uplcom_ioctl(void *addr, int portno, u_long cmd, void *data, int flag,
 	     proc_t *p)
 {

Index: src/sys/dev/usb/uslsa.c
diff -u src/sys/dev/usb/uslsa.c:1.27 src/sys/dev/usb/uslsa.c:1.28
--- src/sys/dev/usb/uslsa.c:1.27	Sat May  4 08:04:13 2019
+++ src/sys/dev/usb/uslsa.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: uslsa.c,v 1.27 2019/05/04 08:04:13 mrg Exp $ */
+/* $NetBSD: uslsa.c,v 1.28 2019/05/09 02:43:35 mrg Exp $ */
 
 /* from ugensa.c */
 
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uslsa.c,v 1.27 2019/05/04 08:04:13 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uslsa.c,v 1.28 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -103,7 +103,6 @@ static void uslsa_get_status(void *sc, i
 static void uslsa_set(void *, int, int, int);
 static int uslsa_param(void *, int, struct termios *);
 static int uslsa_ioctl(void *, int, u_long, void *, int, proc_t *);
-
 static int uslsa_open(void *, int);
 static void uslsa_close(void *, int);
 
@@ -149,10 +148,9 @@ static int uslsa_match(device_t, cfdata_
 static void uslsa_attach(device_t, device_t, void *);
 static void uslsa_childdet(device_t, device_t);
 static int uslsa_detach(device_t, int);
-static int uslsa_activate(device_t, enum devact);
 
 CFATTACH_DECL2_NEW(uslsa, sizeof(struct uslsa_softc), uslsa_match,
-    uslsa_attach, uslsa_detach, uslsa_activate, NULL, uslsa_childdet);
+    uslsa_attach, uslsa_detach, NULL, NULL, uslsa_childdet);
 
 static int
 uslsa_match(device_t parent, cfdata_t match, void *aux)
@@ -182,6 +180,7 @@ uslsa_attach(device_t parent, device_t s
 	sc->sc_dev = self;
 	sc->sc_udev = uiaa->uiaa_device;
 	sc->sc_iface = uiaa->uiaa_iface;
+	sc->sc_dying = false;
 
 	aprint_naive("\n");
 	aprint_normal("\n");
@@ -246,20 +245,6 @@ uslsa_attach(device_t parent, device_t s
 	return;
 }
 
-static int
-uslsa_activate(device_t self, enum devact act)
-{
-	struct uslsa_softc *sc = device_private(self);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = true;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
 static void
 uslsa_childdet(device_t self, device_t child)
 {
@@ -281,6 +266,7 @@ uslsa_detach(device_t self, int flags)
 
 	if (sc->sc_subdev != NULL) {
 		rv = config_detach(sc->sc_subdev, flags);
+		sc->sc_subdev = NULL;
 	}
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
@@ -313,9 +299,8 @@ uslsa_get_status(void *vsc, int portno, 
 
 	DPRINTF((sc->sc_dev, "%s(%p, %d, ....)\n", __func__, vsc, portno));
 
-	if (sc->sc_dying) {
+	if (sc->sc_dying)
 		return;
-	}
 
 	req.bmRequestType = UT_READ_VENDOR_INTERFACE;
 	req.bRequest = SLSA_R_GET_MDMSTS;
@@ -350,9 +335,8 @@ uslsa_set(void *vsc, int portno, int reg
 	DPRINTF((sc->sc_dev, "%s(%p, %d, %d, %d)\n", __func__, vsc, portno,
 	    reg, onoff));
 
-	if (sc->sc_dying) {
+	if (sc->sc_dying)
 		return;
-	}
 
 	switch (reg) {
 	case UCOM_SET_DTR:
@@ -395,9 +379,8 @@ uslsa_param(void *vsc, int portno, struc
 
 	DPRINTF((sc->sc_dev, "%s(%p, %d, %p)\n", __func__, vsc, portno, t));
 
-	if (sc->sc_dying) {
+	if (sc->sc_dying)
 		return EIO;
-	}
 
 	req.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
 	req.bRequest = SLSA_R_SET_BAUDRATE;
@@ -477,6 +460,9 @@ uslsa_ioctl(void *vsc, int portno, u_lon
 
 	sc = vsc;
 
+	if (sc->sc_dying)
+		return EIO;
+
 	switch (cmd) {
 	case TIOCMGET:
 		ucom_status_change(device_private(sc->sc_subdev));
@@ -497,9 +483,8 @@ uslsa_open(void *vsc, int portno)
 
 	DPRINTF((sc->sc_dev, "%s(%p, %d)\n", __func__, vsc, portno));
 
-	if (sc->sc_dying) {
+	if (sc->sc_dying)
 		return EIO;
-	}
 
 	return uslsa_request_set(sc, SLSA_R_IFC_ENABLE,
 	    SLSA_RV_IFC_ENABLE_ENABLE);
@@ -514,12 +499,10 @@ uslsa_close(void *vsc, int portno)
 
 	DPRINTF((sc->sc_dev, "%s(%p, %d)\n", __func__, vsc, portno));
 
-	if (sc->sc_dying) {
+	if (sc->sc_dying)
 		return;
-	}
 
-	(void)uslsa_request_set(sc, SLSA_R_IFC_ENABLE,
-	    SLSA_RV_IFC_ENABLE_DISABLE);
+	uslsa_request_set(sc, SLSA_R_IFC_ENABLE, SLSA_RV_IFC_ENABLE_DISABLE);
 }
 
 static int

Index: src/sys/dev/usb/uvisor.c
diff -u src/sys/dev/usb/uvisor.c:1.50 src/sys/dev/usb/uvisor.c:1.51
--- src/sys/dev/usb/uvisor.c:1.50	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/uvisor.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvisor.c,v 1.50 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: uvisor.c,v 1.51 2019/05/09 02:43:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvisor.c,v 1.50 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvisor.c,v 1.51 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -142,17 +142,18 @@ struct uvisor_softc {
 
 	uint16_t		sc_flags;
 
-	u_char			sc_dying;
+	bool			sc_dying;
 };
 
-Static usbd_status uvisor_init(struct uvisor_softc *,
+static usbd_status uvisor_init(struct uvisor_softc *,
 			       struct uvisor_connection_info *,
 			       struct uvisor_palm_connection_info *);
 
-Static void uvisor_close(void *, int);
-
+static int uvisor_open(void *, int);
+static void uvisor_close(void *, int);
 
 struct ucom_methods uvisor_methods = {
+	.ucom_open = uvisor_open,
 	.ucom_close = uvisor_close,
 };
 
@@ -186,16 +187,15 @@ static const struct uvisor_type uvisor_d
 };
 #define uvisor_lookup(v, p) ((const struct uvisor_type *)usb_lookup(uvisor_devs, v, p))
 
-int uvisor_match(device_t, cfdata_t, void *);
-void uvisor_attach(device_t, device_t, void *);
-void uvisor_childdet(device_t, device_t);
-int uvisor_detach(device_t, int);
-int uvisor_activate(device_t, enum devact);
+static int	uvisor_match(device_t, cfdata_t, void *);
+static void	uvisor_attach(device_t, device_t, void *);
+static void	uvisor_childdet(device_t, device_t);
+static int	uvisor_detach(device_t, int);
 
 CFATTACH_DECL2_NEW(uvisor, sizeof(struct uvisor_softc), uvisor_match,
-    uvisor_attach, uvisor_detach, uvisor_activate, NULL, uvisor_childdet);
+    uvisor_attach, uvisor_detach, NULL, NULL, uvisor_childdet);
 
-int
+static int
 uvisor_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct usb_attach_arg *uaa = aux;
@@ -207,7 +207,7 @@ uvisor_match(device_t parent, cfdata_t m
 		UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
 }
 
-void
+static void
 uvisor_attach(device_t parent, device_t self, void *aux)
 {
 	struct uvisor_softc *sc = device_private(self);
@@ -227,6 +227,7 @@ uvisor_attach(device_t parent, device_t 
 	DPRINTFN(10,("\nuvisor_attach: sc=%p\n", sc));
 
 	sc->sc_dev = self;
+	sc->sc_dying = false;
 
 	aprint_naive("\n");
 	aprint_normal("\n");
@@ -368,25 +369,11 @@ uvisor_attach(device_t parent, device_t 
 
 bad:
 	DPRINTF(("uvisor_attach: ATTACH ERROR\n"));
-	sc->sc_dying = 1;
+	sc->sc_dying = true;
 	return;
 }
 
-int
-uvisor_activate(device_t self, enum devact act)
-{
-	struct uvisor_softc *sc = device_private(self);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
-void
+static void
 uvisor_childdet(device_t self, device_t child)
 {
 	int i;
@@ -400,7 +387,7 @@ uvisor_childdet(device_t self, device_t 
 	sc->sc_subdevs[i] = NULL;
 }
 
-int
+static int
 uvisor_detach(device_t self, int flags)
 {
 	struct uvisor_softc *sc = device_private(self);
@@ -408,21 +395,22 @@ uvisor_detach(device_t self, int flags)
 	int i;
 
 	DPRINTF(("uvisor_detach: sc=%p flags=%d\n", sc, flags));
-	sc->sc_dying = 1;
+
+	sc->sc_dying = true;
+
 	for (i = 0; i < sc->sc_numcon; i++) {
-		if (sc->sc_subdevs[i] != NULL)
+		if (sc->sc_subdevs[i] != NULL) {
 			rv |= config_detach(sc->sc_subdevs[i], flags);
+			sc->sc_subdevs[i] = NULL;
+		}
 	}
 
-	if (sc->sc_udev)
-		usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
-				   sc->sc_dev);
-
+	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
 
 	return rv;
 }
 
-usbd_status
+static usbd_status
 uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci,
     struct uvisor_palm_connection_info *cpi)
 {
@@ -472,6 +460,17 @@ uvisor_init(struct uvisor_softc *sc, str
 	return err;
 }
 
+static int
+uvisor_open(void *arg, int portno)
+{
+	struct uvisor_softc *sc = arg;
+
+	if (sc->sc_dying)
+		return EIO;
+
+	return 0;
+}
+
 void
 uvisor_close(void *addr, int portno)
 {

Index: src/sys/dev/usb/uvscom.c
diff -u src/sys/dev/usb/uvscom.c:1.34 src/sys/dev/usb/uvscom.c:1.35
--- src/sys/dev/usb/uvscom.c:1.34	Sun May  5 03:17:54 2019
+++ src/sys/dev/usb/uvscom.c	Thu May  9 02:43:35 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvscom.c,v 1.34 2019/05/05 03:17:54 mrg Exp $	*/
+/*	$NetBSD: uvscom.c,v 1.35 2019/05/09 02:43:35 mrg Exp $	*/
 /*-
  * Copyright (c) 2001-2002, Shunsuke Akiyama <akiy...@jp.freebsd.org>.
  * All rights reserved.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvscom.c,v 1.34 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvscom.c,v 1.35 2019/05/09 02:43:35 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -160,7 +160,7 @@ struct	uvscom_softc {
 	u_char			sc_usr;		/* unit status */
 
 	device_t		sc_subdev;	/* ucom device */
-	u_char			sc_dying;	/* disconnecting */
+	bool			sc_dying;	/* disconnecting */
 };
 
 /*
@@ -170,23 +170,23 @@ struct	uvscom_softc {
 #define UVSCOMIBUFSIZE 512
 #define UVSCOMOBUFSIZE 64
 
-Static	usbd_status uvscom_readstat(struct uvscom_softc *);
-Static	usbd_status uvscom_shutdown(struct uvscom_softc *);
-Static	usbd_status uvscom_reset(struct uvscom_softc *);
-Static	usbd_status uvscom_set_line_coding(struct uvscom_softc *,
+static	usbd_status uvscom_readstat(struct uvscom_softc *);
+static	usbd_status uvscom_shutdown(struct uvscom_softc *);
+static	usbd_status uvscom_reset(struct uvscom_softc *);
+static	usbd_status uvscom_set_line_coding(struct uvscom_softc *,
 					   uint16_t, uint16_t);
-Static	usbd_status uvscom_set_line(struct uvscom_softc *, uint16_t);
-Static	usbd_status uvscom_set_crtscts(struct uvscom_softc *);
-Static	void uvscom_get_status(void *, int, u_char *, u_char *);
-Static	void uvscom_dtr(struct uvscom_softc *, int);
-Static	void uvscom_rts(struct uvscom_softc *, int);
-Static	void uvscom_break(struct uvscom_softc *, int);
-
-Static	void uvscom_set(void *, int, int, int);
-Static	void uvscom_intr(struct usbd_xfer *, void *, usbd_status);
-Static	int  uvscom_param(void *, int, struct termios *);
-Static	int  uvscom_open(void *, int);
-Static	void uvscom_close(void *, int);
+static	usbd_status uvscom_set_line(struct uvscom_softc *, uint16_t);
+static	usbd_status uvscom_set_crtscts(struct uvscom_softc *);
+static	void uvscom_get_status(void *, int, u_char *, u_char *);
+static	void uvscom_dtr(struct uvscom_softc *, int);
+static	void uvscom_rts(struct uvscom_softc *, int);
+static	void uvscom_break(struct uvscom_softc *, int);
+
+static	void uvscom_set(void *, int, int, int);
+static	void uvscom_intr(struct usbd_xfer *, void *, usbd_status);
+static	int  uvscom_param(void *, int, struct termios *);
+static	int  uvscom_open(void *, int);
+static	void uvscom_close(void *, int);
 
 struct ucom_methods uvscom_methods = {
 	.ucom_get_status = uvscom_get_status,
@@ -215,10 +215,9 @@ int uvscom_match(device_t, cfdata_t, voi
 void uvscom_attach(device_t, device_t, void *);
 void uvscom_childdet(device_t, device_t);
 int uvscom_detach(device_t, int);
-int uvscom_activate(device_t, enum devact);
 
 CFATTACH_DECL2_NEW(uvscom, sizeof(struct uvscom_softc), uvscom_match,
-    uvscom_attach, uvscom_detach, uvscom_activate, NULL, uvscom_childdet);
+    uvscom_attach, uvscom_detach, NULL, NULL, uvscom_childdet);
 
 int
 uvscom_match(device_t parent, cfdata_t match, void *aux)
@@ -251,7 +250,8 @@ uvscom_attach(device_t parent, device_t 
 	usbd_devinfo_free(devinfop);
 
 	sc->sc_dev = self;
-        sc->sc_udev = dev;
+	sc->sc_udev = dev;
+	sc->sc_dying = false;
 
 	DPRINTF(("uvscom attach: sc = %p\n", sc));
 
@@ -265,7 +265,7 @@ uvscom_attach(device_t parent, device_t 
 	if (err) {
 		aprint_error_dev(self, "failed to set configuration, err=%s\n",
 		    usbd_errstr(err));
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -275,7 +275,7 @@ uvscom_attach(device_t parent, device_t 
 	if (cdesc == NULL) {
 		aprint_error_dev(self,
 		    "failed to get configuration descriptor\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -285,7 +285,7 @@ uvscom_attach(device_t parent, device_t 
 	if (err) {
 		aprint_error_dev(self, "failed to get interface, err=%s\n",
 		    usbd_errstr(err));
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -298,7 +298,7 @@ uvscom_attach(device_t parent, device_t 
 		if (ed == NULL) {
 			aprint_error_dev(self,
 			    "no endpoint descriptor for %d\n", i);
-			sc->sc_dying = 1;
+			sc->sc_dying = true;
 			return;
 		}
 
@@ -317,17 +317,17 @@ uvscom_attach(device_t parent, device_t 
 
 	if (ucaa.ucaa_bulkin == -1) {
 		aprint_error_dev(self, "Could not find data bulk in\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 	if (ucaa.ucaa_bulkout == -1) {
 		aprint_error_dev(self, "Could not find data bulk out\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 	if (sc->sc_intr_number == -1) {
 		aprint_error_dev(self, "Could not find interrupt in\n");
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -350,7 +350,7 @@ uvscom_attach(device_t parent, device_t 
 
 	if (err) {
 		aprint_error_dev(self, "reset failed, %s\n", usbd_errstr(err));
-		sc->sc_dying = 1;
+		sc->sc_dying = true;
 		return;
 	}
 
@@ -376,47 +376,44 @@ uvscom_childdet(device_t self, device_t 
 	sc->sc_subdev = NULL;
 }
 
-int
-uvscom_detach(device_t self, int flags)
+static void 
+uvscom_close_pipe(struct uvscom_softc *sc)
 {
-	struct uvscom_softc *sc = device_private(self);
-	int rv = 0;
-
-	DPRINTF(("uvscom_detach: sc = %p\n", sc));
-
-	sc->sc_dying = 1;
 
 	if (sc->sc_intr_pipe != NULL) {
 		usbd_abort_pipe(sc->sc_intr_pipe);
 		usbd_close_pipe(sc->sc_intr_pipe);
-		kmem_free(sc->sc_intr_buf, sc->sc_isize);
 		sc->sc_intr_pipe = NULL;
 	}
-
-	sc->sc_dying = 1;
-	if (sc->sc_subdev != NULL)
-		rv = config_detach(sc->sc_subdev, flags);
-
-	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
-
-	return rv;
+	if (sc->sc_intr_buf) {
+		kmem_free(sc->sc_intr_buf, sc->sc_isize);
+		sc->sc_intr_buf = NULL;
+	}
 }
 
 int
-uvscom_activate(device_t self, enum devact act)
+uvscom_detach(device_t self, int flags)
 {
 	struct uvscom_softc *sc = device_private(self);
+	int rv = 0;
 
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
+	DPRINTF(("uvscom_detach: sc = %p\n", sc));
+
+	sc->sc_dying = true;
+ 
+	uvscom_close_pipe(sc);
+
+	if (sc->sc_subdev != NULL) {
+		rv = config_detach(sc->sc_subdev, flags);
+		sc->sc_subdev = NULL;
 	}
+
+	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
+
+	return rv;
 }
 
-Static usbd_status
+static usbd_status
 uvscom_readstat(struct uvscom_softc *sc)
 {
 	usb_device_request_t req;
@@ -444,7 +441,7 @@ uvscom_readstat(struct uvscom_softc *sc)
 	return USBD_NORMAL_COMPLETION;
 }
 
-Static usbd_status
+static usbd_status
 uvscom_shutdown(struct uvscom_softc *sc)
 {
 	usb_device_request_t req;
@@ -468,7 +465,7 @@ uvscom_shutdown(struct uvscom_softc *sc)
 	return USBD_NORMAL_COMPLETION;
 }
 
-Static usbd_status
+static usbd_status
 uvscom_reset(struct uvscom_softc *sc)
 {
 	DPRINTF(("%s: uvscom_reset\n", device_xname(sc->sc_dev)));
@@ -476,7 +473,7 @@ uvscom_reset(struct uvscom_softc *sc)
 	return USBD_NORMAL_COMPLETION;
 }
 
-Static usbd_status
+static usbd_status
 uvscom_set_crtscts(struct uvscom_softc *sc)
 {
 	DPRINTF(("%s: uvscom_set_crtscts\n", device_xname(sc->sc_dev)));
@@ -484,7 +481,7 @@ uvscom_set_crtscts(struct uvscom_softc *
 	return USBD_NORMAL_COMPLETION;
 }
 
-Static usbd_status
+static usbd_status
 uvscom_set_line(struct uvscom_softc *sc, uint16_t line)
 {
 	usb_device_request_t req;
@@ -509,7 +506,7 @@ uvscom_set_line(struct uvscom_softc *sc,
 	return USBD_NORMAL_COMPLETION;
 }
 
-Static usbd_status
+static usbd_status
 uvscom_set_line_coding(struct uvscom_softc *sc, uint16_t lsp, uint16_t ls)
 {
 	usb_device_request_t req;
@@ -547,7 +544,7 @@ uvscom_set_line_coding(struct uvscom_sof
 	return USBD_NORMAL_COMPLETION;
 }
 
-Static void
+static void
 uvscom_dtr(struct uvscom_softc *sc, int onoff)
 {
 	DPRINTF(("%s: uvscom_dtr: onoff = %d\n",
@@ -566,7 +563,7 @@ uvscom_dtr(struct uvscom_softc *sc, int 
 	uvscom_set_line(sc, sc->sc_lcr);
 }
 
-Static void
+static void
 uvscom_rts(struct uvscom_softc *sc, int onoff)
 {
 	DPRINTF(("%s: uvscom_rts: onoff = %d\n",
@@ -585,7 +582,7 @@ uvscom_rts(struct uvscom_softc *sc, int 
 	uvscom_set_line(sc, sc->sc_lcr);
 }
 
-Static void
+static void
 uvscom_break(struct uvscom_softc *sc, int onoff)
 {
 	DPRINTF(("%s: uvscom_break: onoff = %d\n",
@@ -595,11 +592,14 @@ uvscom_break(struct uvscom_softc *sc, in
 		uvscom_set_line(sc, SET(sc->sc_lcr, UVSCOM_BREAK));
 }
 
-Static void
+static void
 uvscom_set(void *addr, int portno, int reg, int onoff)
 {
 	struct uvscom_softc *sc = addr;
 
+	if (sc->sc_dying)
+		return;
+
 	switch (reg) {
 	case UCOM_SET_DTR:
 		uvscom_dtr(sc, onoff);
@@ -615,7 +615,7 @@ uvscom_set(void *addr, int portno, int r
 	}
 }
 
-Static int
+static int
 uvscom_param(void *addr, int portno, struct termios *t)
 {
 	struct uvscom_softc *sc = addr;
@@ -626,6 +626,9 @@ uvscom_param(void *addr, int portno, str
 	DPRINTF(("%s: uvscom_param: sc = %p\n",
 		 device_xname(sc->sc_dev), sc));
 
+	if (sc->sc_dying)
+		return EIO;
+
 	ls = 0;
 
 	switch (t->c_ospeed) {
@@ -709,7 +712,7 @@ uvscom_param(void *addr, int portno, str
 	return 0;
 }
 
-Static int
+static int
 uvscom_open(void *addr, int portno)
 {
 	struct uvscom_softc *sc = addr;
@@ -778,36 +781,21 @@ uvscom_open(void *addr, int portno)
 	return 0;
 }
 
-Static void
+static void
 uvscom_close(void *addr, int portno)
 {
 	struct uvscom_softc *sc = addr;
-	int err;
-
-	if (sc->sc_dying)
-		return;
 
 	DPRINTF(("uvscom_close: close\n"));
 
-	uvscom_shutdown(sc);
+	if (sc->sc_dying) 
+		return;
 
-	if (sc->sc_intr_pipe != NULL) {
-		err = usbd_abort_pipe(sc->sc_intr_pipe);
-		if (err)
-			aprint_error_dev(sc->sc_dev,
-			    "abort interrupt pipe failed: %s\n",
-			    usbd_errstr(err));
-		err = usbd_close_pipe(sc->sc_intr_pipe);
-		if (err)
-			aprint_error_dev(sc->sc_dev,
-			    "lose interrupt pipe failed: %s\n",
-			    usbd_errstr(err));
-		kmem_free(sc->sc_intr_buf, sc->sc_isize);
-		sc->sc_intr_pipe = NULL;
-	}
+	uvscom_shutdown(sc);
+	uvscom_close_pipe(sc);
 }
 
-Static void
+static void
 uvscom_intr(struct usbd_xfer *xfer, void *priv,
     usbd_status status)
 {
@@ -852,12 +840,14 @@ uvscom_intr(struct usbd_xfer *xfer, void
 	ucom_status_change(device_private(sc->sc_subdev));
 }
 
-Static void
+static void
 uvscom_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
 {
 	struct uvscom_softc *sc = addr;
 
+	if (sc->sc_dying)
+		return;
+
 	*lsr = sc->sc_lsr;
 	*msr = sc->sc_msr;
 }
-

Reply via email to