svn commit: r198655 - in stable/8/sys: . amd64/include/xen cddl/contrib/opensolaris contrib/dev/acpica contrib/pf dev/usb/serial dev/xen/xenpci

Andrew Thompson thompsa at FreeBSD.org
Thu Oct 29 23:23:34 UTC 2009


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 <sys/callout.h>
 #include <sys/malloc.h>
 #include <sys/priv.h>
+#include <sys/cons.h>
+#include <sys/kdb.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
@@ -98,14 +100,40 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/usb/serial/usb_serial.h>
 
+#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 <gdb/gdb.h>
+
+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);
+}


More information about the svn-src-all mailing list