Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb Split the umodem driver into two parts: the part...



details:   https://anonhg.NetBSD.org/src/rev/e3a1c222da4a
branches:  trunk
changeset: 481254:e3a1c222da4a
user:      augustss <augustss%NetBSD.org@localhost>
date:      Tue Jan 25 08:12:58 2000 +0000

description:
Split the umodem driver into two parts: the part that emulates a tty over
two bulk pipes, and the setup and status fiddling goo.
This allows the former part to be shared by other drivers that need to
look like a tty.

diffstat:

 sys/dev/usb/files.usb |   14 +-
 sys/dev/usb/ucom.c    |  957 +++++++++++++++++++++++++++++++++++++++++++++++--
 sys/dev/usb/umodem.c  |  839 ++++++++++---------------------------------
 3 files changed, 1113 insertions(+), 697 deletions(-)

diffs (truncated from 2139 to 300 lines):

diff -r 1ced030cbff5 -r e3a1c222da4a sys/dev/usb/files.usb
--- a/sys/dev/usb/files.usb     Tue Jan 25 08:07:14 2000 +0000
+++ b/sys/dev/usb/files.usb     Tue Jan 25 08:12:58 2000 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.usb,v 1.13 2000/01/16 09:40:07 augustss Exp $
+#      $NetBSD: files.usb,v 1.14 2000/01/25 08:12:58 augustss Exp $
 #
 # Config file and device description for machine-independent USB code.
 # Included by ports that need it.  Ports that use it must provide
@@ -24,11 +24,19 @@
 
 attach uhub at uhub with uhub_uhub
 
+# Modem and com serial port "bus"
+define ucombus {[ portno = -1 ]}
+
 # Audio devices
 device uaudio: audio, auconv, mulaw
 attach uaudio at uhub
 file   dev/usb/uaudio.c                uaudio
 
+# Modem and com serial port
+device ucom
+attach ucom at ucombus
+file   dev/usb/ucom.c                  ucom            needs-flag
+
 # Generic devices
 device ugen
 attach ugen at uhub
@@ -56,9 +64,9 @@
 file   dev/usb/umass.c                 umass
 
 # Modems
-device umodem
+device umodem: ucombus
 attach umodem at uhub
-file   dev/usb/umodem.c                umodem          needs-flag
+file   dev/usb/umodem.c                umodem
 
 # Mice
 device ums: wsmousedev
diff -r 1ced030cbff5 -r e3a1c222da4a sys/dev/usb/ucom.c
--- a/sys/dev/usb/ucom.c        Tue Jan 25 08:07:14 2000 +0000
+++ b/sys/dev/usb/ucom.c        Tue Jan 25 08:12:58 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ucom.c,v 1.11 1999/11/12 00:34:57 augustss Exp $       */
+/*     $NetBSD: ucom.c,v 1.12 2000/01/25 08:12:58 augustss Exp $       */
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -40,84 +40,947 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
-#include <sys/malloc.h>
-#if defined(__NetBSD__)
 #include <sys/ioctl.h>
-#include <sys/device.h>
-#elif defined(__FreeBSD__)
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
 #include <sys/conf.h>
-#endif
 #include <sys/tty.h>
 #include <sys/file.h>
 #include <sys/select.h>
 #include <sys/proc.h>
 #include <sys/vnode.h>
+#include <sys/device.h>
 #include <sys/poll.h>
 
 #include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
 
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdi_util.h>
 #include <dev/usb/usbdevs.h>
 #include <dev/usb/usb_quirks.h>
-#include <dev/usb/hid.h>
+
+#include <dev/usb/ucomvar.h>
+
+#ifdef UCOM_DEBUG
+#define DPRINTFN(n, x) if (ucomdebug > (n)) logprintf x
+int ucomdebug = 0;
+#else
+#define DPRINTFN(n, x)
+#endif
+#define DPRINTF(x) DPRINTFN(0, x)
 
-#ifdef USB_DEBUG
-#define DPRINTF(x)     if (ucomdebug) logprintf x
-#define DPRINTFN(n,x)  if (ucomdebug>(n)) logprintf x
-int    ucomdebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
+#define        UCOMUNIT_MASK           0x3ffff
+#define        UCOMDIALOUT_MASK        0x80000
+#define        UCOMCALLUNIT_MASK       0x40000
+
+#define        UCOMUNIT(x)             (minor(x) & UCOMUNIT_MASK)
+#define        UCOMDIALOUT(x)          (minor(x) & UCOMDIALOUT_MASK)
+#define        UCOMCALLUNIT(x)         (minor(x) & UCOMCALLUNIT_MASK)
+
+/* 
+ * These are the maximum number of bytes transferred per frame.
+ * If some really high speed devices should use this driver they
+ * may need to be increased, but this is good enough for modems.
+ */
+#define UCOMIBUFSIZE 64
+#define UCOMOBUFSIZE 256
 
 struct ucom_softc {
-       bdevice sc_dev;                 /* base device */
-       usbd_interface_handle sc_iface; /* interface */
+       USBBASEDEVICE           sc_dev;         /* base device */
+
+       usbd_device_handle      sc_udev;        /* USB device */
+
+       usbd_interface_handle   sc_iface;       /* data interface */
+
+       int                     sc_bulkin_no;   /* bulk in endpoint address */
+       usbd_pipe_handle        sc_bulkin_pipe; /* bulk in pipe */
+       usbd_xfer_handle        sc_ixfer;       /* read request */
+       u_char                  *sc_ibuf;       /* read buffer */
+
+       int                     sc_bulkout_no;  /* bulk out endpoint address */
+       usbd_pipe_handle        sc_bulkout_pipe;/* bulk out pipe */
+       usbd_xfer_handle        sc_oxfer;       /* write request */
+       u_char                  *sc_obuf;       /* write buffer */
+
+       struct ucom_methods     *sc_methods;
+       void                    *sc_parent;
+       int                     sc_portno;
+
+       struct tty              *sc_tty;        /* our tty */
+       u_char                  sc_lsr;
+       u_char                  sc_msr;
+       u_char                  sc_mcr;
+       u_char                  sc_tx_stopped;
+       int                     sc_swflags;
+
+       u_char                  sc_opening;     /* lock during open */
+       u_char                  sc_dying;       /* disconnecting */
 };
 
-void ucom_intr __P((usbd_xfer_handle, usbd_private_handle, usbd_status));
-void ucom_disco __P((void *));
+cdev_decl(ucom);
+
+static void    ucom_cleanup    __P((struct ucom_softc *));
+static void    ucom_hwiflow    __P((struct ucom_softc *));
+static int     ucomparam       __P((struct tty *, struct termios *));
+static void    ucomstart       __P((struct tty *));
+static void    ucom_shutdown   __P((struct ucom_softc *));
+static void    ucom_dtr        __P((struct ucom_softc *, int));
+static void    ucom_rts        __P((struct ucom_softc *, int));
+static void    ucom_break      __P((struct ucom_softc *, int));
+static usbd_status ucomstartread __P((struct ucom_softc *));
+static void    ucomreadcb      __P((usbd_xfer_handle, usbd_private_handle, 
+                                    usbd_status status));
+static void    ucomwritecb     __P((usbd_xfer_handle, usbd_private_handle, 
+                                    usbd_status status));
+static void    tiocm_to_ucom   __P((struct ucom_softc *, int, int));
+static int     ucom_to_tiocm   __P((struct ucom_softc *));
 
 USB_DECLARE_DRIVER(ucom);
 
 USB_MATCH(ucom)
 {
-       USB_MATCH_START(ucom, uaa);
-       usb_interface_descriptor_t *id;
-       
-       if (!uaa->iface)
-               return (UMATCH_NONE);
-       id = usbd_get_interface_descriptor(uaa->iface);
-       if (id &&
-           id->bInterfaceClass != UCLASS_CDC ||
-           id->bInterfaceSubClass != USUBCLASS_ABSTRACT_CONTROL_MODEL)
-               return (UMATCH_NONE);
-       return (UMATCH_IFACECLASS_IFACESUBCLASS);
+       return (1);
 }
 
 USB_ATTACH(ucom)
 {
-       USB_ATTACH_START(ucom, sc, uaa);
-       usbd_interface_handle iface = uaa->iface;
-       usb_interface_descriptor_t *id;
-       char devinfo[1024];
-       
-       sc->sc_iface = iface;
-       id = usbd_get_interface_descriptor(iface);
-       usbd_devinfo(uaa->device, 0, devinfo);
-       USB_ATTACH_SETUP;
-       printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
-              devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
+       struct ucom_softc *sc = (struct ucom_softc *)self;
+       struct ucom_attach_args *uca = aux;
+       struct tty *tp;
+
+       if (uca->portno != UCOM_UNK_PORTNO)
+               printf(": portno %d", uca->portno);
+       printf("\n");
+
+       sc->sc_udev = uca->device;
+       sc->sc_iface = uca->iface;
+       sc->sc_bulkout_no = uca->bulkout;
+       sc->sc_bulkin_no = uca->bulkin;
+       sc->sc_methods = uca->methods;
+       sc->sc_parent = uca->arg;
+       sc->sc_portno = uca->portno;
+
+       tp = ttymalloc();
+       tp->t_oproc = ucomstart;
+       tp->t_param = ucomparam;
+       sc->sc_tty = tp;
+
+       DPRINTF(("ucom_attach: tty_attach %p\n", tp));
+       tty_attach(tp);
 
        USB_ATTACH_SUCCESS_RETURN;
 }
 
-#if defined(__FreeBSD__)
-DRIVER_MODULE(ucom, usb, ucom_driver, ucom_devclass, usbd_driver_load, 0);
+USB_DETACH(ucom)
+{
+       struct ucom_softc *sc = (struct ucom_softc *)self;
+       int maj, mn;
+
+       DPRINTF(("ucom_detach: sc=%p flags=%d tp=%p\n", 
+                sc, flags, sc->sc_tty));
+
+       sc->sc_dying = 1;
+
+#ifdef DIAGNOSTIC
+       if (sc->sc_tty == NULL) {
+               DPRINTF(("ucom_detach: no tty\n"));
+               return (0);
+       }
+#endif
+
+       /* XXX  Use reference count? */
+
+       /* locate the major number */
+       for (maj = 0; maj < nchrdev; maj++)
+               if (cdevsw[maj].d_open == ucomopen)
+                       break;
+
+       /* Nuke the vnodes for any open instances. */
+       mn = self->dv_unit;
+       vdevgone(maj, mn, mn, VCHR);
+       vdevgone(maj, mn, mn | UCOMDIALOUT_MASK, VCHR);
+       vdevgone(maj, mn, mn | UCOMCALLUNIT_MASK, VCHR);
+
+       /* Detach and free the tty. */
+       tty_detach(sc->sc_tty);
+       ttyfree(sc->sc_tty);
+       sc->sc_tty = 0;
+
+       return (0);
+}
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+int
+ucom_activate(self, act)
+       device_ptr_t self;
+       enum devact act;
+{
+       struct ucom_softc *sc = (struct ucom_softc *)self;
+
+       switch (act) {
+       case DVACT_ACTIVATE:
+               return (EOPNOTSUPP);
+               break;
+
+       case DVACT_DEACTIVATE:
+               sc->sc_dying = 1;
+               break;
+       }
+       return (0);
+}
 #endif
 
+void
+ucom_shutdown(sc)
+       struct ucom_softc *sc;
+{
+       struct tty *tp = sc->sc_tty;
+
+       DPRINTF(("ucom_shutdown\n"));
+       /*
+        * Hang up if necessary.  Wait a bit, so the other side has time to
+        * notice even if we immediately open the port again.
+        */
+       if (ISSET(tp->t_cflag, HUPCL)) {



Home | Main Index | Thread Index | Old Index