From owner-svn-src-stable@FreeBSD.ORG Thu Oct 29 23:23:34 2009 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BFD881065694; Thu, 29 Oct 2009 23:23:34 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id AA0658FC16; Thu, 29 Oct 2009 23:23:34 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n9TNNYdB015298; Thu, 29 Oct 2009 23:23:34 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n9TNNYvk015280; Thu, 29 Oct 2009 23:23:34 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <200910292323.n9TNNYvk015280@svn.freebsd.org> From: Andrew Thompson Date: Thu, 29 Oct 2009 23:23:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r198655 - in stable/8/sys: . amd64/include/xen cddl/contrib/opensolaris contrib/dev/acpica contrib/pf dev/usb/serial dev/xen/xenpci X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Oct 2009 23:23:34 -0000 Author: thompsa Date: Thu Oct 29 23:23:34 2009 New Revision: 198655 URL: http://svn.freebsd.org/changeset/base/198655 Log: MFC r197570 Add experimental support for usb serial console and polled mode during DDB. Modified: 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) 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/uvscom.c stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/sys/dev/usb/serial/uark.c ============================================================================== --- stable/8/sys/dev/usb/serial/uark.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/uark.c Thu Oct 29 23:23:34 2009 (r198655) @@ -114,6 +114,7 @@ static void uark_cfg_get_status(struct u uint8_t *); static void uark_cfg_set_break(struct ucom_softc *, uint8_t); static void uark_cfg_write(struct uark_softc *, uint16_t, uint16_t); +static void uark_poll(struct ucom_softc *ucom); static const struct usb_config uark_xfer_config[UARK_N_TRANSFER] = { @@ -146,6 +147,7 @@ static const struct ucom_callback uark_c .ucom_stop_read = &uark_stop_read, .ucom_start_write = &uark_start_write, .ucom_stop_write = &uark_stop_write, + .ucom_poll = &uark_poll, }; static device_method_t uark_methods[] = { @@ -431,3 +433,10 @@ uark_cfg_write(struct uark_softc *sc, ui "(ignored)\n", usbd_errstr(err)); } } + +static void +uark_poll(struct ucom_softc *ucom) +{ + struct uark_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UARK_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/ubsa.c ============================================================================== --- stable/8/sys/dev/usb/serial/ubsa.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/ubsa.c Thu Oct 29 23:23:34 2009 (r198655) @@ -194,6 +194,7 @@ static void ubsa_start_write(struct ucom static void ubsa_stop_write(struct ucom_softc *); static void ubsa_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *); +static void ubsa_poll(struct ucom_softc *ucom); static const struct usb_config ubsa_config[UBSA_N_TRANSFER] = { @@ -236,6 +237,7 @@ static const struct ucom_callback ubsa_c .ucom_stop_read = &ubsa_stop_read, .ucom_start_write = &ubsa_start_write, .ucom_stop_write = &ubsa_stop_write, + .ucom_poll = &ubsa_poll, }; static const struct usb_device_id ubsa_devs[] = { @@ -659,3 +661,11 @@ tr_setup: } } + +static void +ubsa_poll(struct ucom_softc *ucom) +{ + struct ubsa_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UBSA_N_TRANSFER); + +} Modified: stable/8/sys/dev/usb/serial/ubser.c ============================================================================== --- stable/8/sys/dev/usb/serial/ubser.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/ubser.c Thu Oct 29 23:23:34 2009 (r198655) @@ -163,6 +163,7 @@ static void ubser_start_read(struct ucom static void ubser_stop_read(struct ucom_softc *); static void ubser_start_write(struct ucom_softc *); static void ubser_stop_write(struct ucom_softc *); +static void ubser_poll(struct ucom_softc *ucom); static const struct usb_config ubser_config[UBSER_N_TRANSFER] = { @@ -193,6 +194,7 @@ static const struct ucom_callback ubser_ .ucom_stop_read = &ubser_stop_read, .ucom_start_write = &ubser_start_write, .ucom_stop_write = &ubser_stop_write, + .ucom_poll = &ubser_poll, }; static device_method_t ubser_methods[] = { @@ -535,3 +537,10 @@ ubser_stop_write(struct ucom_softc *ucom usbd_transfer_stop(sc->sc_xfer[UBSER_BULK_DT_WR]); } + +static void +ubser_poll(struct ucom_softc *ucom) +{ + struct ubser_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UBSER_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/uchcom.c ============================================================================== --- stable/8/sys/dev/usb/serial/uchcom.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/uchcom.c Thu Oct 29 23:23:34 2009 (r198655) @@ -230,6 +230,7 @@ static void uchcom_set_dte_rate(struct u static void uchcom_set_line_control(struct uchcom_softc *, tcflag_t); static void uchcom_clear_chip(struct uchcom_softc *); static void uchcom_reset_chip(struct uchcom_softc *); +static void uchcom_poll(struct ucom_softc *ucom); static device_probe_t uchcom_probe; static device_attach_t uchcom_attach; @@ -280,6 +281,7 @@ static struct ucom_callback uchcom_callb .ucom_stop_read = &uchcom_stop_read, .ucom_start_write = &uchcom_start_write, .ucom_stop_write = &uchcom_stop_write, + .ucom_poll = &uchcom_poll, }; /* ---------------------------------------------------------------------- @@ -888,6 +890,13 @@ tr_setup: } } +static void +uchcom_poll(struct ucom_softc *ucom) +{ + struct uchcom_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UCHCOM_N_TRANSFER); +} + static device_method_t uchcom_methods[] = { /* Device interface */ DEVMETHOD(device_probe, uchcom_probe), Modified: stable/8/sys/dev/usb/serial/ucycom.c ============================================================================== --- stable/8/sys/dev/usb/serial/ucycom.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/ucycom.c Thu Oct 29 23:23:34 2009 (r198655) @@ -124,6 +124,7 @@ static void ucycom_stop_write(struct uco static void ucycom_cfg_write(struct ucycom_softc *, uint32_t, uint8_t); static int ucycom_pre_param(struct ucom_softc *, struct termios *); static void ucycom_cfg_param(struct ucom_softc *, struct termios *); +static void ucycom_poll(struct ucom_softc *ucom); static const struct usb_config ucycom_config[UCYCOM_N_TRANSFER] = { @@ -154,6 +155,7 @@ static const struct ucom_callback ucycom .ucom_stop_read = &ucycom_stop_read, .ucom_start_write = &ucycom_start_write, .ucom_stop_write = &ucycom_stop_write, + .ucom_poll = &ucycom_poll, }; static device_method_t ucycom_methods[] = { @@ -578,3 +580,10 @@ tr_setup: } } + +static void +ucycom_poll(struct ucom_softc *ucom) +{ + struct ucycom_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UCYCOM_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/ufoma.c ============================================================================== --- stable/8/sys/dev/usb/serial/ufoma.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/ufoma.c Thu Oct 29 23:23:34 2009 (r198655) @@ -230,13 +230,13 @@ static void ufoma_start_read(struct ucom static void ufoma_stop_read(struct ucom_softc *); static void ufoma_start_write(struct ucom_softc *); static void ufoma_stop_write(struct ucom_softc *); +static void ufoma_poll(struct ucom_softc *ucom); /*sysctl stuff*/ static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS); static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS); static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS); - static const struct usb_config ufoma_ctrl_config[UFOMA_CTRL_ENDPT_MAX] = { @@ -304,6 +304,7 @@ static const struct ucom_callback ufoma_ .ucom_stop_read = &ufoma_stop_read, .ucom_start_write = &ufoma_start_write, .ucom_stop_write = &ufoma_stop_write, + .ucom_poll = &ufoma_poll, }; static device_method_t ufoma_methods[] = { @@ -1241,3 +1242,11 @@ static int ufoma_sysctl_open(SYSCTL_HAND return EINVAL; } + +static void +ufoma_poll(struct ucom_softc *ucom) +{ + struct ufoma_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_ctrl_xfer, UFOMA_CTRL_ENDPT_MAX); + usbd_transfer_poll(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 Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/uftdi.c Thu Oct 29 23:23:34 2009 (r198655) @@ -156,6 +156,7 @@ static void uftdi_stop_read(struct ucom_ static void uftdi_start_write(struct ucom_softc *); static void uftdi_stop_write(struct ucom_softc *); static uint8_t uftdi_8u232am_getrate(uint32_t, uint16_t *); +static void uftdi_poll(struct ucom_softc *ucom); static const struct usb_config uftdi_config[UFTDI_N_TRANSFER] = { @@ -190,6 +191,7 @@ static const struct ucom_callback uftdi_ .ucom_stop_read = &uftdi_stop_read, .ucom_start_write = &uftdi_start_write, .ucom_stop_write = &uftdi_stop_write, + .ucom_poll = &uftdi_poll, }; static device_method_t uftdi_methods[] = { @@ -808,3 +810,10 @@ done: *rate = result; return (0); } + +static void +uftdi_poll(struct ucom_softc *ucom) +{ + struct uftdi_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UFTDI_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/ugensa.c ============================================================================== --- stable/8/sys/dev/usb/serial/ugensa.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/ugensa.c Thu Oct 29 23:23:34 2009 (r198655) @@ -110,9 +110,9 @@ static void ugensa_start_read(struct uco static void ugensa_stop_read(struct ucom_softc *); static void ugensa_start_write(struct ucom_softc *); static void ugensa_stop_write(struct ucom_softc *); +static void ugensa_poll(struct ucom_softc *ucom); -static const struct usb_config - ugensa_xfer_config[UGENSA_N_TRANSFER] = { +static const struct usb_config ugensa_xfer_config[UGENSA_N_TRANSFER] = { [UGENSA_BULK_DT_WR] = { .type = UE_BULK, @@ -138,6 +138,7 @@ static const struct ucom_callback ugensa .ucom_stop_read = &ugensa_stop_read, .ucom_start_write = &ugensa_start_write, .ucom_stop_write = &ugensa_stop_write, + .ucom_poll = &ugensa_poll, }; static device_method_t ugensa_methods[] = { @@ -369,3 +370,12 @@ ugensa_stop_write(struct ucom_softc *uco usbd_transfer_stop(ssc->sc_xfer[UGENSA_BULK_DT_WR]); } + +static void +ugensa_poll(struct ucom_softc *ucom) +{ + struct ugensa_softc *sc = ucom->sc_parent; + struct ugensa_sub_softc *ssc = sc->sc_sub + ucom->sc_portno; + + usbd_transfer_poll(ssc->sc_xfer, UGENSA_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/uipaq.c ============================================================================== --- stable/8/sys/dev/usb/serial/uipaq.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/uipaq.c Thu Oct 29 23:23:34 2009 (r198655) @@ -122,6 +122,7 @@ static void uipaq_stop_write(struct ucom static void uipaq_cfg_set_dtr(struct ucom_softc *, uint8_t); static void uipaq_cfg_set_rts(struct ucom_softc *, uint8_t); static void uipaq_cfg_set_break(struct ucom_softc *, uint8_t); +static void uipaq_poll(struct ucom_softc *ucom); static const struct usb_config uipaq_config_data[UIPAQ_N_TRANSFER] = { @@ -152,6 +153,7 @@ static const struct ucom_callback uipaq_ .ucom_stop_read = &uipaq_stop_read, .ucom_start_write = &uipaq_start_write, .ucom_stop_write = &uipaq_stop_write, + .ucom_poll = &uipaq_poll, }; /* @@ -1342,3 +1344,10 @@ tr_setup: return; } } + +static void +uipaq_poll(struct ucom_softc *ucom) +{ + struct uipaq_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UIPAQ_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/umct.c ============================================================================== --- stable/8/sys/dev/usb/serial/umct.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/umct.c Thu Oct 29 23:23:34 2009 (r198655) @@ -142,6 +142,7 @@ static void umct_start_read(struct ucom_ static void umct_stop_read(struct ucom_softc *); static void umct_start_write(struct ucom_softc *); static void umct_stop_write(struct ucom_softc *); +static void umct_poll(struct ucom_softc *ucom); static const struct usb_config umct_config[UMCT_N_TRANSFER] = { @@ -186,6 +187,7 @@ static const struct ucom_callback umct_c .ucom_stop_read = &umct_stop_read, .ucom_start_write = &umct_start_write, .ucom_stop_write = &umct_stop_write, + .ucom_poll = &umct_poll, }; static const struct usb_device_id umct_devs[] = { @@ -603,3 +605,10 @@ tr_setup: return; } } + +static void +umct_poll(struct ucom_softc *ucom) +{ + struct umct_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UMCT_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/umodem.c ============================================================================== --- stable/8/sys/dev/usb/serial/umodem.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/umodem.c Thu Oct 29 23:23:34 2009 (r198655) @@ -196,6 +196,7 @@ static void umodem_cfg_set_break(struct static void *umodem_get_desc(struct usb_attach_arg *, uint8_t, uint8_t); static usb_error_t umodem_set_comm_feature(struct usb_device *, uint8_t, uint16_t, uint16_t); +static void umodem_poll(struct ucom_softc *ucom); static const struct usb_config umodem_config[UMODEM_N_TRANSFER] = { @@ -242,6 +243,7 @@ static const struct ucom_callback umodem .ucom_stop_read = &umodem_stop_read, .ucom_start_write = &umodem_start_write, .ucom_stop_write = &umodem_stop_write, + .ucom_poll = &umodem_poll, }; static device_method_t umodem_methods[] = { @@ -810,3 +812,10 @@ umodem_detach(device_t dev) return (0); } + +static void +umodem_poll(struct ucom_softc *ucom) +{ + struct umodem_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UMODEM_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/umoscom.c ============================================================================== --- stable/8/sys/dev/usb/serial/umoscom.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/umoscom.c Thu Oct 29 23:23:34 2009 (r198655) @@ -210,6 +210,7 @@ static void umoscom_start_read(struct uc static void umoscom_stop_read(struct ucom_softc *); static void umoscom_start_write(struct ucom_softc *); static void umoscom_stop_write(struct ucom_softc *); +static void umoscom_poll(struct ucom_softc *ucom); static const struct usb_config umoscom_config_data[UMOSCOM_N_TRANSFER] = { @@ -257,6 +258,7 @@ static const struct ucom_callback umosco .ucom_stop_read = &umoscom_stop_read, .ucom_start_write = &umoscom_start_write, .ucom_stop_write = &umoscom_stop_write, + .ucom_poll = &umoscom_poll, }; static device_method_t umoscom_methods[] = { @@ -694,3 +696,10 @@ tr_setup: return; } } + +static void +umoscom_poll(struct ucom_softc *ucom) +{ + struct umoscom_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UMOSCOM_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/uplcom.c ============================================================================== --- stable/8/sys/dev/usb/serial/uplcom.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/uplcom.c Thu Oct 29 23:23:34 2009 (r198655) @@ -186,6 +186,7 @@ static void uplcom_start_write(struct uc static void uplcom_stop_write(struct ucom_softc *); static void uplcom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *); +static void uplcom_poll(struct ucom_softc *ucom); static device_probe_t uplcom_probe; static device_attach_t uplcom_attach; @@ -239,6 +240,7 @@ static struct ucom_callback uplcom_callb .ucom_stop_read = &uplcom_stop_read, .ucom_start_write = &uplcom_start_write, .ucom_stop_write = &uplcom_stop_write, + .ucom_poll = &uplcom_poll, }; #define USB_UPL(v,p,rl,rh,t) \ @@ -862,3 +864,10 @@ tr_setup: return; } } + +static void +uplcom_poll(struct ucom_softc *ucom) +{ + struct uplcom_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UPLCOM_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/usb_serial.c ============================================================================== --- stable/8/sys/dev/usb/serial/usb_serial.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/usb_serial.c Thu Oct 29 23:23:34 2009 (r198655) @@ -86,6 +86,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -98,14 +100,40 @@ __FBSDID("$FreeBSD$"); #include +#include "opt_gdb.h" + +SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom"); + #if USB_DEBUG static int ucom_debug = 0; -SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom"); SYSCTL_INT(_hw_usb_ucom, OID_AUTO, debug, CTLFLAG_RW, &ucom_debug, 0, "ucom debug level"); #endif +#define UCOM_CONS_BUFSIZE 1024 + +static uint8_t ucom_cons_rx_buf[UCOM_CONS_BUFSIZE]; +static uint8_t ucom_cons_tx_buf[UCOM_CONS_BUFSIZE]; + +static unsigned int ucom_cons_rx_low = 0; +static unsigned int ucom_cons_rx_high = 0; + +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_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_baud", &ucom_cons_baud); +SYSCTL_INT(_hw_usb_ucom, OID_AUTO, cons_baud, CTLFLAG_RW, + &ucom_cons_baud, 0, "console baud rate"); + static usb_proc_callback_t ucom_cfg_start_transfers; static usb_proc_callback_t ucom_cfg_open; static usb_proc_callback_t ucom_cfg_close; @@ -121,6 +149,7 @@ static void ucom_queue_command(struct uc usb_proc_callback_t *, struct termios *pt, struct usb_proc_msg *t0, struct usb_proc_msg *t1); static void ucom_shutdown(struct ucom_softc *); +static void ucom_ring(struct ucom_softc *, uint8_t); static void ucom_break(struct ucom_softc *, uint8_t); static void ucom_dtr(struct ucom_softc *, uint8_t); static void ucom_rts(struct ucom_softc *, uint8_t); @@ -147,7 +176,7 @@ static struct ttydevsw ucom_class = { MODULE_DEPEND(ucom, usb, 1, 1, 1); MODULE_VERSION(ucom, 1); -#define UCOM_UNIT_MAX 0x1000 /* exclusive */ +#define UCOM_UNIT_MAX 0x200 /* exclusive */ #define UCOM_SUB_UNIT_MAX 0x100 /* exclusive */ static uint8_t ucom_bitmap[(UCOM_UNIT_MAX + 7) / 8]; @@ -346,6 +375,29 @@ ucom_attach_tty(struct ucom_softc *sc, u DPRINTF("ttycreate: %s\n", buf); cv_init(&sc->sc_cv, "ucom"); + /* Check if this device should be a console */ + if ((ucom_cons_softc == NULL) && + (sc->sc_unit == ucom_cons_unit)) { + + struct termios t; + + ucom_cons_softc = sc; + + memset(&t, 0, sizeof(t)); + t.c_ispeed = ucom_cons_baud; + t.c_ospeed = t.c_ispeed; + t.c_cflag = CS8; + + mtx_lock(ucom_cons_softc->sc_mtx); + ucom_cons_rx_low = 0; + ucom_cons_rx_high = 0; + ucom_cons_tx_low = 0; + ucom_cons_tx_high = 0; + sc->sc_flag |= UCOM_FLAG_CONSOLE; + ucom_open(ucom_cons_softc->sc_tty); + ucom_param(ucom_cons_softc->sc_tty, &t); + mtx_unlock(ucom_cons_softc->sc_mtx); + } done: return (error); } @@ -357,12 +409,18 @@ ucom_detach_tty(struct ucom_softc *sc) DPRINTF("sc = %p, tp = %p\n", sc, sc->sc_tty); + if (sc->sc_flag & UCOM_FLAG_CONSOLE) { + mtx_lock(ucom_cons_softc->sc_mtx); + ucom_close(ucom_cons_softc->sc_tty); + mtx_unlock(ucom_cons_softc->sc_mtx); + ucom_cons_softc = NULL; + } + /* the config thread has been stopped when we get here */ mtx_lock(sc->sc_mtx); sc->sc_flag |= UCOM_FLAG_GONE; - sc->sc_flag &= ~(UCOM_FLAG_HL_READY | - UCOM_FLAG_LL_READY); + sc->sc_flag &= ~(UCOM_FLAG_HL_READY | UCOM_FLAG_LL_READY); mtx_unlock(sc->sc_mtx); if (tp) { tty_lock(tp); @@ -588,6 +646,8 @@ ucom_open(struct tty *tp) ucom_modem(tp, SER_DTR | SER_RTS, 0); + ucom_ring(sc, 0); + ucom_break(sc, 0); ucom_status_change(sc); @@ -653,6 +713,16 @@ ucom_ioctl(struct tty *tp, u_long cmd, c DPRINTF("cmd = 0x%08lx\n", cmd); switch (cmd) { +#if 0 + case TIOCSRING: + ucom_ring(sc, 1); + error = 0; + break; + case TIOCCRING: + ucom_ring(sc, 0); + error = 0; + break; +#endif case TIOCSBRK: ucom_break(sc, 1); error = 0; @@ -751,6 +821,8 @@ ucom_cfg_line_state(struct usb_proc_msg mask |= UCOM_LS_RTS; if (sc->sc_callback->ucom_cfg_set_break) mask |= UCOM_LS_BREAK; + if (sc->sc_callback->ucom_cfg_set_ring) + mask |= UCOM_LS_RING; /* compute the bits we are to program */ notch_bits = (sc->sc_pls_set & sc->sc_pls_clr) & mask; @@ -773,6 +845,9 @@ ucom_cfg_line_state(struct usb_proc_msg if (notch_bits & UCOM_LS_BREAK) sc->sc_callback->ucom_cfg_set_break(sc, (prev_value & UCOM_LS_BREAK) ? 1 : 0); + if (notch_bits & UCOM_LS_RING) + sc->sc_callback->ucom_cfg_set_ring(sc, + (prev_value & UCOM_LS_RING) ? 1 : 0); /* set last value */ if (any_bits & UCOM_LS_DTR) @@ -784,6 +859,9 @@ ucom_cfg_line_state(struct usb_proc_msg if (any_bits & UCOM_LS_BREAK) sc->sc_callback->ucom_cfg_set_break(sc, (last_value & UCOM_LS_BREAK) ? 1 : 0); + if (any_bits & UCOM_LS_RING) + sc->sc_callback->ucom_cfg_set_ring(sc, + (last_value & UCOM_LS_RING) ? 1 : 0); } static void @@ -811,6 +889,17 @@ ucom_line_state(struct ucom_softc *sc, } static void +ucom_ring(struct ucom_softc *sc, uint8_t onoff) +{ + DPRINTF("onoff = %d\n", onoff); + + if (onoff) + ucom_line_state(sc, UCOM_LS_RING, 0); + else + ucom_line_state(sc, 0, UCOM_LS_RING); +} + +static void ucom_break(struct ucom_softc *sc, uint8_t onoff) { DPRINTF("onoff = %d\n", onoff); @@ -895,6 +984,9 @@ ucom_status_change(struct ucom_softc *sc { mtx_assert(sc->sc_mtx, MA_OWNED); + if (sc->sc_flag & UCOM_FLAG_CONSOLE) + return; /* not supported */ + if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) { return; } @@ -1033,6 +1125,38 @@ ucom_get_data(struct ucom_softc *sc, str mtx_assert(sc->sc_mtx, MA_OWNED); + if (sc->sc_flag & UCOM_FLAG_CONSOLE) { + unsigned int temp; + + /* get total TX length */ + + temp = ucom_cons_tx_high - ucom_cons_tx_low; + temp %= UCOM_CONS_BUFSIZE; + + /* limit TX length */ + + if (temp > (UCOM_CONS_BUFSIZE - ucom_cons_tx_low)) + temp = (UCOM_CONS_BUFSIZE - ucom_cons_tx_low); + + if (temp > len) + temp = len; + + /* copy in data */ + + usbd_copy_in(pc, offset, ucom_cons_tx_buf + ucom_cons_tx_low, temp); + + /* update counters */ + + ucom_cons_tx_low += temp; + ucom_cons_tx_low %= UCOM_CONS_BUFSIZE; + + /* store actual length */ + + *actlen = temp; + + return (temp ? 1 : 0); + } + if (tty_gone(tp) || !(sc->sc_flag & UCOM_FLAG_GP_DATA)) { actlen[0] = 0; @@ -1080,6 +1204,34 @@ ucom_put_data(struct ucom_softc *sc, str mtx_assert(sc->sc_mtx, MA_OWNED); + if (sc->sc_flag & UCOM_FLAG_CONSOLE) { + unsigned int temp; + + /* get maximum RX length */ + + temp = (UCOM_CONS_BUFSIZE - 1) - ucom_cons_rx_high + ucom_cons_rx_low; + temp %= UCOM_CONS_BUFSIZE; + + /* limit RX length */ + + if (temp > (UCOM_CONS_BUFSIZE - ucom_cons_rx_high)) + temp = (UCOM_CONS_BUFSIZE - ucom_cons_rx_high); + + if (temp > len) + temp = len; + + /* copy out data */ + + usbd_copy_out(pc, offset, ucom_cons_rx_buf + ucom_cons_rx_high, temp); + + /* update counters */ + + ucom_cons_rx_high += temp; + ucom_cons_rx_high %= UCOM_CONS_BUFSIZE; + + return; + } + if (tty_gone(tp)) return; /* multiport device polling */ @@ -1136,3 +1288,138 @@ ucom_free(void *xsc) cv_signal(&sc->sc_cv); mtx_unlock(sc->sc_mtx); } + +static cn_probe_t ucom_cnprobe; +static cn_init_t ucom_cninit; +static cn_term_t ucom_cnterm; +static cn_getc_t ucom_cngetc; +static cn_putc_t ucom_cnputc; + +CONSOLE_DRIVER(ucom); + +static void +ucom_cnprobe(struct consdev *cp) +{ + cp->cn_pri = CN_NORMAL; +} + +static void +ucom_cninit(struct consdev *cp) +{ +} + +static void +ucom_cnterm(struct consdev *cp) +{ +} + +static int +ucom_cngetc(struct consdev *cd) +{ + struct ucom_softc *sc = ucom_cons_softc; + int c; + + if (sc == NULL) + return (-1); + + mtx_lock(sc->sc_mtx); + + if (ucom_cons_rx_low != ucom_cons_rx_high) { + c = ucom_cons_rx_buf[ucom_cons_rx_low]; + ucom_cons_rx_low ++; + ucom_cons_rx_low %= UCOM_CONS_BUFSIZE; + } else { + c = -1; + } + + /* start USB transfers */ + ucom_outwakeup(sc->sc_tty); + + mtx_unlock(sc->sc_mtx); + + /* poll if necessary */ + if (kdb_active && sc->sc_callback->ucom_poll) + (sc->sc_callback->ucom_poll) (sc); + + return (c); +} + +static void +ucom_cnputc(struct consdev *cd, int c) +{ + struct ucom_softc *sc = ucom_cons_softc; + unsigned int temp; + + if (sc == NULL) + return; + + repeat: + + mtx_lock(sc->sc_mtx); + + /* compute maximum TX length */ + + temp = (UCOM_CONS_BUFSIZE - 1) - ucom_cons_tx_high + ucom_cons_tx_low; + temp %= UCOM_CONS_BUFSIZE; + + if (temp) { + ucom_cons_tx_buf[ucom_cons_tx_high] = c; + ucom_cons_tx_high ++; + ucom_cons_tx_high %= UCOM_CONS_BUFSIZE; + } + + /* start USB transfers */ + ucom_outwakeup(sc->sc_tty); + + mtx_unlock(sc->sc_mtx); + + /* poll if necessary */ + if (kdb_active && sc->sc_callback->ucom_poll) { + (sc->sc_callback->ucom_poll) (sc); + /* simple flow control */ + if (temp == 0) + goto repeat; + } +} + +#if defined(GDB) + +#include + +static gdb_probe_f ucom_gdbprobe; +static gdb_init_f ucom_gdbinit; +static gdb_term_f ucom_gdbterm; +static gdb_getc_f ucom_gdbgetc; +static gdb_putc_f ucom_gdbputc; + +GDB_DBGPORT(sio, ucom_gdbprobe, ucom_gdbinit, ucom_gdbterm, ucom_gdbgetc, ucom_gdbputc); + +static int +ucom_gdbprobe(void) +{ + return ((ucom_cons_softc != NULL) ? 0 : -1); +} + +static void +ucom_gdbinit(void) +{ +} + +static void +ucom_gdbterm(void) +{ +} + +static void +ucom_gdbputc(int c) +{ + ucom_cnputc(NULL, c); +} + +static int +ucom_gdbgetc(void) +{ + return (ucom_cngetc(NULL)); +} + +#endif Modified: stable/8/sys/dev/usb/serial/usb_serial.h ============================================================================== --- stable/8/sys/dev/usb/serial/usb_serial.h Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/usb_serial.h Thu Oct 29 23:23:34 2009 (r198655) @@ -94,6 +94,7 @@ struct ucom_callback { void (*ucom_cfg_set_dtr) (struct ucom_softc *, uint8_t); void (*ucom_cfg_set_rts) (struct ucom_softc *, uint8_t); void (*ucom_cfg_set_break) (struct ucom_softc *, uint8_t); + void (*ucom_cfg_set_ring) (struct ucom_softc *, uint8_t); void (*ucom_cfg_param) (struct ucom_softc *, struct termios *); void (*ucom_cfg_open) (struct ucom_softc *); void (*ucom_cfg_close) (struct ucom_softc *); @@ -105,6 +106,7 @@ struct ucom_callback { 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_poll) (struct ucom_softc *); }; /* Line status register */ @@ -162,13 +164,14 @@ struct ucom_softc { uint32_t sc_unit; uint32_t sc_local_unit; uint16_t sc_portno; - uint8_t sc_flag; + uint16_t sc_flag; #define UCOM_FLAG_RTS_IFLOW 0x01 /* use RTS input flow control */ #define UCOM_FLAG_GONE 0x02 /* the device is gone */ #define UCOM_FLAG_ATTACHED 0x04 /* set if attached */ #define UCOM_FLAG_GP_DATA 0x08 /* set if get and put data is possible */ #define UCOM_FLAG_LL_READY 0x20 /* set if low layer is ready */ #define UCOM_FLAG_HL_READY 0x40 /* set if high layer is ready */ +#define UCOM_FLAG_CONSOLE 0x80 /* set if device is a console */ uint8_t sc_lsr; uint8_t sc_msr; uint8_t sc_mcr; @@ -180,6 +183,7 @@ struct ucom_softc { #define UCOM_LS_DTR 0x01 #define UCOM_LS_RTS 0x02 #define UCOM_LS_BREAK 0x04 +#define UCOM_LS_RING 0x08 }; #define ucom_cfg_do_request(udev,com,req,ptr,flags,timo) \ Modified: stable/8/sys/dev/usb/serial/uslcom.c ============================================================================== --- stable/8/sys/dev/usb/serial/uslcom.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/uslcom.c Thu Oct 29 23:23:34 2009 (r198655) @@ -135,6 +135,7 @@ static void uslcom_start_read(struct uco static void uslcom_stop_read(struct ucom_softc *); static void uslcom_start_write(struct ucom_softc *); static void uslcom_stop_write(struct ucom_softc *); +static void uslcom_poll(struct ucom_softc *ucom); static const struct usb_config uslcom_config[USLCOM_N_TRANSFER] = { @@ -170,6 +171,7 @@ static struct ucom_callback uslcom_callb .ucom_stop_read = &uslcom_stop_read, .ucom_start_write = &uslcom_start_write, .ucom_stop_write = &uslcom_stop_write, + .ucom_poll = &uslcom_poll, }; static const struct usb_device_id uslcom_devs[] = { @@ -562,3 +564,10 @@ uslcom_stop_write(struct ucom_softc *uco usbd_transfer_stop(sc->sc_xfer[USLCOM_BULK_DT_WR]); } + +static void +uslcom_poll(struct ucom_softc *ucom) +{ + struct uslcom_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, USLCOM_N_TRANSFER); +} Modified: stable/8/sys/dev/usb/serial/uvscom.c ============================================================================== --- stable/8/sys/dev/usb/serial/uvscom.c Thu Oct 29 23:22:54 2009 (r198654) +++ stable/8/sys/dev/usb/serial/uvscom.c Thu Oct 29 23:23:34 2009 (r198655) @@ -185,6 +185,7 @@ static void uvscom_cfg_get_status(struct uint8_t *); static void uvscom_cfg_write(struct uvscom_softc *, uint8_t, uint16_t); static uint16_t uvscom_cfg_read_status(struct uvscom_softc *); +static void uvscom_poll(struct ucom_softc *ucom); static const struct usb_config uvscom_config[UVSCOM_N_TRANSFER] = { @@ -230,6 +231,7 @@ static const struct ucom_callback uvscom .ucom_stop_read = &uvscom_stop_read, .ucom_start_write = &uvscom_start_write, .ucom_stop_write = &uvscom_stop_write, + .ucom_poll = &uvscom_poll, }; static const struct usb_device_id uvscom_devs[] = { @@ -734,3 +736,10 @@ uvscom_cfg_read_status(struct uvscom_sof } return (data[0] | (data[1] << 8)); } + +static void +uvscom_poll(struct ucom_softc *ucom) +{ + struct uvscom_softc *sc = ucom->sc_parent; + usbd_transfer_poll(sc->sc_xfer, UVSCOM_N_TRANSFER); +}