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>