From owner-svn-src-all@FreeBSD.ORG Tue Sep 18 16:28:50 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B7DB1106566C; Tue, 18 Sep 2012 16:28:50 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 9F6CC8FC16; Tue, 18 Sep 2012 16:28:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q8IGSoZF024644; Tue, 18 Sep 2012 16:28:50 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q8IGSoOF024628; Tue, 18 Sep 2012 16:28:50 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201209181628.q8IGSoOF024628@svn.freebsd.org> From: Hans Petter Selasky Date: Tue, 18 Sep 2012 16:28:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r240659 - in stable/9/sys: dev/usb/net dev/usb/serial kern sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Sep 2012 16:28:50 -0000 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 ***