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
This commit is contained in:
mrg 2019-05-09 02:43:35 +00:00
parent d3665a665f
commit cc0cad1ec6
22 changed files with 623 additions and 770 deletions

View File

@ -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 self, void *aux)
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;
int rv = 0;
if (sc->sc_dying)
return 0;
pmf_device_deregister(self);
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 child)
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)

View File

@ -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 match, void *aux)
!= 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 self, void *aux)
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 self, void *aux)
&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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 onoff)
}
}
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 termios *t)
#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 termios *t)
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 onoff)
#endif
}
int
static int
uark_cmd(struct uark_softc *sc, uint16_t index, uint16_t value)
{
usb_device_request_t req;

View File

@ -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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
&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 self, void *aux)
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 self, void *aux)
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;
}
}

View File

@ -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 portno, int onoff)
{
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, struct termios *ti)
{
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);
@ -368,31 +376,32 @@ ubsa_open(void *addr, int portno)
return 0;
}
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

View File

@ -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);

View File

@ -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 match, void *aux)
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 self, void *aux)
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 child)
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, struct termios *t)
int ret;
if (sc->sc_dying)
return 0;
return EIO;
ret = set_line_control(sc, t->c_cflag);
if (ret)

View File

@ -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)
{

View File

@ -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.
@ -36,6 +36,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.

View File

@ -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 match, void *aux)
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 self, void *aux)
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 self, void *aux)
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 child)
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, uint32_t *count)
*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_char *to, u_char *from, uint32_t *count)
*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, int onoff)
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, int onoff)
(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, struct termios *t)
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, u_char *lsr, u_char *msr)
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;

View File

@ -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_devs[] = {
#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 match, void *aux)
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 self, void *aux)
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 self, void *aux)
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 child)
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;
}

View File

@ -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 <yuo@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, cfdata_t, void *);
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
"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 self, void *aux)
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 self, void *aux)
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,
@ -421,50 +412,39 @@ uhmodem_detach(device_t self, int flags)
return rv;
}
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

View File

@ -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 self, void *aux)
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 self, void *aux)
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 reg, int onoff)
{
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 reg, int onoff)
}
}
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;
}

View File

@ -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_methods = {
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 portno, u_char *lsr, u_char *msr)
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,21 +208,13 @@ ukyopon_ioctl(void *addr, int portno, u_long cmd, void *data, int flag,
break;
default:
error = umodem_ioctl(addr, portno, cmd, data, flag, p);
error = umodem_ioctl(&sc->sc_umodem, portno, cmd, data, flag, p);
break;
}
return error;
}
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)
{

View File

@ -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, device_t, void *);
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_devs[] = {
#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_t self, void *aux)
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_t self, void *aux)
&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_t self, void *aux)
}
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_t self, void *aux)
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_t self, void *aux)
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, struct termios *t)
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, void *priv,
int actlen;
int subunit;
if (sc->sc_dying)
return;
if (status == USBD_NOT_STARTED || status == USBD_CANCELLED
|| status == USBD_IOERROR)
return;

View File

@ -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_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_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 match, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
return;
}
void
static void
umct_childdet(device_t self, device_t child)
{
struct umct_softc *sc = device_private(self);
@ -316,7 +316,22 @@ umct_childdet(device_t self, device_t child)
sc->sc_subdev = NULL;
}
int
static void
umct_close_pipe(struct umct_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;
}
}
static int
umct_detach(device_t self, int flags)
{
struct umct_softc *sc = device_private(self);
@ -324,37 +339,21 @@ umct_detach(device_t self, int flags)
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 = true;
sc->sc_dying = 1;
if (sc->sc_subdev != NULL)
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;
}
int
umct_activate(device_t self, enum devact act)
{
struct umct_softc *sc = device_private(self);
switch (act) {
case DVACT_DEACTIVATE:
sc->sc_dying = 1;
return 0;
default:
return EOPNOTSUPP;
}
}
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 *sc)
(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, u_int rate)
(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, u_char *lsr, u_char *msr)
DPRINTF(("umct_get_status:\n"));
if (sc->sc_dying)
return;
*lsr = sc->sc_lsr;
*msr = sc->sc_msr;
}

View File

@ -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_methods = {
.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 match, void *aux)
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 self, void *aux)
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);

View File

@ -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, struct termios *t)
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_long cmd, void *data,
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_softc *sc, int feature, int state)
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, int flags)
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);

View File

@ -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 termios *);
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);

View File

@ -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, void *);
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 child)
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 *sc)
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_softc *sc)
(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 reg, int onoff)
}
}
void
static void
uplcom_dtr(struct uplcom_softc *sc, int onoff)
{
@ -651,7 +653,7 @@ uplcom_dtr(struct uplcom_softc *sc, int onoff)
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 onoff)
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, int onoff)
(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 *sc)
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_softc *sc, usb_cdc_line_state_t *state)
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, struct termios *t)
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, struct termios *t)
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_device *dev, uint16_t value,
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 *priv, usbd_status status)
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)
{

View File

@ -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, int, u_char *, u_char *);
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_t, void *);
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 self, void *aux)
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 self, void *aux)
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, u_char *lsr, u_char *msr)
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, int onoff)
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, struct termios *t)
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_long cmd, void *data, int flag, proc_t *p)
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

View File

@ -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_devs[] = {
};
#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 match, void *aux)
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 self, void *aux)
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 self, void *aux)
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 child)
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, struct uvisor_connection_info *ci,
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)
{

View File

@ -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 <akiyama@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 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 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, void *);
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
if (err) {
aprint_error_dev(self, "reset failed, %s\n", usbd_errstr(err));
sc->sc_dying = 1;
sc->sc_dying = true;
return;
}
@ -376,6 +376,21 @@ uvscom_childdet(device_t self, device_t child)
sc->sc_subdev = NULL;
}
static void
uvscom_close_pipe(struct uvscom_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;
}
}
int
uvscom_detach(device_t self, int flags)
{
@ -384,39 +399,21 @@ uvscom_detach(device_t self, int flags)
DPRINTF(("uvscom_detach: sc = %p\n", sc));
sc->sc_dying = 1;
sc->sc_dying = true;
uvscom_close_pipe(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 = 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);
return rv;
}
int
uvscom_activate(device_t self, enum devact act)
{
struct uvscom_softc *sc = device_private(self);
switch (act) {
case DVACT_DEACTIVATE:
sc->sc_dying = 1;
return 0;
default:
return EOPNOTSUPP;
}
}
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 *sc)
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, uint16_t line)
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_softc *sc, uint16_t lsp, uint16_t ls)
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 onoff)
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 onoff)
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, int onoff)
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 reg, int onoff)
}
}
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, struct termios *t)
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, struct termios *t)
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 *priv,
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;
}