clean up ucom parents: - 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 Index: u3g.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/u3g.c,v retrieving revision 1.36 diff -p -u -u -r1.36 u3g.c --- u3g.c 4 May 2019 08:04:13 -0000 1.36 +++ u3g.c 8 May 2019 06:31:39 -0000 @@ -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,33 +429,33 @@ static int u3g_detach(device_t self, int flags) { struct u3g_softc *sc = device_private(self); - int rv; + int rv = 0; - if (sc->sc_dying) - return 0; + sc->sc_dying = true; - pmf_device_deregister(self); + 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_buff != NULL) { + kmem_free(sc->sc_intr_buff, sc->sc_intr_size); + sc->sc_intr_buff = NULL; + } 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); + 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_com[i].c_dev = NULL; } - if (sc->sc_intr_pipe != NULL) { - (void) usbd_abort_pipe(sc->sc_intr_pipe); - (void) usbd_close_pipe(sc->sc_intr_pipe); - sc->sc_intr_pipe = NULL; - } - if (sc->sc_intr_buff != NULL) { - kmem_free(sc->sc_intr_buff, sc->sc_intr_size); - sc->sc_intr_buff = NULL; - } + pmf_device_deregister(self); - return 0; + return rv; } static void @@ -470,29 +468,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 +577,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: uark.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uark.c,v retrieving revision 1.14 diff -p -u -u -r1.14 uark.c --- uark.c 5 May 2019 03:17:54 -0000 1.14 +++ uark.c 8 May 2019 06:31:39 -0000 @@ -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: ubsa.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ubsa.c,v retrieving revision 1.37 diff -p -u -u -r1.37 ubsa.c --- ubsa.c 5 May 2019 03:17:54 -0000 1.37 +++ ubsa.c 8 May 2019 06:31:39 -0000 @@ -1,4 +1,5 @@ /* $NetBSD: ubsa.c,v 1.37 2019/05/05 03:17:54 mrg Exp $ */ + /*- * Copyright (c) 2002, Alexander Kabaev . * All rights reserved. @@ -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: ubsa_common.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ubsa_common.c,v retrieving revision 1.11 diff -p -u -u -r1.11 ubsa_common.c --- ubsa_common.c 4 May 2019 08:04:13 -0000 1.11 +++ ubsa_common.c 8 May 2019 06:31:39 -0000 @@ -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: ubsavar.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ubsavar.h,v retrieving revision 1.10 diff -p -u -u -r1.10 ubsavar.h --- ubsavar.h 23 Apr 2016 10:15:32 -0000 1.10 +++ ubsavar.h 8 May 2019 06:31:39 -0000 @@ -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: uchcom.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uchcom.c,v retrieving revision 1.32 diff -p -u -u -r1.32 uchcom.c --- uchcom.c 6 May 2019 23:46:25 -0000 1.32 +++ uchcom.c 8 May 2019 06:31:39 -0000 @@ -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: ucom.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ucom.c,v retrieving revision 1.124 diff -p -u -u -r1.124 ucom.c --- ucom.c 5 May 2019 03:17:54 -0000 1.124 +++ ucom.c 8 May 2019 06:31:39 -0000 @@ -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: ucomvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ucomvar.h,v retrieving revision 1.22 diff -p -u -u -r1.22 ucomvar.h --- ucomvar.h 4 May 2019 08:04:13 -0000 1.22 +++ ucomvar.h 8 May 2019 06:31:39 -0000 @@ -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: uftdi.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uftdi.c,v retrieving revision 1.69 diff -p -u -u -r1.69 uftdi.c --- uftdi.c 5 May 2019 03:17:54 -0000 1.69 +++ uftdi.c 8 May 2019 06:31:39 -0000 @@ -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: ugensa.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ugensa.c,v retrieving revision 1.38 diff -p -u -u -r1.38 ugensa.c --- ugensa.c 5 May 2019 03:17:54 -0000 1.38 +++ ugensa.c 8 May 2019 06:31:39 -0000 @@ -68,11 +68,13 @@ struct ugensa_softc { device_t sc_subdev; int sc_numcon; - u_char sc_dying; + bool sc_dying; }; +static int ugensa_open(void *, int); + struct ucom_methods ugensa_methods = { - .ucom_get_status = NULL, + .ucom_open = ugensa_open, }; #define UGENSA_CONFIG_INDEX 0 @@ -107,16 +109,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 +129,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 +147,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 +242,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 +255,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 +263,27 @@ 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; } + +static int +ugensa_open(void *arg, int portno) +{ + struct ugensa_softc *sc = arg; + + if (sc->sc_dying) + return EIO; + + return 0; +} Index: uhmodem.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uhmodem.c,v retrieving revision 1.18 diff -p -u -u -r1.18 uhmodem.c --- uhmodem.c 4 May 2019 23:36:14 -0000 1.18 +++ uhmodem.c 8 May 2019 06:31:39 -0000 @@ -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: uipaq.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uipaq.c,v retrieving revision 1.24 diff -p -u -u -r1.24 uipaq.c --- uipaq.c 5 May 2019 03:17:54 -0000 1.24 +++ uipaq.c 8 May 2019 06:31:39 -0000 @@ -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: ukyopon.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ukyopon.c,v retrieving revision 1.23 diff -p -u -u -r1.23 ukyopon.c --- ukyopon.c 5 May 2019 03:17:54 -0000 1.23 +++ ukyopon.c 8 May 2019 06:31:39 -0000 @@ -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: umcs.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/umcs.c,v retrieving revision 1.12 diff -p -u -u -r1.12 umcs.c --- umcs.c 3 Aug 2018 13:19:33 -0000 1.12 +++ umcs.c 8 May 2019 06:31:39 -0000 @@ -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: umct.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/umct.c,v retrieving revision 1.38 diff -p -u -u -r1.38 umct.c --- umct.c 5 May 2019 03:17:54 -0000 1.38 +++ umct.c 8 May 2019 06:31:39 -0000 @@ -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: umodem.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/umodem.c,v retrieving revision 1.71 diff -p -u -u -r1.71 umodem.c --- umodem.c 5 May 2019 03:17:54 -0000 1.71 +++ umodem.c 8 May 2019 06:31:39 -0000 @@ -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: umodem_common.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/umodem_common.c,v retrieving revision 1.29 diff -p -u -u -r1.29 umodem_common.c --- umodem_common.c 6 May 2019 23:47:39 -0000 1.29 +++ umodem_common.c 8 May 2019 06:31:39 -0000 @@ -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: umodemvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/umodemvar.h,v retrieving revision 1.11 diff -p -u -u -r1.11 umodemvar.h --- umodemvar.h 6 May 2019 23:47:39 -0000 1.11 +++ umodemvar.h 8 May 2019 06:31:39 -0000 @@ -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: uplcom.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uplcom.c,v retrieving revision 1.83 diff -p -u -u -r1.83 uplcom.c --- uplcom.c 7 May 2019 05:17:22 -0000 1.83 +++ uplcom.c 8 May 2019 06:31:39 -0000 @@ -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: uslsa.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uslsa.c,v retrieving revision 1.27 diff -p -u -u -r1.27 uslsa.c --- uslsa.c 4 May 2019 08:04:13 -0000 1.27 +++ uslsa.c 8 May 2019 06:31:39 -0000 @@ -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: uvisor.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uvisor.c,v retrieving revision 1.50 diff -p -u -u -r1.50 uvisor.c --- uvisor.c 5 May 2019 03:17:54 -0000 1.50 +++ uvisor.c 8 May 2019 06:31:39 -0000 @@ -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: uvscom.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uvscom.c,v retrieving revision 1.34 diff -p -u -u -r1.34 uvscom.c --- uvscom.c 5 May 2019 03:17:54 -0000 1.34 +++ uvscom.c 8 May 2019 06:31:39 -0000 @@ -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; } -