Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Sep 2012 16:28:50 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r240659 - in stable/9/sys: dev/usb/net dev/usb/serial kern sys
Message-ID:  <201209181628.q8IGSoOF024628@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Tue Sep 18 16:28:49 2012
New Revision: 240659
URL: http://svn.freebsd.org/changeset/base/240659

Log:
  MFC r239178, r239179, r239180, r239181, r239182 and r239299:
  
  Fix detach of USB serial devices so that it doesn't block
  the USB explore thread forever. To accomplish this two new
  functions have been added to the kernel, to claim and free
  the newbus allocated softc.
  
  This change is backwards API compatible, but not binary
  compatible. The FreeBSD version has been bumped to force
  a recompile of all kernel modules.
  
  Discussed with:         kib, ed, jhb

Modified:
  stable/9/sys/dev/usb/net/if_usie.c
  stable/9/sys/dev/usb/net/uhso.c
  stable/9/sys/dev/usb/serial/u3g.c
  stable/9/sys/dev/usb/serial/uark.c
  stable/9/sys/dev/usb/serial/ubsa.c
  stable/9/sys/dev/usb/serial/ubser.c
  stable/9/sys/dev/usb/serial/uchcom.c
  stable/9/sys/dev/usb/serial/ucycom.c
  stable/9/sys/dev/usb/serial/ufoma.c
  stable/9/sys/dev/usb/serial/uftdi.c
  stable/9/sys/dev/usb/serial/ugensa.c
  stable/9/sys/dev/usb/serial/uipaq.c
  stable/9/sys/dev/usb/serial/ulpt.c
  stable/9/sys/dev/usb/serial/umcs.c
  stable/9/sys/dev/usb/serial/umct.c
  stable/9/sys/dev/usb/serial/umodem.c
  stable/9/sys/dev/usb/serial/umoscom.c
  stable/9/sys/dev/usb/serial/uplcom.c
  stable/9/sys/dev/usb/serial/usb_serial.c
  stable/9/sys/dev/usb/serial/usb_serial.h
  stable/9/sys/dev/usb/serial/uslcom.c
  stable/9/sys/dev/usb/serial/uvisor.c
  stable/9/sys/dev/usb/serial/uvscom.c
  stable/9/sys/kern/subr_bus.c
  stable/9/sys/sys/bus.h
  stable/9/sys/sys/param.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/usb/net/if_usie.c
==============================================================================
--- stable/9/sys/dev/usb/net/if_usie.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/net/if_usie.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -95,7 +95,9 @@ static const STRUCT_USB_HOST_ID usie_dev
 static device_probe_t usie_probe;
 static device_attach_t usie_attach;
 static device_detach_t usie_detach;
+static void usie_free_softc(struct usie_softc *);
 
+static void usie_free(struct ucom_softc *);
 static void usie_uc_update_line_state(struct ucom_softc *, uint8_t);
 static void usie_uc_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *);
 static void usie_uc_cfg_set_dtr(struct ucom_softc *, uint8_t);
@@ -189,7 +191,7 @@ static device_method_t usie_methods[] = 
 	DEVMETHOD(device_probe, usie_probe),
 	DEVMETHOD(device_attach, usie_attach),
 	DEVMETHOD(device_detach, usie_detach),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static driver_t usie_driver = {
@@ -216,6 +218,7 @@ static const struct ucom_callback usie_u
 	.ucom_stop_read = &usie_uc_stop_read,
 	.ucom_start_write = &usie_uc_start_write,
 	.ucom_stop_write = &usie_uc_stop_write,
+	.ucom_free = &usie_free,
 };
 
 static void
@@ -298,6 +301,7 @@ usie_attach(device_t self)
 	sc->sc_dev = self;
 
 	mtx_init(&sc->sc_mtx, "usie", MTX_NETWORK_LOCK, MTX_DEF);
+	ucom_ref(&sc->sc_super_ucom);
 
 	TASK_INIT(&sc->sc_if_status_task, 0, usie_if_status_cb, sc);
 	TASK_INIT(&sc->sc_if_sync_task, 0, usie_if_sync_cb, sc);
@@ -482,11 +486,31 @@ usie_detach(device_t self)
 	for (x = 0; x != USIE_UCOM_MAX; x++)
 		usbd_transfer_unsetup(sc->sc_uc_xfer[x], USIE_UC_N_XFER);
 
-	mtx_destroy(&sc->sc_mtx);
+
+	device_claim_softc(self);
+
+	usie_free_softc(sc);
 
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(usie);
+
+static void
+usie_free_softc(struct usie_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+usie_free(struct ucom_softc *ucom)
+{
+	usie_free_softc(ucom->sc_parent);
+}
+
 static void
 usie_uc_update_line_state(struct ucom_softc *ucom, uint8_t ls)
 {

Modified: stable/9/sys/dev/usb/net/uhso.c
==============================================================================
--- stable/9/sys/dev/usb/net/uhso.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/net/uhso.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -455,6 +455,7 @@ static int  uhso_driver_loaded(struct mo
 static int uhso_radio_sysctl(SYSCTL_HANDLER_ARGS);
 static int uhso_radio_ctrl(struct uhso_softc *, int);
 
+static void uhso_free(struct ucom_softc *);
 static void uhso_ucom_start_read(struct ucom_softc *);
 static void uhso_ucom_stop_read(struct ucom_softc *);
 static void uhso_ucom_start_write(struct ucom_softc *);
@@ -473,6 +474,7 @@ static void uhso_if_rxflush(void *);
 static device_probe_t uhso_probe;
 static device_attach_t uhso_attach;
 static device_detach_t uhso_detach;
+static void uhso_free_softc(struct uhso_softc *);
 
 static device_method_t uhso_methods[] = {
 	DEVMETHOD(device_probe,		uhso_probe),
@@ -500,7 +502,8 @@ static struct ucom_callback uhso_ucom_ca
 	.ucom_start_read = uhso_ucom_start_read,
 	.ucom_stop_read = uhso_ucom_stop_read,
 	.ucom_start_write = uhso_ucom_start_write,
-	.ucom_stop_write = uhso_ucom_stop_write
+	.ucom_stop_write = uhso_ucom_stop_write,
+	.ucom_free = &uhso_free,
 };
 
 static int
@@ -552,6 +555,7 @@ uhso_attach(device_t self)
 	sc->sc_dev = self;
 	sc->sc_udev = uaa->device;
 	mtx_init(&sc->sc_mtx, "uhso", NULL, MTX_DEF);
+	ucom_ref(&sc->sc_super_ucom);
 
 	sc->sc_ucom = NULL;
 	sc->sc_ttys = 0;
@@ -692,10 +696,30 @@ uhso_detach(device_t self)
 		usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX);
 	}
 
-	mtx_destroy(&sc->sc_mtx);
+	device_claim_softc(self);
+
+	uhso_free_softc(sc);
+
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(uhso);
+
+static void
+uhso_free_softc(struct uhso_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+uhso_free(struct ucom_softc *ucom)
+{
+	uhso_free_softc(ucom->sc_parent);
+}
+
 static void
 uhso_test_autoinst(void *arg, struct usb_device *udev,
     struct usb_attach_arg *uaa)

Modified: stable/9/sys/dev/usb/serial/u3g.c
==============================================================================
--- stable/9/sys/dev/usb/serial/u3g.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/u3g.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -118,10 +118,12 @@ struct u3g_softc {
 static device_probe_t u3g_probe;
 static device_attach_t u3g_attach;
 static device_detach_t u3g_detach;
+static void u3g_free_softc(struct u3g_softc *);
 
 static usb_callback_t u3g_write_callback;
 static usb_callback_t u3g_read_callback;
 
+static void u3g_free(struct ucom_softc *ucom);
 static void u3g_start_read(struct ucom_softc *ucom);
 static void u3g_stop_read(struct ucom_softc *ucom);
 static void u3g_start_write(struct ucom_softc *ucom);
@@ -160,13 +162,14 @@ static const struct ucom_callback u3g_ca
 	.ucom_stop_read = &u3g_stop_read,
 	.ucom_start_write = &u3g_start_write,
 	.ucom_stop_write = &u3g_stop_write,
+	.ucom_free = &u3g_free,
 };
 
 static device_method_t u3g_methods[] = {
 	DEVMETHOD(device_probe, u3g_probe),
 	DEVMETHOD(device_attach, u3g_attach),
 	DEVMETHOD(device_detach, u3g_detach),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static devclass_t u3g_devclass;
@@ -799,6 +802,7 @@ u3g_attach(device_t dev)
 
 	device_set_usb_desc(dev);
 	mtx_init(&sc->sc_mtx, "u3g", NULL, MTX_DEF);
+	ucom_ref(&sc->sc_super_ucom);
 
 	sc->sc_udev = uaa->device;
 
@@ -886,11 +890,31 @@ u3g_detach(device_t dev)
 
 	for (subunit = 0; subunit != U3G_MAXPORTS; subunit++)
 		usbd_transfer_unsetup(sc->sc_xfer[subunit], U3G_N_TRANSFER);
-	mtx_destroy(&sc->sc_mtx);
+
+	device_claim_softc(dev);
+
+	u3g_free_softc(sc);
 
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(u3g);
+
+static void
+u3g_free_softc(struct u3g_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+u3g_free(struct ucom_softc *ucom)
+{
+	u3g_free_softc(ucom->sc_parent);
+}
+
 static void
 u3g_start_read(struct ucom_softc *ucom)
 {
@@ -898,7 +922,6 @@ u3g_start_read(struct ucom_softc *ucom)
 
 	/* start read endpoint */
 	usbd_transfer_start(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_RD]);
-	return;
 }
 
 static void
@@ -908,7 +931,6 @@ u3g_stop_read(struct ucom_softc *ucom)
 
 	/* stop read endpoint */
 	usbd_transfer_stop(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_RD]);
-	return;
 }
 
 static void
@@ -917,7 +939,6 @@ u3g_start_write(struct ucom_softc *ucom)
 	struct u3g_softc *sc = ucom->sc_parent;
 
 	usbd_transfer_start(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_WR]);
-	return;
 }
 
 static void
@@ -926,7 +947,6 @@ u3g_stop_write(struct ucom_softc *ucom)
 	struct u3g_softc *sc = ucom->sc_parent;
 
 	usbd_transfer_stop(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_WR]);
-	return;
 }
 
 static void
@@ -955,7 +975,6 @@ tr_setup:
 		}
 		break;
 	}
-	return;
 }
 
 static void
@@ -986,5 +1005,4 @@ tr_setup:
 		}
 		break;
 	}
-	return;
 }

Modified: stable/9/sys/dev/usb/serial/uark.c
==============================================================================
--- stable/9/sys/dev/usb/serial/uark.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/uark.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -99,10 +99,12 @@ struct uark_softc {
 static device_probe_t uark_probe;
 static device_attach_t uark_attach;
 static device_detach_t uark_detach;
+static void uark_free_softc(struct uark_softc *);
 
 static usb_callback_t uark_bulk_write_callback;
 static usb_callback_t uark_bulk_read_callback;
 
+static void	uark_free(struct ucom_softc *);
 static void	uark_start_read(struct ucom_softc *);
 static void	uark_stop_read(struct ucom_softc *);
 static void	uark_start_write(struct ucom_softc *);
@@ -147,6 +149,7 @@ static const struct ucom_callback uark_c
 	.ucom_start_write = &uark_start_write,
 	.ucom_stop_write = &uark_stop_write,
 	.ucom_poll = &uark_poll,
+	.ucom_free = &uark_free,
 };
 
 static device_method_t uark_methods[] = {
@@ -154,7 +157,7 @@ static device_method_t uark_methods[] = 
 	DEVMETHOD(device_probe, uark_probe),
 	DEVMETHOD(device_attach, uark_attach),
 	DEVMETHOD(device_detach, uark_detach),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static devclass_t uark_devclass;
@@ -201,6 +204,7 @@ uark_attach(device_t dev)
 
 	device_set_usb_desc(dev);
 	mtx_init(&sc->sc_mtx, "uark", NULL, MTX_DEF);
+	ucom_ref(&sc->sc_super_ucom);
 
 	sc->sc_udev = uaa->device;
 
@@ -242,11 +246,31 @@ uark_detach(device_t dev)
 
 	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UARK_N_TRANSFER);
-	mtx_destroy(&sc->sc_mtx);
+
+	device_claim_softc(dev);
+
+	uark_free_softc(sc);
 
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(uark);
+
+static void
+uark_free_softc(struct uark_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+uark_free(struct ucom_softc *ucom)
+{
+	uark_free_softc(ucom->sc_parent);
+}
+
 static void
 uark_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
 {

Modified: stable/9/sys/dev/usb/serial/ubsa.c
==============================================================================
--- stable/9/sys/dev/usb/serial/ubsa.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/ubsa.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -176,12 +176,14 @@ struct ubsa_softc {
 static device_probe_t ubsa_probe;
 static device_attach_t ubsa_attach;
 static device_detach_t ubsa_detach;
+static void ubsa_free_softc(struct ubsa_softc *);
 
 static usb_callback_t ubsa_write_callback;
 static usb_callback_t ubsa_read_callback;
 static usb_callback_t ubsa_intr_callback;
 
 static void	ubsa_cfg_request(struct ubsa_softc *, uint8_t, uint16_t);
+static void	ubsa_free(struct ucom_softc *);
 static void	ubsa_cfg_set_dtr(struct ucom_softc *, uint8_t);
 static void	ubsa_cfg_set_rts(struct ucom_softc *, uint8_t);
 static void	ubsa_cfg_set_break(struct ucom_softc *, uint8_t);
@@ -237,6 +239,7 @@ static const struct ucom_callback ubsa_c
 	.ucom_start_write = &ubsa_start_write,
 	.ucom_stop_write = &ubsa_stop_write,
 	.ucom_poll = &ubsa_poll,
+	.ucom_free = &ubsa_free,
 };
 
 static const STRUCT_USB_HOST_ID ubsa_devs[] = {
@@ -262,7 +265,7 @@ static device_method_t ubsa_methods[] = 
 	DEVMETHOD(device_probe, ubsa_probe),
 	DEVMETHOD(device_attach, ubsa_attach),
 	DEVMETHOD(device_detach, ubsa_detach),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static devclass_t ubsa_devclass;
@@ -306,6 +309,7 @@ ubsa_attach(device_t dev)
 
 	device_set_usb_desc(dev);
 	mtx_init(&sc->sc_mtx, "ubsa", NULL, MTX_DEF);
+	ucom_ref(&sc->sc_super_ucom);
 
 	sc->sc_udev = uaa->device;
 	sc->sc_iface_no = uaa->info.bIfaceNum;
@@ -348,11 +352,31 @@ ubsa_detach(device_t dev)
 
 	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UBSA_N_TRANSFER);
-	mtx_destroy(&sc->sc_mtx);
+
+	device_claim_softc(dev);
+
+	ubsa_free_softc(sc);
 
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(ubsa);
+
+static void
+ubsa_free_softc(struct ubsa_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+ubsa_free(struct ucom_softc *ucom)
+{
+	ubsa_free_softc(ucom->sc_parent);
+}
+
 static void
 ubsa_cfg_request(struct ubsa_softc *sc, uint8_t index, uint16_t value)
 {

Modified: stable/9/sys/dev/usb/serial/ubser.c
==============================================================================
--- stable/9/sys/dev/usb/serial/ubser.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/ubser.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -141,7 +141,6 @@ struct ubser_softc {
 	uint8_t	sc_iface_no;
 	uint8_t	sc_iface_index;
 	uint8_t	sc_curr_tx_unit;
-	uint8_t	sc_name[16];
 };
 
 /* prototypes */
@@ -149,10 +148,12 @@ struct ubser_softc {
 static device_probe_t ubser_probe;
 static device_attach_t ubser_attach;
 static device_detach_t ubser_detach;
+static void ubser_free_softc(struct ubser_softc *);
 
 static usb_callback_t ubser_write_callback;
 static usb_callback_t ubser_read_callback;
 
+static void	ubser_free(struct ucom_softc *);
 static int	ubser_pre_param(struct ucom_softc *, struct termios *);
 static void	ubser_cfg_set_break(struct ucom_softc *, uint8_t);
 static void	ubser_cfg_get_status(struct ucom_softc *, uint8_t *,
@@ -193,13 +194,14 @@ static const struct ucom_callback ubser_
 	.ucom_start_write = &ubser_start_write,
 	.ucom_stop_write = &ubser_stop_write,
 	.ucom_poll = &ubser_poll,
+	.ucom_free = &ubser_free,
 };
 
 static device_method_t ubser_methods[] = {
 	DEVMETHOD(device_probe, ubser_probe),
 	DEVMETHOD(device_attach, ubser_attach),
 	DEVMETHOD(device_detach, ubser_detach),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static devclass_t ubser_devclass;
@@ -243,9 +245,7 @@ ubser_attach(device_t dev)
 
 	device_set_usb_desc(dev);
 	mtx_init(&sc->sc_mtx, "ubser", NULL, MTX_DEF);
-
-	snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
-	    device_get_nameunit(dev));
+	ucom_ref(&sc->sc_super_ucom);
 
 	sc->sc_iface_no = uaa->info.bIfaceNum;
 	sc->sc_iface_index = uaa->info.bIfaceIndex;
@@ -319,11 +319,31 @@ ubser_detach(device_t dev)
 
 	ucom_detach(&sc->sc_super_ucom, sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UBSER_N_TRANSFER);
-	mtx_destroy(&sc->sc_mtx);
+
+	device_claim_softc(dev);
+
+	ubser_free_softc(sc);
 
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(ubser);
+
+static void
+ubser_free_softc(struct ubser_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+ubser_free(struct ucom_softc *ucom)
+{
+	ubser_free_softc(ucom->sc_parent);
+}
+
 static int
 ubser_pre_param(struct ucom_softc *ucom, struct termios *t)
 {

Modified: stable/9/sys/dev/usb/serial/uchcom.c
==============================================================================
--- stable/9/sys/dev/usb/serial/uchcom.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/uchcom.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -212,6 +212,7 @@ static const STRUCT_USB_HOST_ID uchcom_d
 
 /* protypes */
 
+static void	uchcom_free(struct ucom_softc *);
 static int	uchcom_pre_param(struct ucom_softc *, struct termios *);
 static void	uchcom_cfg_get_status(struct ucom_softc *, uint8_t *,
 		    uint8_t *);
@@ -235,6 +236,7 @@ static void	uchcom_poll(struct ucom_soft
 static device_probe_t uchcom_probe;
 static device_attach_t uchcom_attach;
 static device_detach_t uchcom_detach;
+static void uchcom_free_softc(struct uchcom_softc *);
 
 static usb_callback_t uchcom_intr_callback;
 static usb_callback_t uchcom_write_callback;
@@ -283,6 +285,7 @@ static struct ucom_callback uchcom_callb
 	.ucom_start_write = &uchcom_start_write,
 	.ucom_stop_write = &uchcom_stop_write,
 	.ucom_poll = &uchcom_poll,
+	.ucom_free = &uchcom_free,
 };
 
 /* ----------------------------------------------------------------------
@@ -320,6 +323,7 @@ uchcom_attach(device_t dev)
 
 	device_set_usb_desc(dev);
 	mtx_init(&sc->sc_mtx, "uchcom", NULL, MTX_DEF);
+	ucom_ref(&sc->sc_super_ucom);
 
 	sc->sc_udev = uaa->device;
 
@@ -372,11 +376,31 @@ uchcom_detach(device_t dev)
 
 	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UCHCOM_N_TRANSFER);
-	mtx_destroy(&sc->sc_mtx);
+
+	device_claim_softc(dev);
+
+	uchcom_free_softc(sc);
 
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(uchcom);
+
+static void
+uchcom_free_softc(struct uchcom_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+uchcom_free(struct ucom_softc *ucom)
+{
+	uchcom_free_softc(ucom->sc_parent);
+}
+
 /* ----------------------------------------------------------------------
  * low level i/o
  */
@@ -842,8 +866,7 @@ static device_method_t uchcom_methods[] 
 	DEVMETHOD(device_probe, uchcom_probe),
 	DEVMETHOD(device_attach, uchcom_attach),
 	DEVMETHOD(device_detach, uchcom_detach),
-
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static driver_t uchcom_driver = {

Modified: stable/9/sys/dev/usb/serial/ucycom.c
==============================================================================
--- stable/9/sys/dev/usb/serial/ucycom.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/ucycom.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -101,7 +101,6 @@ struct ucycom_softc {
 #define	UCYCOM_CFG_STOPB	0x08
 #define	UCYCOM_CFG_DATAB	0x03
 	uint8_t	sc_ist;			/* status flags from last input */
-	uint8_t	sc_name[16];
 	uint8_t	sc_iface_no;
 	uint8_t	sc_temp_cfg[32];
 };
@@ -111,10 +110,12 @@ struct ucycom_softc {
 static device_probe_t ucycom_probe;
 static device_attach_t ucycom_attach;
 static device_detach_t ucycom_detach;
+static void ucycom_free_softc(struct ucycom_softc *);
 
 static usb_callback_t ucycom_ctrl_write_callback;
 static usb_callback_t ucycom_intr_read_callback;
 
+static void	ucycom_free(struct ucom_softc *);
 static void	ucycom_cfg_open(struct ucom_softc *);
 static void	ucycom_start_read(struct ucom_softc *);
 static void	ucycom_stop_read(struct ucom_softc *);
@@ -155,13 +156,14 @@ static const struct ucom_callback ucycom
 	.ucom_start_write = &ucycom_start_write,
 	.ucom_stop_write = &ucycom_stop_write,
 	.ucom_poll = &ucycom_poll,
+	.ucom_free = &ucycom_free,
 };
 
 static device_method_t ucycom_methods[] = {
 	DEVMETHOD(device_probe, ucycom_probe),
 	DEVMETHOD(device_attach, ucycom_attach),
 	DEVMETHOD(device_detach, ucycom_detach),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static devclass_t ucycom_devclass;
@@ -218,9 +220,7 @@ ucycom_attach(device_t dev)
 
 	device_set_usb_desc(dev);
 	mtx_init(&sc->sc_mtx, "ucycom", NULL, MTX_DEF);
-
-	snprintf(sc->sc_name, sizeof(sc->sc_name),
-	    "%s", device_get_nameunit(dev));
+	ucom_ref(&sc->sc_super_ucom);
 
 	DPRINTF("\n");
 
@@ -297,11 +297,31 @@ ucycom_detach(device_t dev)
 
 	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UCYCOM_N_TRANSFER);
-	mtx_destroy(&sc->sc_mtx);
+
+	device_claim_softc(dev);
+
+	ucycom_free_softc(sc);
 
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(ucycom);
+
+static void
+ucycom_free_softc(struct ucycom_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+ucycom_free(struct ucom_softc *ucom)
+{
+	ucycom_free_softc(ucom->sc_parent);
+}
+
 static void
 ucycom_cfg_open(struct ucom_softc *ucom)
 {

Modified: stable/9/sys/dev/usb/serial/ufoma.c
==============================================================================
--- stable/9/sys/dev/usb/serial/ufoma.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/ufoma.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -195,7 +195,6 @@ struct ufoma_softc {
 	uint8_t	sc_msr;
 	uint8_t	sc_modetoactivate;
 	uint8_t	sc_currentmode;
-	uint8_t	sc_name[16];
 };
 
 /* prototypes */
@@ -203,6 +202,7 @@ struct ufoma_softc {
 static device_probe_t ufoma_probe;
 static device_attach_t ufoma_attach;
 static device_detach_t ufoma_detach;
+static void ufoma_free_softc(struct ufoma_softc *);
 
 static usb_callback_t ufoma_ctrl_read_callback;
 static usb_callback_t ufoma_ctrl_write_callback;
@@ -214,6 +214,7 @@ static void	*ufoma_get_intconf(struct us
 		    struct usb_interface_descriptor *, uint8_t, uint8_t);
 static void	ufoma_cfg_link_state(struct ufoma_softc *);
 static void	ufoma_cfg_activate_state(struct ufoma_softc *, uint16_t);
+static void	ufoma_free(struct ucom_softc *);
 static void	ufoma_cfg_open(struct ucom_softc *);
 static void	ufoma_cfg_close(struct ucom_softc *);
 static void	ufoma_cfg_set_break(struct ucom_softc *, uint8_t);
@@ -304,6 +305,7 @@ static const struct ucom_callback ufoma_
 	.ucom_start_write = &ufoma_start_write,
 	.ucom_stop_write = &ufoma_stop_write,
 	.ucom_poll = &ufoma_poll,
+	.ucom_free = &ufoma_free,
 };
 
 static device_method_t ufoma_methods[] = {
@@ -311,7 +313,7 @@ static device_method_t ufoma_methods[] =
 	DEVMETHOD(device_probe, ufoma_probe),
 	DEVMETHOD(device_attach, ufoma_attach),
 	DEVMETHOD(device_detach, ufoma_detach),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static devclass_t ufoma_devclass;
@@ -385,13 +387,11 @@ ufoma_attach(device_t dev)
 	sc->sc_unit = device_get_unit(dev);
 
 	mtx_init(&sc->sc_mtx, "ufoma", NULL, MTX_DEF);
+	ucom_ref(&sc->sc_super_ucom);
 	cv_init(&sc->sc_cv, "CWAIT");
 
 	device_set_usb_desc(dev);
 
-	snprintf(sc->sc_name, sizeof(sc->sc_name),
-	    "%s", device_get_nameunit(dev));
-
 	DPRINTF("\n");
 
 	/* setup control transfers */
@@ -495,12 +495,32 @@ ufoma_detach(device_t dev)
 	if (sc->sc_modetable) {
 		free(sc->sc_modetable, M_USBDEV);
 	}
-	mtx_destroy(&sc->sc_mtx);
 	cv_destroy(&sc->sc_cv);
 
+	device_claim_softc(dev);
+
+	ufoma_free_softc(sc);
+
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(ufoma);
+
+static void
+ufoma_free_softc(struct ufoma_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+ufoma_free(struct ucom_softc *ucom)
+{
+	ufoma_free_softc(ucom->sc_parent);
+}
+
 static void *
 ufoma_get_intconf(struct usb_config_descriptor *cd, struct usb_interface_descriptor *id,
     uint8_t type, uint8_t subtype)

Modified: stable/9/sys/dev/usb/serial/uftdi.c
==============================================================================
--- stable/9/sys/dev/usb/serial/uftdi.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/uftdi.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -110,8 +110,6 @@ struct uftdi_softc {
 	uint8_t	sc_hdrlen;
 	uint8_t	sc_msr;
 	uint8_t	sc_lsr;
-
-	uint8_t	sc_name[16];
 };
 
 struct uftdi_param_config {
@@ -127,10 +125,12 @@ struct uftdi_param_config {
 static device_probe_t uftdi_probe;
 static device_attach_t uftdi_attach;
 static device_detach_t uftdi_detach;
+static void uftdi_free_softc(struct uftdi_softc *);
 
 static usb_callback_t uftdi_write_callback;
 static usb_callback_t uftdi_read_callback;
 
+static void	uftdi_free(struct ucom_softc *);
 static void	uftdi_cfg_open(struct ucom_softc *);
 static void	uftdi_cfg_set_dtr(struct ucom_softc *, uint8_t);
 static void	uftdi_cfg_set_rts(struct ucom_softc *, uint8_t);
@@ -182,6 +182,7 @@ static const struct ucom_callback uftdi_
 	.ucom_start_write = &uftdi_start_write,
 	.ucom_stop_write = &uftdi_stop_write,
 	.ucom_poll = &uftdi_poll,
+	.ucom_free = &uftdi_free,
 };
 
 static device_method_t uftdi_methods[] = {
@@ -189,7 +190,6 @@ static device_method_t uftdi_methods[] =
 	DEVMETHOD(device_probe, uftdi_probe),
 	DEVMETHOD(device_attach, uftdi_attach),
 	DEVMETHOD(device_detach, uftdi_detach),
-
 	DEVMETHOD_END
 };
 
@@ -304,9 +304,7 @@ uftdi_attach(device_t dev)
 
 	device_set_usb_desc(dev);
 	mtx_init(&sc->sc_mtx, "uftdi", NULL, MTX_DEF);
-
-	snprintf(sc->sc_name, sizeof(sc->sc_name),
-	    "%s", device_get_nameunit(dev));
+	ucom_ref(&sc->sc_super_ucom);
 
 	DPRINTF("\n");
 
@@ -368,11 +366,31 @@ uftdi_detach(device_t dev)
 
 	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UFTDI_N_TRANSFER);
-	mtx_destroy(&sc->sc_mtx);
+
+	device_claim_softc(dev);
+
+	uftdi_free_softc(sc);
 
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(uftdi);
+
+static void
+uftdi_free_softc(struct uftdi_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+uftdi_free(struct ucom_softc *ucom)
+{
+	uftdi_free_softc(ucom->sc_parent);
+}
+
 static void
 uftdi_cfg_open(struct ucom_softc *ucom)
 {

Modified: stable/9/sys/dev/usb/serial/ugensa.c
==============================================================================
--- stable/9/sys/dev/usb/serial/ugensa.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/ugensa.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -94,10 +94,12 @@ struct ugensa_softc {
 static device_probe_t ugensa_probe;
 static device_attach_t ugensa_attach;
 static device_detach_t ugensa_detach;
+static void ugensa_free_softc(struct ugensa_softc *);
 
 static usb_callback_t ugensa_bulk_write_callback;
 static usb_callback_t ugensa_bulk_read_callback;
 
+static void	ugensa_free(struct ucom_softc *);
 static void	ugensa_start_read(struct ucom_softc *);
 static void	ugensa_stop_read(struct ucom_softc *);
 static void	ugensa_start_write(struct ucom_softc *);
@@ -131,6 +133,7 @@ static const struct ucom_callback ugensa
 	.ucom_start_write = &ugensa_start_write,
 	.ucom_stop_write = &ugensa_stop_write,
 	.ucom_poll = &ugensa_poll,
+	.ucom_free = &ugensa_free,
 };
 
 static device_method_t ugensa_methods[] = {
@@ -138,7 +141,7 @@ static device_method_t ugensa_methods[] 
 	DEVMETHOD(device_probe, ugensa_probe),
 	DEVMETHOD(device_attach, ugensa_attach),
 	DEVMETHOD(device_detach, ugensa_detach),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static devclass_t ugensa_devclass;
@@ -192,6 +195,7 @@ ugensa_attach(device_t dev)
 
 	device_set_usb_desc(dev);
 	mtx_init(&sc->sc_mtx, "ugensa", NULL, MTX_DEF);
+	ucom_ref(&sc->sc_super_ucom);
 
 	/* Figure out how many interfaces this device has got */
 	for (cnt = 0; cnt < UGENSA_IFACE_MAX; cnt++) {
@@ -266,11 +270,31 @@ ugensa_detach(device_t dev)
 	for (x = 0; x < sc->sc_niface; x++) {
 		usbd_transfer_unsetup(sc->sc_sub[x].sc_xfer, UGENSA_N_TRANSFER);
 	}
-	mtx_destroy(&sc->sc_mtx);
+
+	device_claim_softc(dev);
+
+	ugensa_free_softc(sc);
 
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(ugensa);
+
+static void
+ugensa_free_softc(struct ugensa_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+ugensa_free(struct ucom_softc *ucom)
+{
+	ugensa_free_softc(ucom->sc_parent);
+}
+
 static void
 ugensa_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
 {

Modified: stable/9/sys/dev/usb/serial/uipaq.c
==============================================================================
--- stable/9/sys/dev/usb/serial/uipaq.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/uipaq.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -103,10 +103,12 @@ struct uipaq_softc {
 static device_probe_t uipaq_probe;
 static device_attach_t uipaq_attach;
 static device_detach_t uipaq_detach;
+static void uipaq_free_softc(struct uipaq_softc *);
 
 static usb_callback_t uipaq_write_callback;
 static usb_callback_t uipaq_read_callback;
 
+static void	uipaq_free(struct ucom_softc *);
 static void	uipaq_start_read(struct ucom_softc *);
 static void	uipaq_stop_read(struct ucom_softc *);
 static void	uipaq_start_write(struct ucom_softc *);
@@ -146,6 +148,7 @@ static const struct ucom_callback uipaq_
 	.ucom_start_write = &uipaq_start_write,
 	.ucom_stop_write = &uipaq_stop_write,
 	.ucom_poll = &uipaq_poll,
+	.ucom_free = &uipaq_free,
 };
 
 /*
@@ -1070,7 +1073,7 @@ static device_method_t uipaq_methods[] =
 	DEVMETHOD(device_probe, uipaq_probe),
 	DEVMETHOD(device_attach, uipaq_attach),
 	DEVMETHOD(device_detach, uipaq_detach),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static devclass_t uipaq_devclass;
@@ -1121,6 +1124,7 @@ uipaq_attach(device_t dev)
 
 	device_set_usb_desc(dev);
 	mtx_init(&sc->sc_mtx, "uipaq", NULL, MTX_DEF);
+	ucom_ref(&sc->sc_super_ucom);
 
 	/*
 	 * Send magic bytes, cribbed from Linux ipaq driver that
@@ -1176,11 +1180,31 @@ uipaq_detach(device_t dev)
 
 	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UIPAQ_N_TRANSFER);
-	mtx_destroy(&sc->sc_mtx);
+
+	device_claim_softc(dev);
+
+	uipaq_free_softc(sc);
 
 	return (0);
 }
 
+UCOM_UNLOAD_DRAIN(uipaq);
+
+static void
+uipaq_free_softc(struct uipaq_softc *sc)
+{
+	if (ucom_unref(&sc->sc_super_ucom)) {
+		mtx_destroy(&sc->sc_mtx);
+		device_free_softc(sc);
+	}
+}
+
+static void
+uipaq_free(struct ucom_softc *ucom)
+{
+	uipaq_free_softc(ucom->sc_parent);
+}
+
 static void
 uipaq_start_read(struct ucom_softc *ucom)
 {

Modified: stable/9/sys/dev/usb/serial/ulpt.c
==============================================================================
--- stable/9/sys/dev/usb/serial/ulpt.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/ulpt.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -747,7 +747,7 @@ static device_method_t ulpt_methods[] = 
 	DEVMETHOD(device_probe, ulpt_probe),
 	DEVMETHOD(device_attach, ulpt_attach),
 	DEVMETHOD(device_detach, ulpt_detach),
-	{0, 0}
+	DEVMETHOD_END
 };
 
 static driver_t ulpt_driver = {

Modified: stable/9/sys/dev/usb/serial/umcs.c
==============================================================================
--- stable/9/sys/dev/usb/serial/umcs.c	Tue Sep 18 16:23:23 2012	(r240658)
+++ stable/9/sys/dev/usb/serial/umcs.c	Tue Sep 18 16:28:49 2012	(r240659)
@@ -154,6 +154,7 @@ static usb_error_t umcs7840_set_UART_reg
 static usb_error_t umcs7840_set_baudrate(struct umcs7840_softc *, uint8_t, uint32_t);
 static usb_error_t umcs7840_calc_baudrate(uint32_t rate, uint16_t *, uint8_t *);
 
+static void	umcs7840_free(struct ucom_softc *);
 static void umcs7840_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *);
 static void umcs7840_cfg_set_dtr(struct ucom_softc *, uint8_t);
 static void umcs7840_cfg_set_rts(struct ucom_softc *, uint8_t);
@@ -175,6 +176,7 @@ static void umcs7840_poll(struct ucom_so
 static device_probe_t umcs7840_probe;
 static device_attach_t umcs7840_attach;
 static device_detach_t umcs7840_detach;
+static void umcs7840_free_softc(struct umcs7840_softc *);
 
 static usb_callback_t umcs7840_intr_callback;
 static usb_callback_t umcs7840_read_callback1;
@@ -251,6 +253,7 @@ static struct ucom_callback umcs7840_cal
 	.ucom_stop_write = &umcs7840_stop_write,

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209181628.q8IGSoOF024628>