Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 May 2011 22:20:01 +0000 (UTC)
From:      Nick Hibma <n_hibma@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r221612 - in stable/8/sys/dev/usb: . net serial
Message-ID:  <201105072220.p47MK1Fo017362@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: n_hibma
Date: Sat May  7 22:20:01 2011
New Revision: 221612
URL: http://svn.freebsd.org/changeset/base/221612

Log:
  MFC overview:
  - Fix busg in events provided to devd from the USB stack.
  - Provide more info on the u3g devices that attached.
  - Make the ucom device numbering more sane.
  
  MFC r214429
  
  Add support for setting per-interface PnP information.
  
  MFC r214761
  
  - Simplify the way unit/subunit allocation is done in ucom.
  - hw.usb.ucom.cons_unit is now split into
    hw.usb.ucom.cons_unit/...cons_subunit.
  
    Note: The tunable/sysctl hw.usb.ucom.cons_unit needs to be reviewed if
  
    a) a console was defined a USB serial devices, and a USB device with
    more than 1 subunit is present, and this device is attached before the
    device functioning as a console
  
    or
  
    b) a console was defined on a USB device with more than 1 subunit
  
  MFC r214809
  
    Don't terminate the notification with \n. This is done in
    usb_device.c:devctl_notify_f().
  
  MFC r214830
  
  Bugfix: Move the 'at <location string' to the beginning of the attach
  notification. devd would stop evaluating at 'at' (not '<k>=<v>') and
  hence prevent 'port=X' (and 'bus=<"on" string>) from making it into the
  environment for the devd action.
  
  MFC r214831
  
  - Remove an unused entry from the softc (only used in a debugging printf).
  - Fix the loop count on detach (causing a panic on detaching a serial
    dongle).
  - Increase a buffer in case some driver want extra long tty device names
    (postfixing the purpose of the tty for example, e.g. u3g.ppp).
  
  MFC r214843
  
  Implement ucom_set_pnpinfo_usb() providing ttyname and port number
  information through devd. My E220 now produces the notification (1 line):
  
          +u3g0 at bus=1 hubaddr=1 port=0 devaddr=2 interface=0 \
          vendor=0x12d1 product=0x1003 devclass=0x00 devsubclass=0x00 \
          sernum="" release=0x0000 intclass=0xff intsubclass=0xff \
          ttyname=U0 ttyports=2 on uhub0
  
  Note: serial/ufoma and net/uhso still provide port number and tty name
  (uhso only) information through sysctls, which should now be removed.
  
  MFC r214919
  
  Bugfix: Set the bit that marks a device number in use.
  This would cause a panic when disconnecting the second serial device.

Modified:
  stable/8/sys/dev/usb/net/uhso.c
  stable/8/sys/dev/usb/serial/u3g.c
  stable/8/sys/dev/usb/serial/uark.c
  stable/8/sys/dev/usb/serial/ubsa.c
  stable/8/sys/dev/usb/serial/ubser.c
  stable/8/sys/dev/usb/serial/uchcom.c
  stable/8/sys/dev/usb/serial/ucycom.c
  stable/8/sys/dev/usb/serial/ufoma.c
  stable/8/sys/dev/usb/serial/uftdi.c
  stable/8/sys/dev/usb/serial/ugensa.c
  stable/8/sys/dev/usb/serial/uipaq.c
  stable/8/sys/dev/usb/serial/umct.c
  stable/8/sys/dev/usb/serial/umodem.c
  stable/8/sys/dev/usb/serial/umoscom.c
  stable/8/sys/dev/usb/serial/uplcom.c
  stable/8/sys/dev/usb/serial/usb_serial.c
  stable/8/sys/dev/usb/serial/usb_serial.h
  stable/8/sys/dev/usb/serial/uslcom.c
  stable/8/sys/dev/usb/serial/uvisor.c
  stable/8/sys/dev/usb/serial/uvscom.c
  stable/8/sys/dev/usb/usb_device.c
  stable/8/sys/dev/usb/usb_hub.c
  stable/8/sys/dev/usb/usbdi.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/usb/net/uhso.c
==============================================================================
--- stable/8/sys/dev/usb/net/uhso.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/net/uhso.c	Sat May  7 22:20:01 2011	(r221612)
@@ -633,11 +633,10 @@ uhso_attach(device_t self)
 
 		ht->ht_name[0] = 0;
 		if (sc->sc_ttys == 1)
-			snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_unit);
+			snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_super->sc_unit);
 		else {
 			snprintf(ht->ht_name, 32, "cuaU%d.%d",
-			    ucom->sc_unit - ucom->sc_local_unit,
-			    ucom->sc_local_unit);
+			    ucom->sc_super->sc_unit, ucom->sc_subunit);
 		}
 
 		desc = uhso_port_type[port];
@@ -666,7 +665,7 @@ uhso_detach(device_t self)
 	usbd_transfer_unsetup(sc->sc_xfer, 3);
 	usbd_transfer_unsetup(sc->sc_ctrl_xfer, UHSO_CTRL_MAX);
 	if (sc->sc_ttys > 0) {
-		ucom_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_ttys);
+		ucom_detach(&sc->sc_super_ucom, sc->sc_ucom);
 
 		for (i = 0; i < sc->sc_ttys; i++) {
 			if (sc->sc_tty[i].ht_muxport != -1) {
@@ -903,6 +902,7 @@ uhso_probe_iface(struct uhso_softc *sc, 
 				device_printf(sc->sc_dev, "ucom_attach failed\n");
 				return (ENXIO);
 			}
+			ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev);
 
 			mtx_lock(&sc->sc_mtx);
 			usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
@@ -921,6 +921,7 @@ uhso_probe_iface(struct uhso_softc *sc, 
 			device_printf(sc->sc_dev, "ucom_attach failed\n");
 			return (ENXIO);
 		}
+		ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev);
 	}
 	else {
 		UHSO_DPRINTF(0, "Unknown type %x\n", type);
@@ -1448,11 +1449,11 @@ uhso_ucom_start_read(struct ucom_softc *
 {
 	struct uhso_softc *sc = ucom->sc_parent;
 
-	UHSO_DPRINTF(3, "unit=%d, local_unit=%d\n",
-	    ucom->sc_unit, ucom->sc_local_unit);
+	UHSO_DPRINTF(3, "unit=%d, subunit=%d\n",
+	    ucom->sc_super->sc_unit, ucom->sc_subunit);
 
 	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
-		sc->sc_tty[ucom->sc_local_unit].ht_open = 1;
+		sc->sc_tty[ucom->sc_subunit].ht_open = 1;
 		usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
 	}
 	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
@@ -1470,9 +1471,9 @@ uhso_ucom_stop_read(struct ucom_softc *u
 	struct uhso_softc *sc = ucom->sc_parent;
 
 	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
-		sc->sc_tty[ucom->sc_local_unit].ht_open = 0;
+		sc->sc_tty[ucom->sc_subunit].ht_open = 0;
 		usbd_transfer_stop(
-		    sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_READ]);
+		    sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_READ]);
 	}
 	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
 		sc->sc_tty[0].ht_open = 0;
@@ -1488,15 +1489,15 @@ uhso_ucom_start_write(struct ucom_softc 
 	struct uhso_softc *sc = ucom->sc_parent;
 
 	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
-		UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_local_unit);
+		UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_subunit);
 
 		usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
 
 		usbd_xfer_set_priv(
-		    sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_WRITE],
-		    &sc->sc_tty[ucom->sc_local_unit]);
+		    sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE],
+		    &sc->sc_tty[ucom->sc_subunit]);
 		usbd_transfer_start(
-		    sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_WRITE]);
+		    sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]);
 
 	}
 	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
@@ -1511,7 +1512,7 @@ uhso_ucom_stop_write(struct ucom_softc *
 
 	if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) {
 		usbd_transfer_stop(
-		    sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_WRITE]);
+		    sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]);
 	}
 	else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
 		usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]);

Modified: stable/8/sys/dev/usb/serial/u3g.c
==============================================================================
--- stable/8/sys/dev/usb/serial/u3g.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/u3g.c	Sat May  7 22:20:01 2011	(r221612)
@@ -855,8 +855,10 @@ u3g_attach(device_t dev)
 		DPRINTF("ucom_attach failed\n");
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
 	device_printf(dev, "Found %u port%s.\n", sc->sc_numports,
 	    sc->sc_numports > 1 ? "s":"");
+
 	return (0);
 
 detach:
@@ -868,15 +870,15 @@ static int
 u3g_detach(device_t dev)
 {
 	struct u3g_softc *sc = device_get_softc(dev);
-	uint8_t m;
+	uint8_t subunit;
 
 	DPRINTF("sc=%p\n", sc);
 
 	/* NOTE: It is not dangerous to detach more ports than attached! */
-	ucom_detach(&sc->sc_super_ucom, sc->sc_ucom, U3G_MAXPORTS);
+	ucom_detach(&sc->sc_super_ucom, sc->sc_ucom);
 
-	for (m = 0; m != U3G_MAXPORTS; m++)
-		usbd_transfer_unsetup(sc->sc_xfer[m], U3G_N_TRANSFER);
+	for (subunit = 0; subunit != U3G_MAXPORTS; subunit++)
+		usbd_transfer_unsetup(sc->sc_xfer[subunit], U3G_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 
 	return (0);
@@ -888,7 +890,7 @@ u3g_start_read(struct ucom_softc *ucom)
 	struct u3g_softc *sc = ucom->sc_parent;
 
 	/* start read endpoint */
-	usbd_transfer_start(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_RD]);
+	usbd_transfer_start(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_RD]);
 	return;
 }
 
@@ -898,7 +900,7 @@ u3g_stop_read(struct ucom_softc *ucom)
 	struct u3g_softc *sc = ucom->sc_parent;
 
 	/* stop read endpoint */
-	usbd_transfer_stop(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_RD]);
+	usbd_transfer_stop(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_RD]);
 	return;
 }
 
@@ -907,7 +909,7 @@ u3g_start_write(struct ucom_softc *ucom)
 {
 	struct u3g_softc *sc = ucom->sc_parent;
 
-	usbd_transfer_start(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_WR]);
+	usbd_transfer_start(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_WR]);
 	return;
 }
 
@@ -916,7 +918,7 @@ u3g_stop_write(struct ucom_softc *ucom)
 {
 	struct u3g_softc *sc = ucom->sc_parent;
 
-	usbd_transfer_stop(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_WR]);
+	usbd_transfer_stop(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_WR]);
 	return;
 }
 

Modified: stable/8/sys/dev/usb/serial/uark.c
==============================================================================
--- stable/8/sys/dev/usb/serial/uark.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/uark.c	Sat May  7 22:20:01 2011	(r221612)
@@ -226,6 +226,8 @@ uark_attach(device_t dev)
 		DPRINTF("ucom_attach failed\n");
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);			/* success */
 
 detach:
@@ -238,7 +240,7 @@ uark_detach(device_t dev)
 {
 	struct uark_softc *sc = device_get_softc(dev);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UARK_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/ubsa.c
==============================================================================
--- stable/8/sys/dev/usb/serial/ubsa.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/ubsa.c	Sat May  7 22:20:01 2011	(r221612)
@@ -330,6 +330,8 @@ ubsa_attach(device_t dev)
 		DPRINTF("ucom_attach failed\n");
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);
 
 detach:
@@ -344,7 +346,7 @@ ubsa_detach(device_t dev)
 
 	DPRINTF("sc=%p\n", sc);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UBSA_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/ubser.c
==============================================================================
--- stable/8/sys/dev/usb/serial/ubser.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/ubser.c	Sat May  7 22:20:01 2011	(r221612)
@@ -295,6 +295,7 @@ ubser_attach(device_t dev)
 	if (error) {
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
 
 	mtx_lock(&sc->sc_mtx);
 	usbd_xfer_set_stall(sc->sc_xfer[UBSER_BULK_DT_WR]);
@@ -316,7 +317,7 @@ ubser_detach(device_t dev)
 
 	DPRINTF("\n");
 
-	ucom_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_numser);
+	ucom_detach(&sc->sc_super_ucom, sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UBSER_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/uchcom.c
==============================================================================
--- stable/8/sys/dev/usb/serial/uchcom.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/uchcom.c	Sat May  7 22:20:01 2011	(r221612)
@@ -353,6 +353,8 @@ uchcom_attach(device_t dev)
 	if (error) {
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);
 
 detach:
@@ -367,7 +369,7 @@ uchcom_detach(device_t dev)
 
 	DPRINTFN(11, "\n");
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UCHCOM_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/ucycom.c
==============================================================================
--- stable/8/sys/dev/usb/serial/ucycom.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/ucycom.c	Sat May  7 22:20:01 2011	(r221612)
@@ -271,13 +271,15 @@ ucycom_attach(device_t dev)
 	}
 	error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
 	    &ucycom_callback, &sc->sc_mtx);
-
 	if (error) {
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	if (urd_ptr) {
 		free(urd_ptr, M_USBDEV);
 	}
+
 	return (0);			/* success */
 
 detach:
@@ -293,7 +295,7 @@ ucycom_detach(device_t dev)
 {
 	struct ucycom_softc *sc = device_get_softc(dev);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UCYCOM_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/ufoma.c
==============================================================================
--- stable/8/sys/dev/usb/serial/ufoma.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/ufoma.c	Sat May  7 22:20:01 2011	(r221612)
@@ -449,6 +449,8 @@ ufoma_attach(device_t dev)
 		DPRINTF("ucom_attach failed\n");
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	/*Sysctls*/
 	sctx = device_get_sysctl_ctx(dev);
 	soid = device_get_sysctl_tree(dev);
@@ -465,7 +467,7 @@ ufoma_attach(device_t dev)
 			CTLFLAG_RW|CTLTYPE_STRING, sc, 0, ufoma_sysctl_open,
 			"A", "Mode to transit when port is opened");
 	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "comunit",
-			CTLFLAG_RD, &(sc->sc_ucom.sc_unit), 0, 
+			CTLFLAG_RD, &(sc->sc_super_ucom.sc_unit), 0, 
 			"Unit number as USB serial");
 
 	return (0);			/* success */
@@ -480,7 +482,7 @@ ufoma_detach(device_t dev)
 {
 	struct ufoma_softc *sc = device_get_softc(dev);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_ctrl_xfer, UFOMA_CTRL_ENDPT_MAX);
 	usbd_transfer_unsetup(sc->sc_bulk_xfer, UFOMA_BULK_ENDPT_MAX);
 

Modified: stable/8/sys/dev/usb/serial/uftdi.c
==============================================================================
--- stable/8/sys/dev/usb/serial/uftdi.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/uftdi.c	Sat May  7 22:20:01 2011	(r221612)
@@ -332,6 +332,8 @@ uftdi_attach(device_t dev)
 	if (error) {
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);			/* success */
 
 detach:
@@ -344,7 +346,7 @@ uftdi_detach(device_t dev)
 {
 	struct uftdi_softc *sc = device_get_softc(dev);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UFTDI_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/ugensa.c
==============================================================================
--- stable/8/sys/dev/usb/serial/ugensa.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/ugensa.c	Sat May  7 22:20:01 2011	(r221612)
@@ -246,6 +246,8 @@ ugensa_attach(device_t dev)
 		DPRINTF("attach failed\n");
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);			/* success */
 
 detach:
@@ -259,7 +261,7 @@ ugensa_detach(device_t dev)
 	struct ugensa_softc *sc = device_get_softc(dev);
 	uint8_t x;
 
-	ucom_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_niface);
+	ucom_detach(&sc->sc_super_ucom, sc->sc_ucom);
 
 	for (x = 0; x < sc->sc_niface; x++) {
 		usbd_transfer_unsetup(sc->sc_sub[x].sc_xfer, UGENSA_N_TRANSFER);

Modified: stable/8/sys/dev/usb/serial/uipaq.c
==============================================================================
--- stable/8/sys/dev/usb/serial/uipaq.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/uipaq.c	Sat May  7 22:20:01 2011	(r221612)
@@ -1160,6 +1160,8 @@ uipaq_attach(device_t dev)
 	if (error) {
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);
 
 detach:
@@ -1172,7 +1174,7 @@ uipaq_detach(device_t dev)
 {
 	struct uipaq_softc *sc = device_get_softc(dev);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UIPAQ_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/umct.c
==============================================================================
--- stable/8/sys/dev/usb/serial/umct.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/umct.c	Sat May  7 22:20:01 2011	(r221612)
@@ -296,6 +296,8 @@ umct_attach(device_t dev)
 	if (error) {
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);			/* success */
 
 detach:
@@ -308,7 +310,7 @@ umct_detach(device_t dev)
 {
 	struct umct_softc *sc = device_get_softc(dev);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UMCT_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/umodem.c
==============================================================================
--- stable/8/sys/dev/usb/serial/umodem.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/umodem.c	Sat May  7 22:20:01 2011	(r221612)
@@ -388,6 +388,8 @@ umodem_attach(device_t dev)
 	if (error) {
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);
 
 detach:
@@ -815,7 +817,7 @@ umodem_detach(device_t dev)
 
 	DPRINTF("sc=%p\n", sc);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UMODEM_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/umoscom.c
==============================================================================
--- stable/8/sys/dev/usb/serial/umoscom.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/umoscom.c	Sat May  7 22:20:01 2011	(r221612)
@@ -337,6 +337,8 @@ umoscom_attach(device_t dev)
 	if (error) {
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);
 
 detach:
@@ -350,7 +352,7 @@ umoscom_detach(device_t dev)
 {
 	struct umoscom_softc *sc = device_get_softc(dev);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UMOSCOM_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/uplcom.c
==============================================================================
--- stable/8/sys/dev/usb/serial/uplcom.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/uplcom.c	Sat May  7 22:20:01 2011	(r221612)
@@ -445,6 +445,8 @@ uplcom_attach(device_t dev)
 		device_printf(dev, "init failed\n");
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);
 
 detach:
@@ -459,7 +461,7 @@ uplcom_detach(device_t dev)
 
 	DPRINTF("sc=%p\n", sc);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UPLCOM_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/usb_serial.c
==============================================================================
--- stable/8/sys/dev/usb/serial/usb_serial.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/usb_serial.c	Sat May  7 22:20:01 2011	(r221612)
@@ -122,13 +122,16 @@ static unsigned int ucom_cons_tx_low = 0
 static unsigned int ucom_cons_tx_high = 0;
 
 static int ucom_cons_unit = -1;
+static int ucom_cons_subunit = 0;
 static int ucom_cons_baud = 9600;
 static struct ucom_softc *ucom_cons_softc = NULL;
 
 TUNABLE_INT("hw.usb.ucom.cons_unit", &ucom_cons_unit);
 SYSCTL_INT(_hw_usb_ucom, OID_AUTO, cons_unit, CTLFLAG_RW,
     &ucom_cons_unit, 0, "console unit number");
-
+TUNABLE_INT("hw.usb.ucom.cons_subunit", &ucom_cons_subunit);
+SYSCTL_INT(_hw_usb_ucom, OID_AUTO, cons_subunit, CTLFLAG_RW,
+    &ucom_cons_subunit, 0, "console subunit number");
 TUNABLE_INT("hw.usb.ucom.cons_baud", &ucom_cons_baud);
 SYSCTL_INT(_hw_usb_ucom, OID_AUTO, cons_baud, CTLFLAG_RW,
     &ucom_cons_baud, 0, "console baud rate");
@@ -140,9 +143,9 @@ static usb_proc_callback_t ucom_cfg_line
 static usb_proc_callback_t ucom_cfg_status_change;
 static usb_proc_callback_t ucom_cfg_param;
 
-static uint8_t	ucom_units_alloc(uint32_t, uint32_t *);
-static void	ucom_units_free(uint32_t, uint32_t);
-static int	ucom_attach_tty(struct ucom_softc *, uint32_t);
+static int	ucom_unit_alloc(void);
+static void	ucom_unit_free(int);
+static int	ucom_attach_tty(struct ucom_super_softc *, struct ucom_softc *);
 static void	ucom_detach_tty(struct ucom_softc *);
 static void	ucom_queue_command(struct ucom_softc *,
 		    usb_proc_callback_t *, struct termios *pt,
@@ -175,84 +178,57 @@ static struct ttydevsw ucom_class = {
 MODULE_DEPEND(ucom, usb, 1, 1, 1);
 MODULE_VERSION(ucom, 1);
 
-#define	UCOM_UNIT_MAX 0x200		/* exclusive */
-#define	UCOM_SUB_UNIT_MAX 0x100		/* exclusive */
+#define	UCOM_UNIT_MAX 		128	/* limits size of ucom_bitmap */
 
 static uint8_t ucom_bitmap[(UCOM_UNIT_MAX + 7) / 8];
 static struct mtx ucom_bitmap_mtx;
 MTX_SYSINIT(ucom_bitmap_mtx, &ucom_bitmap_mtx, "ucom bitmap", MTX_DEF);
 
-static uint8_t
-ucom_units_alloc(uint32_t sub_units, uint32_t *p_root_unit)
+#define UCOM_TTY_PREFIX		"U"
+
+/*
+ * Mark a unit number (the X in cuaUX) as in use.
+ *
+ * Note that devices using a different naming scheme (see ucom_tty_name()
+ * callback) still use this unit allocation.
+ */
+static int
+ucom_unit_alloc(void)
 {
-	uint32_t n;
-	uint32_t o;
-	uint32_t x;
-	uint32_t max = UCOM_UNIT_MAX - (UCOM_UNIT_MAX % sub_units);
-	uint8_t error = 1;
+	int unit;
 
 	mtx_lock(&ucom_bitmap_mtx);
 
-	for (n = 0; n < max; n += sub_units) {
-
-		/* check for free consecutive bits */
-
-		for (o = 0; o < sub_units; o++) {
-
-			x = n + o;
-
-			if (ucom_bitmap[x / 8] & (1 << (x % 8))) {
-				goto skip;
-			}
-		}
-
-		/* allocate */
-
-		for (o = 0; o < sub_units; o++) {
-
-			x = n + o;
-
-			ucom_bitmap[x / 8] |= (1 << (x % 8));
+	for (unit = 0; unit < UCOM_UNIT_MAX; unit++) {
+		if ((ucom_bitmap[unit / 8] & (1 << (unit % 8))) == 0) {
+			ucom_bitmap[unit / 8] |= (1 << (unit % 8));
+			break;
 		}
-
-		error = 0;
-
-		break;
-
-skip:		;
 	}
 
 	mtx_unlock(&ucom_bitmap_mtx);
 
-	/*
-	 * Always set the variable pointed to by "p_root_unit" so that
-	 * the compiler does not think that it is used uninitialised:
-	 */
-	*p_root_unit = n;
-
-	return (error);
+	if (unit == UCOM_UNIT_MAX)
+		return -1;
+	else
+		return unit;
 }
 
+/*
+ * Mark the unit number as not in use.
+ */
 static void
-ucom_units_free(uint32_t root_unit, uint32_t sub_units)
+ucom_unit_free(int unit)
 {
-	uint32_t x;
-
 	mtx_lock(&ucom_bitmap_mtx);
 
-	while (sub_units--) {
-		x = root_unit + sub_units;
-		ucom_bitmap[x / 8] &= ~(1 << (x % 8));
-	}
+	ucom_bitmap[unit / 8] &= ~(1 << (unit % 8));
 
 	mtx_unlock(&ucom_bitmap_mtx);
 }
 
 /*
- * "N" sub_units are setup at a time. All sub-units will
- * be given sequential unit numbers. The number of
- * sub-units can be used to differentiate among
- * different types of devices.
+ * Setup a group of one or more serial ports.
  *
  * The mutex pointed to by "mtx" is applied before all
  * callbacks are called back. Also "mtx" must be applied
@@ -260,47 +236,47 @@ ucom_units_free(uint32_t root_unit, uint
  */
 int
 ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc,
-    uint32_t sub_units, void *parent,
+    uint32_t subunits, void *parent,
     const struct ucom_callback *callback, struct mtx *mtx)
 {
-	uint32_t n;
-	uint32_t root_unit;
+	uint32_t subunit;
 	int error = 0;
 
 	if ((sc == NULL) ||
-	    (sub_units == 0) ||
-	    (sub_units > UCOM_SUB_UNIT_MAX) ||
+	    (subunits == 0) ||
 	    (callback == NULL)) {
 		return (EINVAL);
 	}
 
-	/* XXX unit management does not really belong here */
-	if (ucom_units_alloc(sub_units, &root_unit)) {
+	ssc->sc_unit = ucom_unit_alloc();
+	if (ssc->sc_unit == -1)
 		return (ENOMEM);
-	}
 
 	error = usb_proc_create(&ssc->sc_tq, mtx, "ucom", USB_PRI_MED);
 	if (error) {
-		ucom_units_free(root_unit, sub_units);
+		ucom_unit_free(ssc->sc_unit);
 		return (error);
 	}
+	ssc->sc_subunits = subunits;
 
-	for (n = 0; n != sub_units; n++, sc++) {
-		sc->sc_unit = root_unit + n;
-		sc->sc_local_unit = n;
-		sc->sc_super = ssc;
-		sc->sc_mtx = mtx;
-		sc->sc_parent = parent;
-		sc->sc_callback = callback;
+	for (subunit = 0; subunit < ssc->sc_subunits; subunit++) {
+		sc[subunit].sc_subunit = subunit;
+		sc[subunit].sc_super = ssc;
+		sc[subunit].sc_mtx = mtx;
+		sc[subunit].sc_parent = parent;
+		sc[subunit].sc_callback = callback;
 
-		error = ucom_attach_tty(sc, sub_units);
+		error = ucom_attach_tty(ssc, &sc[subunit]);
 		if (error) {
-			ucom_detach(ssc, sc - n, n);
-			ucom_units_free(root_unit + n, sub_units - n);
+			ucom_detach(ssc, &sc[0]);
 			return (error);
 		}
-		sc->sc_flag |= UCOM_FLAG_ATTACHED;
+		sc[subunit].sc_flag |= UCOM_FLAG_ATTACHED;
 	}
+
+	DPRINTF("tp = %p, unit = %d, subunits = %d\n",
+		sc->sc_tty, ssc->sc_unit, ssc->sc_subunits);
+
 	return (0);
 }
 
@@ -309,62 +285,51 @@ ucom_attach(struct ucom_super_softc *ssc
  * the structure pointed to by "ssc" and "sc" is zero.
  */
 void
-ucom_detach(struct ucom_super_softc *ssc, struct ucom_softc *sc,
-    uint32_t sub_units)
+ucom_detach(struct ucom_super_softc *ssc, struct ucom_softc *sc)
 {
-	uint32_t n;
+	uint32_t subunit;
 
 	usb_proc_drain(&ssc->sc_tq);
 
-	for (n = 0; n != sub_units; n++, sc++) {
-		if (sc->sc_flag & UCOM_FLAG_ATTACHED) {
-
-			ucom_detach_tty(sc);
+	for (subunit = 0; subunit < ssc->sc_subunits; subunit++) {
+		if (sc[subunit].sc_flag & UCOM_FLAG_ATTACHED) {
 
-			ucom_units_free(sc->sc_unit, 1);
+			ucom_detach_tty(&sc[subunit]);
 
-			/* avoid duplicate detach: */
-			sc->sc_flag &= ~UCOM_FLAG_ATTACHED;
+			/* avoid duplicate detach */
+			sc[subunit].sc_flag &= ~UCOM_FLAG_ATTACHED;
 		}
 	}
+	ucom_unit_free(ssc->sc_unit);
 	usb_proc_free(&ssc->sc_tq);
 }
 
 static int
-ucom_attach_tty(struct ucom_softc *sc, uint32_t sub_units)
+ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
 {
 	struct tty *tp;
-	int error = 0;
 	char buf[32];			/* temporary TTY device name buffer */
 
 	tp = tty_alloc_mutex(&ucom_class, sc, sc->sc_mtx);
-	if (tp == NULL) {
-		error = ENOMEM;
-		goto done;
-	}
-	DPRINTF("tp = %p, unit = %d\n", tp, sc->sc_unit);
-
-	buf[0] = 0;			/* set some default value */
+	if (tp == NULL)
+		return (ENOMEM);
 
 	/* Check if the client has a custom TTY name */
+	buf[0] = '\0';
 	if (sc->sc_callback->ucom_tty_name) {
 		sc->sc_callback->ucom_tty_name(sc, buf,
-		    sizeof(buf), sc->sc_local_unit);
+		    sizeof(buf), ssc->sc_unit, sc->sc_subunit);
 	}
 	if (buf[0] == 0) {
 		/* Use default TTY name */
-		if (sub_units > 1) {
+		if (ssc->sc_subunits > 1) {
 			/* multiple modems in one */
-			if (snprintf(buf, sizeof(buf), "U%u.%u",
-			    sc->sc_unit - sc->sc_local_unit,
-			    sc->sc_local_unit)) {
-				/* ignore */
-			}
+			snprintf(buf, sizeof(buf), UCOM_TTY_PREFIX "%u.%u",
+			    ssc->sc_unit, sc->sc_subunit);
 		} else {
 			/* single modem */
-			if (snprintf(buf, sizeof(buf), "U%u", sc->sc_unit)) {
-				/* ignore */
-			}
+			snprintf(buf, sizeof(buf), UCOM_TTY_PREFIX "%u",
+			    ssc->sc_unit);
 		}
 	}
 	tty_makedev(tp, NULL, "%s", buf);
@@ -376,10 +341,12 @@ ucom_attach_tty(struct ucom_softc *sc, u
 
 	/* Check if this device should be a console */
 	if ((ucom_cons_softc == NULL) && 
-	    (sc->sc_unit == ucom_cons_unit)) {
-
+	    (ssc->sc_unit == ucom_cons_unit) &&
+	    (sc->sc_subunit == ucom_cons_subunit)) {
 		struct termios t;
 
+		DPRINTF("unit %d subunit %d is console", ssc->sc_unit, sc->sc_subunit);
+
 		ucom_cons_softc = sc;
 
 		memset(&t, 0, sizeof(t));
@@ -397,8 +364,8 @@ ucom_attach_tty(struct ucom_softc *sc, u
 		ucom_param(ucom_cons_softc->sc_tty, &t);
 		mtx_unlock(ucom_cons_softc->sc_mtx);
 	}
-done:
-	return (error);
+
+	return (0);
 }
 
 static void
@@ -411,6 +378,7 @@ ucom_detach_tty(struct ucom_softc *sc)
 	if (sc->sc_flag & UCOM_FLAG_CONSOLE) {
 		mtx_lock(ucom_cons_softc->sc_mtx);
 		ucom_close(ucom_cons_softc->sc_tty);
+		sc->sc_flag &= ~UCOM_FLAG_CONSOLE;
 		mtx_unlock(ucom_cons_softc->sc_mtx);
 		ucom_cons_softc = NULL;
 	}
@@ -446,6 +414,24 @@ ucom_detach_tty(struct ucom_softc *sc)
 	cv_destroy(&sc->sc_cv);
 }
 
+void
+ucom_set_pnpinfo_usb(struct ucom_super_softc *ssc, device_t dev)
+{
+    char buf[64];
+    uint8_t iface_index;
+    struct usb_attach_arg *uaa;
+
+    snprintf(buf, sizeof(buf), "ttyname=%s%d ttyports=%d",
+	     UCOM_TTY_PREFIX, ssc->sc_unit, ssc->sc_subunits);
+
+    /* Store the PNP info in the first interface for the dev */
+    uaa = device_get_ivars(dev);
+    iface_index = uaa->info.bIfaceIndex;
+    
+    if (usbd_set_pnpinfo(uaa->device, iface_index, buf) != 0)
+	device_printf(dev, "Could not set PNP info\n");
+}
+
 static void
 ucom_queue_command(struct ucom_softc *sc,
     usb_proc_callback_t *fn, struct termios *pt,

Modified: stable/8/sys/dev/usb/serial/usb_serial.h
==============================================================================
--- stable/8/sys/dev/usb/serial/usb_serial.h	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/usb_serial.h	Sat May  7 22:20:01 2011	(r221612)
@@ -105,7 +105,7 @@ struct ucom_callback {
 	void    (*ucom_stop_read) (struct ucom_softc *);
 	void    (*ucom_start_write) (struct ucom_softc *);
 	void    (*ucom_stop_write) (struct ucom_softc *);
-	void    (*ucom_tty_name) (struct ucom_softc *, char *pbuf, uint16_t buflen, uint16_t local_subunit);
+	void    (*ucom_tty_name) (struct ucom_softc *, char *pbuf, uint16_t buflen, uint16_t unit, uint16_t subunit);
 	void    (*ucom_poll) (struct ucom_softc *);
 };
 
@@ -133,6 +133,8 @@ struct ucom_param_task {
 
 struct ucom_super_softc {
 	struct usb_process sc_tq;
+	uint32_t sc_unit;
+	uint32_t sc_subunits;
 };
 
 struct ucom_softc {
@@ -161,8 +163,7 @@ struct ucom_softc {
 	struct tty *sc_tty;
 	struct mtx *sc_mtx;
 	void   *sc_parent;
-	uint32_t sc_unit;
-	uint32_t sc_local_unit;
+	uint32_t sc_subunit;
 	uint16_t sc_portno;
 	uint16_t sc_flag;
 #define	UCOM_FLAG_RTS_IFLOW	0x01	/* use RTS input flow control */
@@ -192,8 +193,8 @@ struct ucom_softc {
 int	ucom_attach(struct ucom_super_softc *,
 	    struct ucom_softc *, uint32_t, void *,
 	    const struct ucom_callback *callback, struct mtx *);
-void	ucom_detach(struct ucom_super_softc *,
-	    struct ucom_softc *, uint32_t);
+void	ucom_detach(struct ucom_super_softc *, struct ucom_softc *);
+void	ucom_set_pnpinfo_usb(struct ucom_super_softc *, device_t);
 void	ucom_status_change(struct ucom_softc *);
 uint8_t	ucom_get_data(struct ucom_softc *, struct usb_page_cache *,
 	    uint32_t, uint32_t, uint32_t *);

Modified: stable/8/sys/dev/usb/serial/uslcom.c
==============================================================================
--- stable/8/sys/dev/usb/serial/uslcom.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/uslcom.c	Sat May  7 22:20:01 2011	(r221612)
@@ -332,6 +332,8 @@ uslcom_attach(device_t dev)
 	if (error) {
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);
 
 detach:
@@ -346,7 +348,7 @@ uslcom_detach(device_t dev)
 
 	DPRINTF("sc=%p\n", sc);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, USLCOM_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/uvisor.c
==============================================================================
--- stable/8/sys/dev/usb/serial/uvisor.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/uvisor.c	Sat May  7 22:20:01 2011	(r221612)
@@ -346,6 +346,8 @@ uvisor_attach(device_t dev)
 		DPRINTF("ucom_attach failed\n");
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	return (0);
 
 detach:
@@ -360,7 +362,7 @@ uvisor_detach(device_t dev)
 
 	DPRINTF("sc=%p\n", sc);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UVISOR_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/serial/uvscom.c
==============================================================================
--- stable/8/sys/dev/usb/serial/uvscom.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/serial/uvscom.c	Sat May  7 22:20:01 2011	(r221612)
@@ -320,6 +320,8 @@ uvscom_attach(device_t dev)
 	if (error) {
 		goto detach;
 	}
+	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
+
 	/* start interrupt pipe */
 	mtx_lock(&sc->sc_mtx);
 	usbd_transfer_start(sc->sc_xfer[UVSCOM_INTR_DT_RD]);
@@ -344,7 +346,7 @@ uvscom_detach(device_t dev)
 	if (sc->sc_xfer[UVSCOM_INTR_DT_RD])
 		usbd_transfer_stop(sc->sc_xfer[UVSCOM_INTR_DT_RD]);
 
-	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
+	ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
 	usbd_transfer_unsetup(sc->sc_xfer, UVSCOM_N_TRANSFER);
 	mtx_destroy(&sc->sc_mtx);
 

Modified: stable/8/sys/dev/usb/usb_device.c
==============================================================================
--- stable/8/sys/dev/usb/usb_device.c	Sat May  7 22:05:14 2011	(r221611)
+++ stable/8/sys/dev/usb/usb_device.c	Sat May  7 22:20:01 2011	(r221612)
@@ -87,7 +87,7 @@ static void	usb_init_endpoint(struct usb
 		    struct usb_endpoint *);
 static void	usb_unconfigure(struct usb_device *, uint8_t);
 static void	usb_detach_device_sub(struct usb_device *, device_t *,
-		    uint8_t);
+		    char **, uint8_t);
 static uint8_t	usb_probe_and_attach_sub(struct usb_device *,
 		    struct usb_attach_arg *);
 static void	usb_init_attach_arg(struct usb_device *,
@@ -1032,9 +1032,10 @@ usb_reset_iface_endpoints(struct usb_dev
  *------------------------------------------------------------------------*/
 static void
 usb_detach_device_sub(struct usb_device *udev, device_t *ppdev,
-    uint8_t flag)
+    char **ppnpinfo, uint8_t flag)
 {
 	device_t dev;
+	char *pnpinfo;
 	int err;
 
 	dev = *ppdev;
@@ -1066,11 +1067,17 @@ usb_detach_device_sub(struct usb_device 
 			goto error;
 		}
 	}
+
+	pnpinfo = *ppnpinfo;
+	if (pnpinfo != NULL) {
+		*ppnpinfo = NULL;
+		free(pnpinfo, M_USBDEV);
+	}
 	return;
 
 error:
 	/* Detach is not allowed to fail in the USB world */
-	panic("A USB driver would not detach\n");
+	panic("usb_detach_device_sub: A USB driver would not detach\n");
 }
 
 /*------------------------------------------------------------------------*
@@ -1119,7 +1126,8 @@ usb_detach_device(struct usb_device *ude
 			/* looks like the end of the USB interfaces */
 			break;
 		}
-		usb_detach_device_sub(udev, &iface->subdev, flag);
+		usb_detach_device_sub(udev, &iface->subdev,
+		    &iface->pnpinfo, flag);
 	}
 }
 
@@ -2409,25 +2417,24 @@ usb_notify_addq_compat(const char *type,
 	snprintf(data, buf_size,
 	    "%s"
 	    "%s "
+	    "at port=%u "
 	    "vendor=0x%04x "
 	    "product=0x%04x "
 	    "devclass=0x%02x "
 	    "devsubclass=0x%02x "
 	    "sernum=\"%s\" "
 	    "release=0x%04x "
-	    "at "
-	    "port=%u "
 	    "on "
 	    "%s\n",
 	    ntype,
 	    udev->ugen_name,
+	    udev->port_no,
 	    UGETW(udev->ddesc.idVendor),
 	    UGETW(udev->ddesc.idProduct),
 	    udev->ddesc.bDeviceClass,
 	    udev->ddesc.bDeviceSubClass,
 	    usb_get_serial(udev),
 	    UGETW(udev->ddesc.bcdDevice),
-	    udev->port_no,
 	    udev->parent_hub != NULL ?
 		udev->parent_hub->ugen_name :
 		device_get_nameunit(device_get_parent(udev->bus->bdev)));
@@ -2459,7 +2466,7 @@ usb_notify_addq(const char *type, struct
 	    "release=0x%04x "
 	    "mode=%s "
 	    "port=%u "
-	    "parent=%s\n",
+	    "parent=%s",
 	    udev->ugen_name,
 	    UGETW(udev->ddesc.idVendor),
 	    UGETW(udev->ddesc.idProduct),
@@ -2498,7 +2505,7 @@ usb_notify_addq(const char *type, struct
 		    "endpoints=%d "
 		    "intclass=0x%02x "
 		    "intsubclass=0x%02x "
-		    "intprotocol=0x%02x\n",
+		    "intprotocol=0x%02x",
 		    udev->ugen_name,
 		    UGETW(udev->ddesc.idVendor),
 		    UGETW(udev->ddesc.idProduct),
@@ -2682,3 +2689,37 @@ usbd_enum_is_locked(struct usb_device *u
 {
 	return (sx_xlocked(&udev->enum_sx));
 }
+
+/*
+ * The following function is used to set the per-interface specific

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



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