Add uticom(4) driver for Texas Instruments TUSB3410 USB to serial chips
authorHasso Tepper <hasso@dragonflybsd.org>
Wed, 7 Nov 2007 08:31:08 +0000 (08:31 +0000)
committerHasso Tepper <hasso@dragonflybsd.org>
Wed, 7 Nov 2007 08:31:08 +0000 (08:31 +0000)
written by Dmitry Komissaroff <dxi@mail.ru> and me.

share/man/man4/Makefile
share/man/man4/ucom.4
share/man/man4/uticom.4 [new file with mode: 0644]
sys/dev/usbmisc/Makefile
sys/dev/usbmisc/uticom/Makefile [new file with mode: 0644]
sys/dev/usbmisc/uticom/uticom.c [new file with mode: 0644]
sys/dev/usbmisc/uticom/uticom_fw3410.h [new file with mode: 0644]

index 5240e5d..aef7404 100644 (file)
@@ -1,6 +1,6 @@
 #      @(#)Makefile    8.1 (Berkeley) 6/18/93
 # $FreeBSD: src/share/man/man4/Makefile,v 1.83.2.66 2003/06/04 17:10:30 sam Exp $
-# $DragonFly: src/share/man/man4/Makefile,v 1.70 2007/10/12 14:12:42 sephe Exp $
+# $DragonFly: src/share/man/man4/Makefile,v 1.71 2007/11/07 08:31:08 hasso Exp $
 
 MAN=   aac.4 \
        acpi.4 \
@@ -287,6 +287,7 @@ MAN=        aac.4 \
        usb.4 \
        uscanner.4 \
        uslcom.4 \
+       uticom.4 \
        uvisor.4 \
        uvscom.4 \
        vga.4 \
index 780aca8..12362e7 100644 (file)
@@ -35,7 +35,7 @@
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" $FreeBSD: src/share/man/man4/ucom.4,v 1.2.2.2 2002/08/12 20:32:05 joe Exp $
-.\" $DragonFly: src/share/man/man4/ucom.4,v 1.7 2007/08/16 20:38:33 hasso Exp $
+.\" $DragonFly: src/share/man/man4/ucom.4,v 1.8 2007/11/07 08:31:08 hasso Exp $
 .\"
 .Dd November 25, 1999
 .Dt UCOM 4
@@ -86,6 +86,7 @@ can be used to access the device.
 .Xr uplcom 4 ,
 .Xr usb 4 ,
 .Xr uslcom 4 ,
+.Xr uticom 4 ,
 .Xr uvisor 4 ,
 .Xr uvscom 4
 .Sh HISTORY
diff --git a/share/man/man4/uticom.4 b/share/man/man4/uticom.4
new file mode 100644 (file)
index 0000000..963ea30
--- /dev/null
@@ -0,0 +1,90 @@
+.\" Copyright (c) 2007
+.\"     The DragonFly Project.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in
+.\"    the documentation and/or other materials provided with the
+.\"    distribution.
+.\" 3. Neither the name of The DragonFly Project nor the names of its
+.\"    contributors may be used to endorse or promote products derived
+.\"    from this software without specific, prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $DragonFly: src/share/man/man4/uticom.4,v 1.1 2007/11/07 08:31:08 hasso Exp $
+.\"
+.Dd November 11, 2007
+.Dt UTICOM 4
+.Os
+.Sh NAME
+.Nm uticom
+.Nd Texas Instruments TUSB3410 RS232 to USB converter
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device uticom"
+.Cd "device ucom"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+uticom_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver supports virtual serial port functionality on devices based on Texas
+Instruments TUSB3410 serial to USB converter chip. Note that the driver
+doesn't support devices which have internal EEPROM with firmware.
+.Pp
+The device is accessed through the
+.Xr ucom 4
+driver which makes it behave like a
+.Xr tty 4 .
+.Sh SYSCTL
+.Bl -tag -width indent
+.It Va hw.usb.uticom.stickdsr
+If set to non-zero, DSR (Data Set Ready) signal from DCE is ignored and the
+TIOCM_DSR state flag is set unconditionally.  It can be used if DSR signal
+from DCE is unreliable.  Default is 0.
+.El
+.Sh SEE ALSO
+.Xr tty 4 ,
+.Xr ucom 4 ,
+.Xr usb 4
+.Sh HISTORY
+The
+.Nm
+device driver first appeared in
+.Dx 1.11 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Dmitry Komissaroff
+.Aq dxi@mail.ru
+and
+.An Hasso Tepper
+.Aq hasso@estpak.ee .
index 669efd3..5c0f41f 100644 (file)
@@ -1,7 +1,7 @@
-# $DragonFly: src/sys/dev/usbmisc/Makefile,v 1.5 2007/08/16 20:38:33 hasso Exp $
+# $DragonFly: src/sys/dev/usbmisc/Makefile,v 1.6 2007/11/07 08:31:08 hasso Exp $
 #
 
 SUBDIR= uark ubsa ucom ufm uftdi ugen uhid ukbd ulpt umass umodem ums umsm \
-       uplcom uscanner uslcom uvisor uvscom umct
+       uplcom uscanner uslcom uticom uvisor uvscom umct
 
 .include <bsd.subdir.mk>
diff --git a/sys/dev/usbmisc/uticom/Makefile b/sys/dev/usbmisc/uticom/Makefile
new file mode 100644 (file)
index 0000000..0534650
--- /dev/null
@@ -0,0 +1,12 @@
+# $DragonFly: src/sys/dev/usbmisc/uticom/Makefile,v 1.1 2007/11/07 08:31:08 hasso Exp $
+
+.PATH: ${.CURDIR}/../ucom
+
+KMOD=  uticom
+SRCS=  uticom.c uticom_fw3410.h
+SRCS+= ucomvar.h opt_usb.h bus_if.h device_if.h
+NOMAN=
+KMODDEPS= ucom
+
+.include <bsd.kmod.mk>
+
diff --git a/sys/dev/usbmisc/uticom/uticom.c b/sys/dev/usbmisc/uticom/uticom.c
new file mode 100644 (file)
index 0000000..74dd632
--- /dev/null
@@ -0,0 +1,982 @@
+/*
+ * Copyright (c) 2006-2007 Dmitry Komissaroff <dxi@mail.ru>.
+ * Copyright (c) 2007 Hasso Tepper <hasso@estpak.ee>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $DragonFly: src/sys/dev/usbmisc/uticom/uticom.c,v 1.1 2007/11/07 08:31:08 hasso Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <sys/ioccom.h>
+#include <sys/fcntl.h>
+#include <sys/conf.h>
+#include <sys/tty.h>
+#include <sys/file.h>
+#include <sys/select.h>
+#include <sys/proc.h>
+#include <sys/poll.h>
+#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
+
+#include <bus/usb/usb.h>
+#include <bus/usb/usbcdc.h>
+#include <bus/usb/usbdi.h>
+#include <bus/usb/usbdi_util.h>
+#include <bus/usb/usbdivar.h>
+#include <bus/usb/usb_quirks.h>
+
+#include "../ucom/ucomvar.h"
+
+#include "uticom_fw3410.h"
+
+SYSCTL_NODE(_hw_usb, OID_AUTO, uticom, CTLFLAG_RW, 0, "USB uticom");
+
+#ifdef USB_DEBUG
+static int     uticomdebug = 0;
+SYSCTL_INT(_hw_usb_uticom, OID_AUTO, debug, CTLFLAG_RW, &uticomdebug, 0,
+          "uticom debug level");
+
+#define DPRINTFN(n, x) do { if (uticomdebug > (n)) kprintf x; } while (0)
+#else
+#define DPRINTFN(n, x)
+#endif
+
+#define DPRINTF(x) DPRINTFN(0, x)
+
+#define        UTICOM_CONFIG_INDEX     1
+#define        UTICOM_ACTIVE_INDEX     2
+
+#define        UTICOM_IFACE_INDEX      0
+
+/*
+ * These are the maximum number of bytes transferred per frame.
+ * The output buffer size cannot be increased due to the size encoding.
+ */
+#define UTICOM_IBUFSZ          64
+#define UTICOM_OBUFSZ          64
+
+#define UTICOM_FW_BUFSZ                16284
+
+#define UTICOM_INTR_INTERVAL   100     /* ms */
+
+#define UTICOM_RQ_LINE         0
+/* Used to sync data0/1-toggle on reopen bulk pipe. */
+#define UTICOM_RQ_SOF          1
+#define UTICOM_RQ_SON          2
+
+#define UTICOM_RQ_BAUD         3
+#define UTICOM_RQ_LCR          4
+#define UTICOM_RQ_FCR          5
+#define UTICOM_RQ_RTS          6
+#define UTICOM_RQ_DTR          7
+#define UTICOM_RQ_BREAK                8
+#define UTICOM_RQ_CRTSCTS      9
+
+#define UTICOM_BRATE_REF       923077
+
+#define UTICOM_SET_DATA_BITS(x)        (x - 5)
+
+#define UTICOM_STOP_BITS_1     0x00
+#define UTICOM_STOP_BITS_2     0x40
+
+#define UTICOM_PARITY_NONE     0x00
+#define UTICOM_PARITY_ODD      0x08
+#define UTICOM_PARITY_EVEN     0x18
+
+#define UTICOM_LCR_OVR         0x1
+#define UTICOM_LCR_PTE         0x2
+#define UTICOM_LCR_FRE         0x4
+#define UTICOM_LCR_BRK         0x8
+
+#define UTICOM_MCR_CTS         0x1
+#define UTICOM_MCR_DSR         0x2
+#define UTICOM_MCR_CD          0x4
+#define UTICOM_MCR_RI          0x8
+
+/* Structures */
+struct uticom_fw_header {
+       uint16_t      length;
+       uint8_t       checkSum;
+} __attribute__((packed));
+
+struct uticom_buf {
+       unsigned int            buf_size;
+       char                    *buf_buf;
+       char                    *buf_get;
+       char                    *buf_put;
+};
+
+struct uticom_softc {
+       struct ucom_softc       sc_ucom;
+
+       int                     sc_iface_number; /* interface number */
+
+       usbd_interface_handle   sc_intr_iface;  /* interrupt interface */
+       int                     sc_intr_number; /* interrupt number */
+       usbd_pipe_handle        sc_intr_pipe;   /* interrupt pipe */
+       u_char                  *sc_intr_buf;   /* interrupt buffer */
+       int                     sc_isize;
+
+       u_char                  sc_dtr;         /* current DTR state */
+       u_char                  sc_rts;         /* current RTS state */
+       u_char                  sc_status;
+
+       u_char                  sc_lsr;         /* Local status register */
+       u_char                  sc_msr;         /* uticom status register */
+};
+
+static usbd_status uticom_reset(struct uticom_softc *);
+static usbd_status uticom_set_crtscts(struct uticom_softc *);
+static void uticom_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
+
+static void uticom_set(void *, int, int, int);
+static void uticom_dtr(struct uticom_softc *, int);
+static void uticom_rts(struct uticom_softc *, int);
+static void uticom_break(struct uticom_softc *, int);
+static void uticom_get_status(void *, int, u_char *, u_char *);
+#if 0 /* TODO */
+static int  uticom_ioctl(void *, int, u_long, caddr_t, int, usb_proc_ptr);
+#endif
+static int  uticom_param(void *, int, struct termios *);
+static int  uticom_open(void *, int);
+static void uticom_close(void *, int);
+
+static int uticom_download_fw(struct uticom_softc *sc, unsigned int pipeno,
+                             usbd_device_handle dev, unsigned char *firmware,
+                             unsigned int firmware_size);
+
+struct ucom_callback uticom_callback = {
+       uticom_get_status,
+       uticom_set,
+       uticom_param,
+       NULL, /* uticom_ioctl, TODO */
+       uticom_open,
+       uticom_close,
+       NULL,
+       NULL
+};
+
+static const struct usb_devno uticom_devs [] = {
+       { USB_DEVICE(0x0451, 0x3410) }  /* TI TUSB3410 chip */
+};
+
+static device_probe_t uticom_match;
+static device_attach_t uticom_attach;
+static device_detach_t uticom_detach;
+
+static device_method_t uticom_methods[] = {
+       DEVMETHOD(device_probe, uticom_match),
+       DEVMETHOD(device_attach, uticom_attach),
+       DEVMETHOD(device_detach, uticom_detach),
+       { 0, 0 }
+};
+
+static driver_t uticom_driver = {
+       "ucom",
+       uticom_methods,
+       sizeof (struct uticom_softc)
+};
+
+DRIVER_MODULE(uticom, uhub, uticom_driver, ucom_devclass, usbd_driver_load, 0);
+MODULE_DEPEND(uticom, usb, 1, 1, 1);
+MODULE_DEPEND(uticom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
+MODULE_VERSION(uticom, 1);
+
+/* Sticky DSR level sysctl handling. */
+static int uticomstickdsr = 0;
+static int
+sysctl_hw_usb_uticom_stickdsr(SYSCTL_HANDLER_ARGS)
+{
+       int err, val;
+
+       val = uticomstickdsr;
+       err = sysctl_handle_int(oidp, &val, sizeof(val), req);
+       if (err != 0 || req->newptr == NULL)
+               return (err);
+       if (val == 0 || val == 1)
+               uticomstickdsr = val;
+       else
+               err = EINVAL;
+
+       return (err);
+}
+SYSCTL_PROC(_hw_usb_uticom, OID_AUTO, stickdsr, CTLTYPE_INT | CTLFLAG_RW,
+           0, sizeof(int), sysctl_hw_usb_uticom_stickdsr,
+           "I", "uticom sticky dsr level");
+
+static int
+uticom_match(device_t self)
+{
+       struct usb_attach_arg *uaa = device_get_ivars(self);
+
+       if (uaa->iface != NULL)
+               return (UMATCH_NONE);
+
+       return (usb_lookup(uticom_devs, uaa->vendor, uaa->product) != NULL ?
+               UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
+}
+
+static int
+uticom_attach(device_t self)
+{
+       struct uticom_softc *sc = device_get_softc(self);
+       struct usb_attach_arg *uaa = device_get_ivars(self);
+
+       usbd_device_handle dev = uaa->device;
+       struct ucom_softc *ucom;
+       usb_config_descriptor_t *cdesc;
+       usb_interface_descriptor_t *id;
+       usb_endpoint_descriptor_t *ed;
+       usbd_status err;
+       int status, i;
+       usb_device_descriptor_t *dd;
+
+       ucom = &sc->sc_ucom;
+       bzero(sc, sizeof (struct uticom_softc));
+       ucom->sc_dev = self;
+       ucom->sc_udev = dev;
+       ucom->sc_iface = uaa->iface;
+
+       /* Initialize endpoints. */
+       ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
+       sc->sc_intr_number = -1;
+       sc->sc_intr_pipe = NULL;
+
+       dd = usbd_get_device_descriptor(dev);
+       DPRINTF(("%s: uticom_attach: num of configurations %d\n",
+                device_get_nameunit(self), dd->bNumConfigurations));
+
+       /* The device without firmware has single configuration with single
+        * bulk out interface. */
+       if (dd->bNumConfigurations > 1)
+               goto fwload_done;
+               
+       /* Loading firmware. */
+       DPRINTF(("%s: uticom_attach: starting loading firmware\n",
+                device_get_nameunit(self)));
+
+       err = usbd_set_config_index(dev, UTICOM_CONFIG_INDEX, 1);
+       if (err) {
+               device_printf(self, "failed to set configuration: %s\n",
+                             usbd_errstr(err));
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+       /* Get the config descriptor. */
+       cdesc = usbd_get_config_descriptor(ucom->sc_udev);
+
+       if (cdesc == NULL) {
+               device_printf(self, "failed to get configuration descriptor\n");
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+       err = usbd_device2interface_handle(dev, UTICOM_IFACE_INDEX,
+                                          &ucom->sc_iface);
+       if (err) {
+               device_printf(self, "failed to get interface: %s\n",
+                             usbd_errstr(err));
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+       /* Find the bulk out interface used to upload firmware. */
+       id = usbd_get_interface_descriptor(ucom->sc_iface);
+       sc->sc_iface_number = id->bInterfaceNumber;
+
+       for (i = 0; i < id->bNumEndpoints; i++) {
+               ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
+               if (ed == NULL) {
+                       device_printf(self,
+                                     "no endpoint descriptor for %d\n", i);
+                       ucom->sc_dying = 1;
+                       return ENXIO;
+               }
+
+               if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
+                   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
+                       ucom->sc_bulkout_no = ed->bEndpointAddress;
+                       DPRINTF(("%s: uticom_attach: data bulk out num: %d\n",
+                                device_get_nameunit(self),
+                                ed->bEndpointAddress));
+               }
+
+               if (ucom->sc_bulkout_no == -1) {
+                       device_printf(self, "could not find data bulk out\n");
+                       ucom->sc_dying = 1;
+                       return ENXIO;
+               }
+       }
+
+       status = uticom_download_fw(sc, ucom->sc_bulkout_no, dev,
+                                   uticom_fw_3410, sizeof(uticom_fw_3410));
+
+       if (status) {
+               device_printf(self, "firmware download failed\n");
+               ucom->sc_dying = 1;
+               return ENXIO;
+       } else {
+               device_printf(self, "firmware download succeeded\n");
+       }
+               
+       status = usbd_reload_device_desc(dev);
+       if (status) {
+               device_printf(self, "error reloading device descriptor\n");
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+fwload_done:
+       dd = usbd_get_device_descriptor(dev);
+       DPRINTF(("%s: uticom_attach: num of configurations %d\n",
+                device_get_nameunit(self), dd->bNumConfigurations));
+
+       err = usbd_set_config_index(dev, UTICOM_ACTIVE_INDEX, 1);
+       if (err) {
+               device_printf(self, "failed to set configuration: %s\n",
+                             usbd_errstr(err));
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+       /* Get the config descriptor. */
+       cdesc = usbd_get_config_descriptor(ucom->sc_udev);
+       if (cdesc == NULL) {
+               device_printf(self, "failed to get configuration descriptor\n");
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+       /* Get the interface (XXX: multiport chips are not supported yet). */
+       err = usbd_device2interface_handle(dev, UTICOM_IFACE_INDEX,
+                                          &ucom->sc_iface);
+       if (err) {
+               device_printf(self, "failed to get interface: %s\n",
+                             usbd_errstr(err));
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+       /* Find the interrupt endpoints. */
+       id = usbd_get_interface_descriptor(ucom->sc_iface);
+       sc->sc_iface_number = id->bInterfaceNumber;
+
+       for (i = 0; i < id->bNumEndpoints; i++) {
+               ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
+               if (ed == NULL) {
+                       device_printf(self,
+                                     "no endpoint descriptor for %d\n", i);
+                       ucom->sc_dying = 1;
+                       return ENXIO;
+               }
+
+               if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
+                   UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
+                       sc->sc_intr_number = ed->bEndpointAddress;
+                       sc->sc_isize = UGETW(ed->wMaxPacketSize);
+               }
+       }
+
+       if (sc->sc_intr_number == -1) {
+               device_printf(self, "could not find interrupt in\n");
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+       /* Keep interface for interrupt. */
+       sc->sc_intr_iface = ucom->sc_iface;
+
+       /* Find the bulk{in,out} endpoints. */
+       id = usbd_get_interface_descriptor(ucom->sc_iface);
+       sc->sc_iface_number = id->bInterfaceNumber;
+
+       for (i = 0; i < id->bNumEndpoints; i++) {
+               ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
+               if (ed == NULL) {
+                       device_printf(self,
+                                     "no endpoint descriptor for %d\n", i);
+                       ucom->sc_dying = 1;
+                       return ENXIO;
+               }
+
+               if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
+                   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
+                       ucom->sc_bulkin_no = ed->bEndpointAddress;
+               } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
+                   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
+                       ucom->sc_bulkout_no = ed->bEndpointAddress;
+               }
+       }
+
+       if (ucom->sc_bulkin_no == -1) {
+               device_printf(self, "could not find data bulk in\n");
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+       if (ucom->sc_bulkout_no == -1) {
+               device_printf(self, "could not find data bulk out\n");
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+       sc->sc_dtr = sc->sc_rts = -1;
+       ucom->sc_parent = sc;
+       ucom->sc_portno = UCOM_UNK_PORTNO;
+       ucom->sc_ibufsize = UTICOM_IBUFSZ;
+       ucom->sc_obufsize = UTICOM_OBUFSZ;
+       ucom->sc_ibufsizepad = UTICOM_IBUFSZ;
+       ucom->sc_opkthdrlen = 0;
+       ucom->sc_callback = &uticom_callback;
+
+       err = uticom_reset(sc);
+       if (err) {
+               device_printf(self, "reset failed: %s\n", usbd_errstr(err));
+               ucom->sc_dying = 1;
+               return ENXIO;
+       }
+
+       DPRINTF(("%s: uticom_attach: in = 0x%x, out = 0x%x, intr = 0x%x\n",
+                device_get_nameunit(self), ucom->sc_bulkin_no,
+                ucom->sc_bulkout_no, sc->sc_intr_number));
+
+       ucom_attach(&sc->sc_ucom);
+       return 0;
+}
+
+static int
+uticom_detach(device_t self)
+{
+       struct uticom_softc *sc = device_get_softc(self);
+
+       DPRINTF(("%s: uticom_detach: sc = %p\n",
+                device_get_nameunit(self), sc));
+
+       if (sc->sc_intr_pipe != NULL) {
+               usbd_abort_pipe(sc->sc_intr_pipe);
+               usbd_close_pipe(sc->sc_intr_pipe);
+               kfree(sc->sc_intr_buf, M_USBDEV);
+               sc->sc_intr_pipe = NULL;
+       }
+
+       sc->sc_ucom.sc_dying = 1;
+       return (ucom_detach(&sc->sc_ucom));
+}
+
+static usbd_status
+uticom_reset(struct uticom_softc *sc)
+{
+       usb_device_request_t req;
+       usbd_status err;
+       device_t dev = sc->sc_ucom.sc_dev;
+
+       req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+       req.bRequest = UTICOM_RQ_SON;
+       USETW(req.wValue, 0);
+       USETW(req.wIndex, 0);
+       USETW(req.wLength, 0);
+
+       err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
+       if (err){
+               device_printf(dev, "uticom_reset: %s\n", usbd_errstr(err));
+               return (EIO);
+       }
+
+       DPRINTF(("%s: uticom_reset: done\n", device_get_nameunit(dev)));
+       return (0);
+}
+
+static void
+uticom_set(void *addr, int portno, int reg, int onoff)
+{
+       struct uticom_softc *sc = addr;
+
+       switch (reg) {
+       case UCOM_SET_DTR:
+               uticom_dtr(sc, onoff);
+               break;
+       case UCOM_SET_RTS:
+               uticom_rts(sc, onoff);
+               break;
+       case UCOM_SET_BREAK:
+               uticom_break(sc, onoff);
+               break;
+       default:
+               break;
+       }
+}
+
+static void
+uticom_dtr(struct uticom_softc *sc, int onoff)
+{
+       usb_device_request_t req;
+       usbd_status err;
+       device_t dev = sc->sc_ucom.sc_dev;
+
+       DPRINTF(("%s: uticom_dtr: onoff = %d\n", device_get_nameunit(dev),
+                onoff));
+
+       if (sc->sc_dtr == onoff)
+               return;
+       sc->sc_dtr = onoff;
+
+       req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+       req.bRequest = UTICOM_RQ_DTR;
+       USETW(req.wValue, sc->sc_dtr ? UCDC_LINE_DTR : 0);
+       USETW(req.wIndex, 0);
+       USETW(req.wLength, 0);
+
+       err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
+       if (err)
+               device_printf(dev, "uticom_dtr: %s\n", usbd_errstr(err));
+}
+
+static void
+uticom_rts(struct uticom_softc *sc, int onoff)
+{
+       usb_device_request_t req;
+       usbd_status err;
+       device_t dev = sc->sc_ucom.sc_dev;
+
+       DPRINTF(("%s: uticom_rts: onoff = %d\n", device_get_nameunit(dev),
+                onoff));
+
+       if (sc->sc_rts == onoff) 
+               return;
+       sc->sc_rts = onoff;
+       req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+       req.bRequest = UTICOM_RQ_RTS;
+       USETW(req.wValue, sc->sc_rts ? UCDC_LINE_RTS : 0);
+       USETW(req.wIndex, 0);
+       USETW(req.wLength, 0);
+
+       err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
+       if (err)
+               device_printf(dev, "uticom_rts: %s\n", usbd_errstr(err));
+}
+
+static void
+uticom_break(struct uticom_softc *sc, int onoff)
+{
+       usb_device_request_t req;
+       usbd_status err;
+       device_t dev = sc->sc_ucom.sc_dev;
+
+       DPRINTF(("%s: uticom_break: onoff = %d\n", device_get_nameunit(dev),
+                onoff));
+
+       req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+       req.bRequest = UTICOM_RQ_BREAK;
+       USETW(req.wValue, onoff ? 1 : 0);
+       USETW(req.wIndex, 0);
+       USETW(req.wLength, 0);
+
+       err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
+       if (err)
+               device_printf(dev, "uticom_break: %s\n", usbd_errstr(err));
+}
+
+static usbd_status
+uticom_set_crtscts(struct uticom_softc *sc)
+{
+       usb_device_request_t req;
+       usbd_status err;
+       device_t dev = sc->sc_ucom.sc_dev;
+
+       DPRINTF(("%s: uticom_set_crtscts: on\n", device_get_nameunit(dev)));
+
+       req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+       req.bRequest = UTICOM_RQ_CRTSCTS;
+       USETW(req.wValue, 1);
+       USETW(req.wIndex, 0);
+       USETW(req.wLength, 0);
+
+       err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
+       if (err) {
+               device_printf(dev, "uticom_set_crtscts: %s\n",
+                             usbd_errstr(err));
+               return (err);
+       }
+
+       return (USBD_NORMAL_COMPLETION);
+}
+
+static int
+uticom_param(void *vsc, int portno, struct termios *t)
+{
+       struct uticom_softc *sc = (struct uticom_softc *)vsc;
+       device_t dev = sc->sc_ucom.sc_dev;
+       usb_device_request_t req;
+       usbd_status err;
+       uint8_t data;
+
+       DPRINTF(("%s: uticom_param\n", device_get_nameunit(dev)));
+
+       switch (t->c_ospeed) {
+       case 1200:
+       case 2400:
+       case 4800:
+       case 7200:
+       case 9600:
+       case 14400:
+       case 19200:
+       case 38400:
+       case 57600:
+       case 115200:
+       case 230400:
+       case 460800:
+       case 921600:
+               req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+               req.bRequest = UTICOM_RQ_BAUD;
+               USETW(req.wValue, (UTICOM_BRATE_REF / t->c_ospeed));
+               USETW(req.wIndex, 0);
+               USETW(req.wLength, 0);
+
+               err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
+               if (err) {
+                       device_printf(dev, "uticom_param: %s\n",
+                                     usbd_errstr(err));
+                       return (EIO);
+               }
+               break;
+       default:
+               device_printf(dev, "uticom_param: unsupported baud rate %d\n",
+                             t->c_ospeed);
+               return (EINVAL);
+       }
+
+       switch (ISSET(t->c_cflag, CSIZE)) {
+       case CS5:
+               data = UTICOM_SET_DATA_BITS(5);
+               break;
+       case CS6:
+               data = UTICOM_SET_DATA_BITS(6);
+               break;
+       case CS7:
+               data = UTICOM_SET_DATA_BITS(7);
+               break;
+       case CS8:
+               data = UTICOM_SET_DATA_BITS(8);
+               break;
+       default:
+               return (EIO);
+       }
+
+       if (ISSET(t->c_cflag, CSTOPB))
+               data |= UTICOM_STOP_BITS_2;
+       else
+               data |= UTICOM_STOP_BITS_1;
+
+       if (ISSET(t->c_cflag, PARENB)) {
+               if (ISSET(t->c_cflag, PARODD))
+                       data |= UTICOM_PARITY_ODD;
+               else
+                       data |= UTICOM_PARITY_EVEN;
+       } else
+               data |= UTICOM_PARITY_NONE;
+
+       req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+       req.bRequest = UTICOM_RQ_LCR;
+       USETW(req.wIndex, 0);
+       USETW(req.wLength, 0);
+       USETW(req.wValue, data);
+
+       err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
+       if (err) {
+               device_printf(dev, "uticom_param: %s\n", usbd_errstr(err));
+               return (err);
+       }
+
+       if (ISSET(t->c_cflag, CRTSCTS)) {
+               err = uticom_set_crtscts(sc);
+               if (err)
+                       return (EIO);
+       } 
+
+       return (0);
+}
+
+static int
+uticom_open(void *addr, int portno)
+{
+       struct uticom_softc *sc = addr;
+       device_t dev = sc->sc_ucom.sc_dev;
+       usbd_status err;
+
+       if (sc->sc_ucom.sc_dying)
+               return (ENXIO);
+
+       DPRINTF(("%s: uticom_open\n", device_get_nameunit(dev)));
+
+       sc->sc_status = 0; /* clear status bit */
+
+       if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
+               sc->sc_intr_buf = kmalloc(sc->sc_isize, M_USBDEV, M_WAITOK);
+               err = usbd_open_pipe_intr(sc->sc_intr_iface, sc->sc_intr_number,
+                                         USBD_SHORT_XFER_OK, &sc->sc_intr_pipe,
+                                         sc, sc->sc_intr_buf, sc->sc_isize,
+                                         uticom_intr, UTICOM_INTR_INTERVAL);
+               if (err) {
+                       device_printf(dev, "cannot open interrupt pipe "
+                                     "(addr %d)\n", sc->sc_intr_number);
+                       return (EIO);
+               }
+       }
+
+       DPRINTF(("%s: uticom_open: port opened\n", device_get_nameunit(dev)));
+       return (0);
+}
+
+static void
+uticom_close(void *addr, int portno)
+{
+       struct uticom_softc *sc = addr;
+       device_t dev = sc->sc_ucom.sc_dev;
+       usb_device_request_t req;
+       usbd_status err;
+
+       if (sc->sc_ucom.sc_dying)
+               return;
+
+       req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+       req.bRequest = UTICOM_RQ_SON;
+       USETW(req.wValue, 0);
+       USETW(req.wIndex, 0);
+       USETW(req.wLength, 0);
+
+       /* Try to reset UART part of chip. */
+       err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
+       if (err) {
+               device_printf(dev, "uticom_close: %s\n", usbd_errstr(err));
+               return;
+       }
+
+       DPRINTF(("%s: uticom_close: close\n",
+                device_get_nameunit(sc->sc_ucom.sc_dev)));
+
+       if (sc->sc_intr_pipe != NULL) {
+               err = usbd_abort_pipe(sc->sc_intr_pipe);
+               if (err)
+                       device_printf(dev, "abort interrupt pipe failed: %s\n",
+                                     usbd_errstr(err));
+               err = usbd_close_pipe(sc->sc_intr_pipe);
+               if (err)
+                       device_printf(dev, "close interrupt pipe failed: %s\n",
+                                     usbd_errstr(err));
+               kfree(sc->sc_intr_buf, M_USBDEV);
+               sc->sc_intr_pipe = NULL;
+       }
+}
+
+static void
+uticom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
+{
+       struct uticom_softc *sc = priv;
+       u_char *buf = sc->sc_intr_buf;
+
+       if (sc->sc_ucom.sc_dying)
+               return;
+
+       if (status != USBD_NORMAL_COMPLETION) {
+               if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
+                       DPRINTF(("%s: uticom_intr: int status: %s\n",
+                                device_get_nameunit(sc->sc_ucom.sc_dev),
+                                usbd_errstr(status)));
+                       return;
+               }
+
+               DPRINTF(("%s: uticom_intr: abnormal status: %s\n",
+                       device_get_nameunit(sc->sc_ucom.sc_dev),
+                       usbd_errstr(status)));
+               usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
+               return;
+       }
+
+       if (!xfer->actlen)
+               return;
+
+       DPRINTF(("%s: xfer_length = %d\n",
+                device_get_nameunit(sc->sc_ucom.sc_dev), xfer->actlen));
+
+       sc->sc_lsr = sc->sc_msr = 0;
+
+       if (buf[0] == 0) {
+               /* msr registers */
+               if (buf[1] & UTICOM_MCR_CTS)
+                       sc->sc_msr |= UMSR_CTS;
+               if (buf[1] & UTICOM_MCR_DSR)
+                       sc->sc_msr |= UMSR_DSR;
+               if (buf[1] & UTICOM_MCR_CD)
+                       sc->sc_msr |= UMSR_DCD;         
+               if (buf[1] & UTICOM_MCR_RI)
+                       sc->sc_msr |= UMSR_RI;          
+       } else {
+               /* lsr registers */
+               if (buf[0] & UTICOM_LCR_OVR)
+                       sc->sc_lsr |= ULSR_OE;
+               if (buf[0] & UTICOM_LCR_PTE)
+                       sc->sc_lsr |= ULSR_PE;
+               if (buf[0] & UTICOM_LCR_FRE)
+                       sc->sc_lsr |= ULSR_FE;
+               if (buf[0] & UTICOM_LCR_BRK)
+                       sc->sc_lsr |= ULSR_BI;  
+       }
+  
+       if (uticomstickdsr)
+               sc->sc_msr |= UMSR_DSR;
+
+       ucom_status_change(&sc->sc_ucom);
+}
+
+static void
+uticom_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
+{
+#if 0 /* TODO */
+       struct uticom_softc *sc = addr;
+
+       DPRINTF(("uticom_get_status:\n"));
+
+       if (lsr != NULL)
+               *lsr = sc->sc_lsr;
+       if (msr != NULL)
+               *msr = sc->sc_msr;
+#endif
+       return;
+}
+
+#if 0 /* TODO */
+static int
+uticom_ioctl(void *addr, int portno, u_long cmd, caddr_t data, int flag,
+            usb_proc_ptr p)
+{
+       struct uticom_softc *sc = addr;
+       int error = 0;
+
+       if (sc->sc_ucom.sc_dying)
+               return (EIO);
+
+       DPRINTF(("uticom_ioctl: cmd = 0x%08lx\n", cmd));
+
+       switch (cmd) {
+       case TIOCNOTTY:
+       case TIOCMGET:
+       case TIOCMSET:
+       case USB_GET_CM_OVER_DATA:
+       case USB_SET_CM_OVER_DATA:
+               break;
+
+       default:
+               DPRINTF(("uticom_ioctl: unknown\n"));
+               error = ENOTTY;
+               break;
+       }
+
+       return (error);
+}
+#endif
+
+static int uticom_download_fw(struct uticom_softc *sc, unsigned int pipeno,
+                             usbd_device_handle dev, unsigned char *firmware,
+                             unsigned int firmware_size)
+{
+       int buffer_size;
+       int pos;
+       uint8_t cs = 0;
+       uint8_t *buffer;
+       usbd_status err;
+       struct uticom_fw_header *header;
+
+       buffer_size = UTICOM_FW_BUFSZ + sizeof(struct uticom_fw_header);
+       buffer = kmalloc(buffer_size, M_USBDEV, M_WAITOK);
+
+       if (!buffer) {
+               device_printf(sc->sc_ucom.sc_dev,
+                             "uticom_download_fw: out of memory\n");
+               return ENOMEM;
+       }
+
+       memcpy(buffer, firmware, firmware_size);
+       memset(buffer + firmware_size, 0xff, buffer_size - firmware_size);
+
+       for (pos = sizeof(struct uticom_fw_header); pos < buffer_size; pos++)
+               cs = (uint8_t)(cs + buffer[pos]);
+
+       header = (struct uticom_fw_header*)buffer;
+       header->length = (uint16_t)(buffer_size -
+                                    sizeof(struct uticom_fw_header));
+       header->checkSum = cs;
+
+       DPRINTF(("%s: downloading firmware ...\n",
+                device_get_nameunit(sc->sc_ucom.sc_dev)));
+
+       usbd_xfer_handle oxfer = 0;
+       u_char *obuf;
+       usbd_status error = 0;
+       usbd_pipe_handle pipe;
+
+       err = usbd_open_pipe(sc->sc_ucom.sc_iface, pipeno, USBD_EXCLUSIVE_USE,
+                            &pipe);
+       if (err) {
+               device_printf(sc->sc_ucom.sc_dev, "open bulk out error "
+                             "(addr %d): %s\n", pipeno, usbd_errstr(err));
+               error = EIO;
+               goto finish;
+       }
+
+       oxfer = usbd_alloc_xfer(dev);
+       if (oxfer == NULL) {
+               error = ENOMEM;
+               goto finish;
+       }
+
+       obuf = usbd_alloc_buffer(oxfer, buffer_size);
+       if (obuf == NULL) {
+               error = ENOMEM;
+               goto finish;
+       }
+
+       memcpy(obuf, buffer, buffer_size);
+
+       usbd_setup_xfer(oxfer, pipe, (usbd_private_handle)sc, obuf, buffer_size,
+                       USBD_NO_COPY || USBD_SYNCHRONOUS, USBD_NO_TIMEOUT, 0);
+       err = usbd_sync_transfer(oxfer);
+
+       if (err != USBD_NORMAL_COMPLETION)
+               device_printf(sc->sc_ucom.sc_dev, "uticom_download_fw: "
+                             "error: %s\n", usbd_errstr(err));
+
+finish:
+       usbd_free_buffer(oxfer);
+       usbd_free_xfer(oxfer);
+       oxfer = NULL;
+       usbd_abort_pipe(pipe);
+       usbd_close_pipe(pipe);
+       kfree(buffer, M_USBDEV);
+
+       return err;     
+}
diff --git a/sys/dev/usbmisc/uticom/uticom_fw3410.h b/sys/dev/usbmisc/uticom/uticom_fw3410.h
new file mode 100644 (file)
index 0000000..cd7d966
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * TI 3410 USB Serial Driver Firmware Header
+ *
+ * Copyright (c) 2005 Dmitry Komissaroff <dxi@mail.ru>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $DragonFly: src/sys/dev/usbmisc/uticom/uticom_fw3410.h,v 1.1 2007/11/07 08:31:08 hasso Exp $
+ */
+
+#ifndef _UTICOM_FW3410_H_
+#define _UTICOM_FW3410_H_
+
+static unsigned char uticom_fw_3410[] = {
+0x0d, 0xce,    /* firmware image length excluding header, little endian */
+0x00,
+0x02,0x10,0x1c,0x02,0x00,0x99,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x5e,0x12,0x01,
+0x6b,0x80,0xfe,0x90,0xff,0x4a,0xe4,0xf0,0x22,0x90,0xff,0x52,0xe0,0xfa,0x43,0x02,
+0x80,0x90,0xff,0x52,0xea,0xf0,0x30,0x00,0x03,0x02,0x01,0xb7,0x22,0x90,0xff,0x5a,
+0xe4,0xf0,0x22,0x90,0xff,0x0a,0xe4,0xf0,0x22,0x90,0xff,0x12,0xe4,0xf0,0x22,0x90,
+0xff,0x1a,0xe4,0xf0,0x22,0x90,0xff,0xfe,0x74,0x20,0xf0,0x22,0x90,0xff,0xfe,0x74,
+0x40,0xf0,0x22,0x12,0x08,0xa1,0x90,0xff,0xfe,0x74,0x80,0xf0,0x22,0x22,0xc0,0xe0,
+0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0xc0,0x06,
+0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0,0x00,0x12,0x0a,0x13,0xd0,0xd0,
+0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0xd0,0x03,0xd0,0x02,
+0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32,0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,
+0x83,0xc0,0xd0,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0xc0,
+0x06,0xc0,0x07,0x90,0xff,0x92,0xe0,0xf0,0x90,0x00,0xd0,0xc0,0x82,0xc0,0x83,0x90,
+0x00,0xeb,0x54,0x7e,0xf5,0xf0,0x04,0x93,0xc0,0xe0,0xe5,0xf0,0x93,0xc0,0xe0,0x22,
+0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,
+0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32,0x00,0x5d,0x00,0x5d,0x00,
+0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x33,0x00,
+0x39,0x00,0x3f,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x13,0x00,
+0x19,0x00,0x2d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x07,0xe4,0x00,
+0x5d,0x00,0x5d,0x00,0x45,0x00,0x4c,0x00,0x53,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x08,
+0x65,0x08,0x83,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x0f,0x11,0x0f,0x7f,0x00,
+0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,
+0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,
+0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x00,0x5d,0x90,0xff,0x93,0x74,0x2a,
+0xf0,0x7a,0x93,0x7b,0xff,0x90,0xff,0x93,0xe0,0xfc,0x43,0x04,0x01,0x8a,0x82,0x8b,
+0x83,0xec,0xf0,0x90,0xff,0xe0,0xe4,0xf0,0x90,0xff,0xe4,0xf0,0x90,0xff,0xfd,0xf0,
+0x90,0xff,0xab,0xf0,0x12,0x0b,0xee,0x12,0x0a,0x13,0x90,0xff,0xfc,0x74,0x80,0xf0,
+0xd2,0xaf,0x7a,0x93,0x7b,0xff,0x90,0xff,0x93,0xe0,0xfc,0x43,0x04,0x01,0x8a,0x82,
+0x8b,0x83,0xec,0xf0,0x80,0xec,0x22,0x75,0x1b,0x00,0xc2,0x00,0x7b,0x00,0xbb,0x41,
+0x00,0x50,0x0a,0x8b,0x82,0x75,0x83,0xfe,0xe4,0xf0,0x0b,0x80,0xf1,0x78,0x21,0xe6,
+0x08,0x46,0x60,0x53,0x78,0x21,0xc3,0x74,0x40,0x96,0xe4,0x08,0x96,0x50,0x12,0x75,
+0x1b,0x40,0x78,0x21,0xe6,0x24,0xc0,0xf6,0x08,0xe6,0x34,0xff,0xf6,0xd2,0x00,0x80,
+0x0a,0x78,0x21,0x86,0x1b,0x78,0x21,0xe4,0xf6,0x08,0xf6,0x7b,0x00,0xc3,0xeb,0x95,
+0x1b,0x50,0x24,0x8b,0x04,0x7d,0xfe,0x78,0x23,0x86,0x06,0x08,0x86,0x07,0x8e,0x82,
+0x8f,0x83,0xe0,0xfa,0x78,0x23,0x74,0x01,0x2e,0xf6,0xe4,0x3f,0x08,0xf6,0x8c,0x82,
+0x8d,0x83,0xea,0xf0,0x0b,0x80,0xd6,0x90,0xff,0x52,0xe5,0x1b,0xf0,0x22,0xaa,0x82,
+0xab,0x83,0xac,0xf0,0x7d,0x40,0x7e,0x00,0x78,0x23,0xa6,0x02,0x08,0xa6,0x03,0xc3,
+0xe5,0x08,0x94,0x40,0xe5,0x09,0x64,0x80,0x94,0x80,0x50,0x04,0xad,0x08,0xae,0x09,
+0x78,0x21,0xa6,0x05,0x08,0xa6,0x06,0x90,0xff,0x52,0xe4,0xf0,0x02,0x01,0xb7,0x7a,
+0x80,0x7b,0xff,0x90,0xff,0x80,0xe0,0xfc,0x43,0x04,0x08,0x8a,0x82,0x8b,0x83,0xec,
+0xf0,0x7a,0x82,0x7b,0xff,0x90,0xff,0x82,0xe0,0xfc,0x43,0x04,0x08,0x8a,0x82,0x8b,
+0x83,0xec,0xf0,0x22,0x75,0x1b,0x00,0xc2,0x01,0x78,0x27,0xe6,0x08,0x46,0x60,0x57,
+0x78,0x27,0xc3,0x74,0x08,0x96,0xe4,0x08,0x96,0x50,0x12,0x75,0x1b,0x08,0x78,0x27,
+0xe6,0x24,0xf8,0xf6,0x08,0xe6,0x34,0xff,0xf6,0xd2,0x01,0x80,0x0a,0x78,0x27,0x86,
+0x1b,0x78,0x27,0xe4,0xf6,0x08,0xf6,0x7b,0x00,0xc3,0xeb,0x95,0x1b,0x50,0x28,0xeb,
+0x24,0xf8,0xfc,0xe4,0x34,0xfe,0xfd,0x78,0x2b,0x86,0x06,0x08,0x86,0x07,0x8e,0x82,
+0x8f,0x83,0xe0,0xfa,0x78,0x2b,0x74,0x01,0x2e,0xf6,0xe4,0x3f,0x08,0xf6,0x8c,0x82,
+0x8d,0x83,0xea,0xf0,0x0b,0x80,0xd2,0x90,0xff,0x81,0xe5,0x1b,0xf0,0x22,0x85,0x82,
+0x0c,0x85,0x83,0x0d,0x85,0xf0,0x0e,0x90,0xff,0x07,0xe0,0xfd,0x8d,0x06,0x7d,0x00,
+0x90,0xff,0x06,0xe0,0xff,0x7a,0x00,0x4d,0xfb,0xea,0x4e,0xfa,0x78,0x2b,0xa6,0x0c,
+0x08,0xa6,0x0d,0xc3,0xe5,0x0a,0x9b,0xe5,0x0b,0x64,0x80,0x8a,0xf0,0x63,0xf0,0x80,
+0x95,0xf0,0x50,0x04,0xab,0x0a,0xaa,0x0b,0x78,0x27,0xa6,0x03,0x08,0xa6,0x02,0x90,
+0xff,0x83,0xe4,0xf0,0x02,0x02,0x84,0xc2,0x01,0x78,0x27,0xe4,0xf6,0x08,0xf6,0x90,
+0xff,0x81,0xe4,0xf0,0x22,0x7a,0x82,0x7b,0xff,0x90,0xff,0x82,0xe0,0xfc,0x43,0x04,
+0x08,0x8a,0x82,0x8b,0x83,0xec,0xf0,0x22,0x90,0xff,0x04,0xe0,0xfa,0x53,0x02,0x0f,
+0xba,0x00,0x03,0x02,0x03,0x37,0x1a,0xba,0x03,0x00,0x50,0x5a,0x90,0xff,0x04,0xe0,
+0xfb,0x53,0x03,0x80,0xbb,0x80,0x27,0xea,0x75,0xf0,0x08,0xa4,0xfb,0xac,0xf0,0xeb,
+0x24,0x48,0xfd,0xec,0x34,0xff,0xfe,0xeb,0x24,0x48,0xf5,0x82,0xec,0x34,0xff,0xf5,
+0x83,0xe0,0xfb,0x53,0x03,0xd7,0x8d,0x82,0x8e,0x83,0xeb,0xf0,0x80,0x25,0xea,0x75,
+0xf0,0x08,0xa4,0xfa,0xab,0xf0,0xea,0x24,0x08,0xfc,0xeb,0x34,0xff,0xfd,0xea,0x24,
+0x08,0xf5,0x82,0xeb,0x34,0xff,0xf5,0x83,0xe0,0xfa,0x53,0x02,0xd7,0x8c,0x82,0x8d,
+0x83,0xea,0xf0,0x12,0x03,0x37,0x7a,0x93,0x7b,0xff,0x90,0xff,0x93,0xe0,0xfc,0x43,
+0x04,0x01,0x8a,0x82,0x8b,0x83,0xec,0xf0,0x22,0x75,0x0a,0x01,0xe4,0xf5,0x0b,0x90,
+0x00,0x25,0x75,0xf0,0x00,0x02,0x02,0xee,0x75,0x0a,0x12,0xe4,0xf5,0x0b,0x90,0xf8,
+0x00,0x75,0xf0,0x01,0x02,0x02,0xee,0x75,0x0a,0x27,0xe4,0xf5,0x0b,0x90,0xf8,0x12,
+0x75,0xf0,0x01,0x02,0x02,0xee,0x7a,0x00,0x7b,0x00,0x90,0xff,0x02,0xe0,0xfc,0x14,
+0xfd,0x90,0xff,0x02,0xf0,0xec,0x24,0xff,0x50,0x16,0xea,0x24,0x39,0xf5,0x82,0xeb,
+0x34,0xf8,0xf5,0x83,0xe0,0xfc,0x7d,0x00,0xec,0x2a,0xfa,0xed,0x3b,0xfb,0x80,0xda,
+0xea,0x24,0x39,0xfa,0xeb,0x34,0xf8,0xfb,0x8a,0x04,0x8b,0x05,0x7e,0x01,0x8a,0x82,
+0x8b,0x83,0xe0,0xfa,0x8a,0x0a,0x75,0x0b,0x00,0x8c,0x82,0x8d,0x83,0x8e,0xf0,0x02,
+0x02,0xee,0x90,0xf8,0xab,0x78,0x26,0xe6,0xf0,0x75,0x0a,0x01,0xe4,0xf5,0x0b,0x90,
+0xf8,0xab,0x75,0xf0,0x01,0x02,0x02,0xee,0x90,0xf8,0x19,0xe0,0xfa,0x74,0x40,0x5a,
+0xfb,0xbb,0x40,0x06,0x90,0xf8,0xab,0x74,0x01,0xf0,0x53,0x02,0x20,0xba,0x20,0x0d,
+0x90,0xf8,0xab,0xe0,0xfa,0x43,0x02,0x02,0x90,0xf8,0xab,0xea,0xf0,0x75,0x0a,0x02,
+0xe4,0xf5,0x0b,0x90,0xf8,0xab,0x75,0xf0,0x01,0x02,0x02,0xee,0x75,0x0a,0x02,0xe4,
+0xf5,0x0b,0x90,0xf8,0xab,0x75,0xf0,0x01,0x02,0x02,0xee,0x90,0xff,0x04,0xe0,0xfa,
+0x53,0x02,0x0f,0xba,0x00,0x49,0x90,0xff,0x04,0xe0,0xfb,0x53,0x03,0x80,0xbb,0x80,
+0x0f,0x90,0xff,0x80,0xe0,0xfb,0x53,0x03,0x08,0x90,0xf8,0xab,0xeb,0xf0,0x80,0x0d,
+0x90,0xff,0x82,0xe0,0xfb,0x53,0x03,0x08,0x90,0xf8,0xab,0xeb,0xf0,0x90,0xf8,0xab,
+0xe0,0xfb,0xc4,0x23,0x54,0x1f,0xfb,0x90,0xf8,0xab,0xf0,0x90,0xff,0x83,0xe4,0xf0,
+0x75,0x0a,0x02,0xe4,0xf5,0x0b,0x90,0xf8,0xab,0x75,0xf0,0x01,0x02,0x02,0xee,0x1a,
+0xba,0x03,0x00,0x50,0x3c,0x90,0xff,0x04,0xe0,0xfb,0x30,0xe7,0x1b,0xea,0x75,0xf0,
+0x08,0xa4,0x24,0x48,0xf5,0x82,0x74,0xff,0x35,0xf0,0xf5,0x83,0xe0,0xfb,0x53,0x03,
+0x08,0x90,0xf8,0xab,0xeb,0xf0,0x80,0x19,0xea,0x75,0xf0,0x08,0xa4,0x24,0x08,0xf5,
+0x82,0x74,0xff,0x35,0xf0,0xf5,0x83,0xe0,0xfa,0x53,0x02,0x08,0x90,0xf8,0xab,0xea,
+0xf0,0x90,0xf8,0xab,0xe0,0xfa,0xc4,0x23,0x54,0x1f,0xfa,0x90,0xf8,0xab,0xf0,0x90,
+0xff,0x83,0xe4,0xf0,0x75,0x0a,0x02,0xe4,0xf5,0x0b,0x90,0xf8,0xab,0x75,0xf0,0x01,
+0x02,0x02,0xee,0x22,0x7a,0x82,0x7b,0xff,0x90,0xff,0x82,0xe0,0xfc,0x43,0x04,0x08,
+0x8a,0x82,0x8b,0x83,0xec,0xf0,0x90,0xff,0x02,0xe0,0xfa,0xba,0x80,0x00,0x50,0x11,
+0x7a,0xff,0x7b,0xff,0x90,0xff,0x02,0xe0,0xfc,0x8a,0x82,0x8b,0x83,0xf0,0x02,0x03,
+0x37,0x02,0x02,0x5f,0x7a,0x82,0x7b,0xff,0x90,0xff,0x82,0xe0,0xfc,0x43,0x04,0x08,
+0x8a,0x82,0x8b,0x83,0xec,0xf0,0x90,0xff,0x02,0xe0,0xfa,0x78,0x25,0xa6,0x02,0x02,
+0x03,0x37,0x02,0x02,0x5f,0x7a,0x82,0x7b,0xff,0x90,0xff,0x82,0xe0,0xfc,0x43,0x04,
+0x08,0x8a,0x82,0x8b,0x83,0xec,0xf0,0x90,0xff,0x02,0xe0,0xfa,0x60,0x03,0x02,0x06,
+0x3c,0x90,0xff,0x04,0xe0,0xfa,0x53,0x02,0x0f,0xba,0x00,0x03,0x02,0x03,0x37,0x1a,
+0xba,0x03,0x00,0x50,0x5a,0x90,0xff,0x04,0xe0,0xfb,0x30,0xe7,0x27,0xea,0x75,0xf0,
+0x08,0xa4,0xfb,0xac,0xf0,0xeb,0x24,0x48,0xfd,0xec,0x34,0xff,0xfe,0xeb,0x24,0x48,
+0xf5,0x82,0xec,0x34,0xff,0xf5,0x83,0xe0,0xfb,0x43,0x03,0x08,0x8d,0x82,0x8e,0x83,
+0xeb,0xf0,0x80,0x25,0xea,0x75,0xf0,0x08,0xa4,0xfa,0xab,0xf0,0xea,0x24,0x08,0xfc,
+0xeb,0x34,0xff,0xfd,0xea,0x24,0x08,0xf5,0x82,0xeb,0x34,0xff,0xf5,0x83,0xe0,0xfa,
+0x43,0x02,0x08,0x8c,0x82,0x8d,0x83,0xea,0xf0,0x02,0x03,0x37,0x02,0x02,0x5f,0x22,
+0x7a,0x82,0x7b,0xff,0x90,0xff,0x82,0xe0,0xfc,0x43,0x04,0x08,0x8a,0x82,0x8b,0x83,
+0xec,0xf0,0x90,0xff,0x04,0xe0,0xfa,0x78,0x26,0xa6,0x02,0x02,0x03,0x37,0x90,0xff,
+0xfe,0xe0,0xfa,0x53,0x02,0x01,0xba,0x00,0x03,0x02,0x02,0x5f,0x22,0x7a,0x82,0x7b,
+0xff,0x90,0xff,0x82,0xe0,0xfc,0x43,0x04,0x08,0x8a,0x82,0x8b,0x83,0xec,0xf0,0x90,
+0xff,0x00,0x12,0x0d,0x87,0xaa,0x82,0xab,0x83,0xba,0x00,0x05,0xbb,0x00,0x02,0x80,
+0x03,0x02,0x02,0x5f,0x02,0x03,0x37,0x90,0xff,0x00,0x12,0x0c,0x3e,0xaa,0x82,0xab,
+0x83,0x8a,0x04,0x8b,0x05,0xea,0x4b,0x60,0x1b,0x8c,0x82,0x8d,0x83,0xe0,0xfa,0x8a,
+0x0a,0x75,0x0b,0x00,0x0c,0xbc,0x00,0x01,0x0d,0x7a,0x01,0x8c,0x82,0x8d,0x83,0x8a,
+0xf0,0x02,0x02,0xee,0x02,0x02,0x5f,0x90,0xff,0x00,0xe0,0xfa,0x30,0xe7,0x03,0x02,
+0x06,0x97,0x02,0x06,0x6d,0x7a,0x00,0xba,0x08,0x00,0x50,0x12,0xea,0x24,0x10,0xf8,
+0x8a,0x82,0x74,0xff,0x24,0x00,0xf5,0x83,0xe0,0xfb,0xf6,0x0a,0x80,0xe9,0x7a,0x33,
+0x7b,0x0b,0x7c,0x02,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x12,0x0f,0xf0,0xfd,0xa3,0xaa,
+0x82,0xab,0x83,0x8c,0xf0,0x12,0x0f,0xf0,0xfe,0xa3,0xaa,0x82,0xab,0x83,0xbd,0xff,
+0x05,0xbe,0xff,0x02,0x80,0x0a,0xaf,0x10,0xbf,0xc0,0x02,0x80,0x03,0xbf,0x40,0x0b,
+0xea,0x24,0xfe,0xfa,0xeb,0x34,0xff,0xfb,0x02,0x07,0xad,0xed,0xb5,0x07,0x74,0xee,
+0xb5,0x11,0x02,0x80,0x02,0x80,0x6c,0x7f,0xc0,0x75,0x0f,0x20,0x8a,0x18,0x8b,0x19,
+0x8c,0x1a,0x7a,0x02,0xba,0x08,0x00,0x50,0x2b,0xea,0x24,0x10,0xf8,0x86,0x05,0x85,
+0x18,0x82,0x85,0x19,0x83,0x85,0x1a,0xf0,0x12,0x0f,0xf0,0xfe,0xa3,0x85,0x82,0x18,
+0x85,0x83,0x19,0xed,0xb5,0x06,0x04,0xe5,0x0f,0x42,0x07,0xe5,0x0f,0xc3,0x13,0xf5,
+0x0f,0x0a,0x80,0xd0,0x85,0x18,0x82,0x85,0x19,0x83,0x85,0x1a,0xf0,0x12,0x0f,0xf0,
+0xfd,0xef,0x5d,0xfe,0xb5,0x05,0x0e,0xe5,0x18,0x24,0xf8,0xfa,0xe5,0x19,0x34,0xff,
+0xfb,0xac,0x1a,0x80,0x18,0x74,0x03,0x25,0x18,0xfa,0xe4,0x35,0x19,0xfb,0xac,0x1a,
+0x02,0x06,0xf4,0x74,0x09,0x2a,0xfa,0xe4,0x3b,0xfb,0x02,0x06,0xf4,0x90,0xff,0xfe,
+0xe0,0xfd,0x53,0x05,0x01,0xbd,0x00,0x2b,0x74,0x09,0x2a,0xfa,0xe4,0x3b,0xfb,0x8a,
+0x82,0x8b,0x83,0x8c,0xf0,0x12,0x0f,0xf0,0xfa,0xa3,0x12,0x0f,0xf0,0xfb,0xc0,0x02,
+0xc0,0x03,0x74,0xdf,0xc0,0xe0,0x74,0x07,0xc0,0xe0,0xc0,0x02,0xc0,0x03,0x22,0xd0,
+0x03,0xd0,0x02,0x22,0x7a,0xfc,0x7b,0xff,0x90,0xff,0xfc,0xe0,0xfc,0x43,0x04,0x02,
+0x8a,0x82,0x8b,0x83,0xec,0xf0,0x90,0xff,0x00,0xe0,0xfa,0x53,0x02,0x80,0xba,0x80,
+0x14,0x7a,0xfc,0x7b,0xff,0x90,0xff,0xfc,0xe0,0xfc,0x43,0x04,0x01,0x8a,0x82,0x8b,
+0x83,0xec,0xf0,0x80,0x12,0x7a,0xfc,0x7b,0xff,0x90,0xff,0xfc,0xe0,0xfc,0x53,0x04,
+0xfe,0x8a,0x82,0x8b,0x83,0xec,0xf0,0xc2,0x01,0xc2,0x02,0x7a,0x00,0xba,0x04,0x00,
+0x50,0x0f,0xea,0x24,0xab,0xf5,0x82,0xe4,0x34,0xf8,0xf5,0x83,0xe4,0xf0,0x0a,0x80,
+0xec,0x12,0x06,0xd5,0x90,0xff,0xfe,0xe0,0xfa,0x20,0xe0,0xaa,0x7a,0xfc,0x7b,0xff,
+0x90,0xff,0xfc,0xe0,0xfc,0x53,0x04,0xfd,0x8a,0x82,0x8b,0x83,0xec,0xf0,0x90,0xff,
+0xfe,0x74,0x04,0xf0,0x22,0x90,0xff,0x83,0xe4,0xf0,0x30,0x01,0x03,0x02,0x02,0x84,
+0x7a,0x80,0x7b,0xff,0x90,0xff,0x80,0xe0,0xfc,0x43,0x04,0x08,0x8a,0x82,0x8b,0x83,
+0xec,0xf0,0x22,0x90,0xff,0x81,0xe4,0xf0,0x30,0x02,0x03,0x02,0x03,0x45,0x7a,0x82,
+0x7b,0xff,0x90,0xff,0x82,0xe0,0xfc,0x43,0x04,0x08,0x8a,0x82,0x8b,0x83,0xec,0xf0,
+0x22,0x78,0x27,0xe4,0xf6,0x08,0xf6,0x78,0x29,0xe4,0xf6,0x08,0xf6,0xc2,0x01,0xc2,
+0x02,0x90,0xff,0xe0,0xe4,0xf0,0x90,0xff,0xe4,0xf0,0x7a,0x00,0x74,0xfb,0xfb,0xc4,
+0x23,0xca,0xc4,0x23,0x54,0x1f,0x6a,0xca,0x54,0x1f,0xca,0x6a,0xca,0x7b,0x00,0x8a,
+0x1b,0x7b,0x00,0xbb,0x03,0x00,0x40,0x03,0x02,0x09,0xc2,0x90,0xff,0x08,0xe4,0xf0,
+0x90,0xff,0x48,0xf0,0xeb,0x75,0xf0,0x08,0xa4,0xfc,0xad,0xf0,0xec,0x24,0x08,0xfe,
+0xed,0x34,0xff,0xff,0x74,0x07,0x2e,0xf5,0x82,0xe4,0x3f,0xf5,0x83,0x74,0x40,0xf0,
+0xec,0x24,0x48,0xfe,0xed,0x34,0xff,0xff,0x74,0x07,0x2e,0xf5,0x82,0xe4,0x3f,0xf5,
+0x83,0x74,0x40,0xf0,0xec,0x24,0x08,0xfe,0xed,0x34,0xff,0xff,0x74,0x02,0x2e,0xf5,
+0x82,0xe4,0x3f,0xf5,0x83,0xe4,0xf0,0xec,0x24,0x08,0xfe,0xed,0x34,0xff,0xff,0x74,
+0x06,0x2e,0xf5,0x82,0xe4,0x3f,0xf5,0x83,0xe4,0xf0,0xec,0x24,0x48,0xfe,0xed,0x34,
+0xff,0xff,0x74,0x02,0x2e,0xf5,0x82,0xe4,0x3f,0xf5,0x83,0x74,0x80,0xf0,0xec,0x24,
+0x48,0xfe,0xed,0x34,0xff,0xff,0x74,0x06,0x2e,0xf5,0x82,0xe4,0x3f,0xf5,0x83,0x74,
+0x80,0xf0,0xec,0x24,0x08,0xfe,0xed,0x34,0xff,0xff,0x74,0x01,0x2e,0xf5,0x82,0xe4,
+0x3f,0xf5,0x83,0xeb,0xc4,0x23,0x54,0xe0,0x25,0x1b,0xfe,0xf0,0xec,0x24,0x08,0xff,
+0xed,0x34,0xff,0xfa,0x74,0x05,0x2f,0xf5,0x82,0xe4,0x3a,0xf5,0x83,0x74,0x08,0x2e,
+0xfa,0xf0,0xec,0x24,0x48,0xfa,0xed,0x34,0xff,0xff,0x74,0x01,0x2a,0xf5,0x82,0xe4,
+0x3f,0xf5,0x83,0x74,0x10,0x2e,0xfa,0xf0,0xec,0x24,0x48,0xfc,0xed,0x34,0xff,0xfd,
+0x74,0x05,0x2c,0xf5,0x82,0xe4,0x3d,0xf5,0x83,0x74,0x18,0x2e,0xfe,0xf0,0x0b,0x02,
+0x08,0xd3,0x90,0xff,0x80,0x74,0x8c,0xf0,0x90,0xff,0x82,0x74,0x8c,0xf0,0x90,0xff,
+0x08,0x74,0x90,0xf0,0x90,0xff,0x48,0x74,0x90,0xf0,0x7a,0x00,0x74,0xfe,0xfb,0xc4,
+0x23,0xca,0xc4,0x23,0x54,0x1f,0x6a,0xca,0x54,0x1f,0xca,0x6a,0xca,0x7b,0x00,0x90,
+0xff,0x51,0xea,0xf0,0x90,0xff,0x50,0x74,0x84,0xf0,0x90,0xff,0xe1,0x74,0x94,0xf0,
+0x90,0xff,0xe5,0x74,0x94,0xf0,0x90,0xff,0xe0,0x74,0xa1,0xf0,0x90,0xff,0xe4,0x74,
+0xa1,0xf0,0x22,0x90,0xf8,0x80,0x78,0x25,0xe0,0xf6,0x90,0xf8,0x81,0x78,0x26,0xe0,
+0xf6,0x7a,0x00,0xba,0x12,0x00,0x50,0x16,0xea,0x24,0x00,0xfb,0xe4,0x34,0xf8,0xfc,
+0xea,0x90,0x0a,0x88,0x93,0xfd,0x8b,0x82,0x8c,0x83,0xf0,0x0a,0x80,0xe5,0x7a,0x00,
+0xba,0x27,0x00,0x50,0x16,0xea,0x24,0x12,0xfb,0xe4,0x34,0xf8,0xfc,0xea,0x90,0x0a,
+0x9a,0x93,0xfd,0x8b,0x82,0x8c,0x83,0xf0,0x0a,0x80,0xe5,0x90,0xf8,0x14,0x74,0x27,
+0xf0,0x7a,0x00,0xba,0x72,0x00,0x50,0x16,0xea,0x24,0x39,0xfb,0xe4,0x34,0xf8,0xfc,
+0xea,0x90,0x0a,0xc1,0x93,0xfd,0x8b,0x82,0x8c,0x83,0xf0,0x0a,0x80,0xe5,0x12,0x08,
+0xa1,0x90,0xff,0xfd,0x74,0xe4,0xf0,0x22,0x12,0x01,0x10,0x01,0xff,0x00,0x00,0x08,
+0x51,0x04,0x10,0x34,0x01,0x00,0x01,0x02,0x03,0x02,0x09,0x02,0xff,0x00,0x01,0x02,
+0x00,0x80,0x32,0x09,0x04,0x00,0x00,0x03,0xff,0x00,0x00,0x00,0x07,0x05,0x01,0x02,
+0x40,0x00,0x00,0x07,0x05,0x81,0x02,0x40,0x00,0x00,0x07,0x05,0x82,0x03,0x40,0x00,
+0x00,0x04,0x03,0x09,0x04,0x22,0x03,0x55,0x00,0x41,0x00,0x52,0x00,0x54,0x00,0x32,
+0x00,0x55,0x00,0x53,0x00,0x42,0x00,0x20,0x00,0x61,0x00,0x64,0x00,0x61,0x00,0x70,
+0x00,0x74,0x00,0x65,0x00,0x72,0x00,0x2a,0x03,0x54,0x00,0x55,0x00,0x53,0x00,0x42,
+0x00,0x33,0x00,0x34,0x00,0x31,0x00,0x30,0x00,0x20,0x00,0x42,0x00,0x6f,0x00,0x6f,
+0x00,0x74,0x00,0x20,0x00,0x44,0x00,0x65,0x00,0x76,0x00,0x69,0x00,0x63,0x00,0x65,
+0x00,0x22,0x03,0x42,0x00,0x4d,0x00,0x4c,0x00,0x53,0x00,0x30,0x00,0x30,0x00,0x30,
+0x00,0x30,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,
+0x00,0x20,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0xc7,0x06,0x40,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x80,0xc7,0x06,0x02,0x01,0x00,0x00,0xff,0x00,0x00,
+0x00,0xf7,0x58,0x03,0x80,0x08,0x00,0x00,0x00,0x00,0x01,0x00,0xff,0xd9,0x03,0x80,
+0x06,0xff,0x01,0xff,0xff,0xff,0xff,0xd0,0xe8,0x03,0x80,0x06,0xff,0x02,0xff,0xff,
+0xff,0xff,0xd0,0xf7,0x03,0x80,0x06,0xff,0x03,0xff,0xff,0xff,0xff,0xd0,0x06,0x04,
+0x81,0x0a,0x00,0x00,0xff,0xff,0x01,0x00,0xf3,0x52,0x04,0x80,0x00,0x00,0x00,0x00,
+0x00,0x02,0x00,0xff,0x68,0x04,0x81,0x00,0x00,0x00,0xff,0x00,0x02,0x00,0xf7,0x9c,
+0x04,0x82,0x00,0x00,0x00,0xff,0x00,0x02,0x00,0xf7,0xab,0x04,0x00,0x05,0xff,0x00,
+0x00,0x00,0x00,0x00,0xdf,0x64,0x05,0x00,0x09,0xff,0x00,0x00,0x00,0x00,0x00,0xdf,
+0x94,0x05,0x00,0x03,0xff,0x00,0x00,0x00,0x00,0x00,0xdf,0xb2,0x05,0x02,0x03,0xff,
+0x00,0xff,0x00,0x00,0x00,0xd7,0xb5,0x05,0x01,0x0b,0xff,0x00,0xff,0x00,0x00,0x00,
+0xd7,0x40,0x06,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x5e,0x06,0x90,0xf8,
+0xaf,0xe4,0xf0,0x90,0xff,0xab,0xf0,0x90,0xff,0xa4,0x74,0x01,0xf0,0x90,0xff,0xa9,
+0x74,0x11,0xf0,0x90,0xff,0xaa,0x74,0x13,0xf0,0x90,0xff,0xa7,0x74,0x60,0xf0,0x90,
+0xff,0xa8,0xe4,0xf0,0x90,0xff,0xa2,0x74,0x83,0xf0,0x90,0xff,0xa3,0xe4,0xf0,0x90,
+0xff,0xa4,0xf0,0x7a,0xab,0x7b,0xff,0x90,0xff,0xab,0xe0,0xfc,0x74,0x01,0x4c,0xfd,
+0x8a,0x82,0x8b,0x83,0xf0,0x90,0xff,0xab,0x43,0x04,0x02,0xec,0xf0,0x22,0xaa,0x82,
+0xab,0x83,0x74,0x01,0x2a,0xf5,0x82,0xe4,0x3b,0xf5,0x83,0xe0,0xfa,0x60,0x02,0x80,
+0x4d,0x90,0xff,0xa7,0xe0,0xfa,0x90,0xf8,0xb1,0xf0,0x90,0xff,0xa8,0xe0,0xfa,0x90,
+0xf8,0xb2,0xf0,0x90,0xff,0xa2,0xe0,0xfa,0x90,0xf8,0xb3,0xf0,0x90,0xff,0xa4,0xe0,
+0xfa,0x63,0x02,0x20,0x90,0xf8,0xb4,0xea,0xf0,0x90,0xff,0xa3,0xe0,0xfa,0x90,0xf8,
+0xb5,0xf0,0x90,0xff,0xa5,0xe0,0xfa,0x90,0xf8,0xb6,0xf0,0x90,0xff,0xa6,0xe0,0xfa,
+0x90,0xf8,0xb7,0xf0,0x90,0xf8,0xb0,0x74,0x07,0xf0,0x90,0xf8,0xb0,0x22,0x90,0x00,
+0x00,0x22,0xe5,0x82,0xfa,0x24,0xf2,0x50,0x03,0x02,0x0d,0x7b,0xea,0x2a,0x2a,0x90,
+0x0c,0xb3,0x73,0x02,0x0d,0x7b,0x02,0x0c,0xdd,0x02,0x0c,0xea,0x02,0x0c,0xf7,0x02,
+0x0d,0x03,0x02,0x0d,0x0f,0x02,0x0d,0x1b,0x02,0x0d,0x27,0x02,0x0d,0x33,0x02,0x0d,
+0x3f,0x02,0x0d,0x4b,0x02,0x0d,0x57,0x02,0x0d,0x63,0x02,0x0d,0x6f,0x90,0xff,0xa8,
+0x74,0x03,0xf0,0x90,0xff,0xa7,0x74,0x01,0xf0,0x22,0x90,0xff,0xa8,0x74,0x01,0xf0,
+0x90,0xff,0xa7,0x74,0x81,0xf0,0x22,0x90,0xff,0xa8,0xe4,0xf0,0x90,0xff,0xa7,0x74,
+0xc0,0xf0,0x22,0x90,0xff,0xa8,0xe4,0xf0,0x90,0xff,0xa7,0x74,0x80,0xf0,0x22,0x90,
+0xff,0xa8,0xe4,0xf0,0x90,0xff,0xa7,0x74,0x60,0xf0,0x22,0x90,0xff,0xa8,0xe4,0xf0,
+0x90,0xff,0xa7,0x74,0x40,0xf0,0x22,0x90,0xff,0xa8,0xe4,0xf0,0x90,0xff,0xa7,0x74,
+0x30,0xf0,0x22,0x90,0xff,0xa8,0xe4,0xf0,0x90,0xff,0xa7,0x74,0x18,0xf0,0x22,0x90,
+0xff,0xa8,0xe4,0xf0,0x90,0xff,0xa7,0x74,0x10,0xf0,0x22,0x90,0xff,0xa8,0xe4,0xf0,
+0x90,0xff,0xa7,0x74,0x08,0xf0,0x22,0x90,0xff,0xa8,0xe4,0xf0,0x90,0xff,0xa7,0x74,
+0x04,0xf0,0x22,0x90,0xff,0xa8,0xe4,0xf0,0x90,0xff,0xa7,0x74,0x02,0xf0,0x22,0x90,
+0xff,0xa8,0xe4,0xf0,0x90,0xff,0xa7,0x74,0x01,0xf0,0x22,0x90,0xff,0xa8,0xe4,0xf0,
+0x90,0xff,0xa7,0x74,0x60,0xf0,0x22,0xaa,0x82,0xab,0x83,0x74,0x01,0x2a,0xf5,0x82,
+0xe4,0x3b,0xf5,0x83,0xe0,0xfc,0x24,0xf6,0x50,0x03,0x02,0x0f,0x06,0xec,0x2c,0x2c,
+0x90,0x0d,0xa4,0x73,0x02,0x0f,0x06,0x02,0x0d,0xc2,0x02,0x0d,0xc5,0x02,0x0d,0xcb,
+0x02,0x0d,0xfe,0x02,0x0d,0xf6,0x02,0x0e,0x19,0x02,0x0e,0x51,0x02,0x0e,0x89,0x02,
+0x0e,0xc0,0x02,0x0f,0x0d,0x12,0x0b,0xee,0x02,0x0f,0x0d,0x7c,0xa8,0x7d,0xff,0x74,
+0x03,0x2a,0xf5,0x82,0xe4,0x3b,0xf5,0x83,0xe0,0xfe,0x8c,0x82,0x8d,0x83,0xf0,0x7c,
+0xa7,0x7d,0xff,0x74,0x02,0x2a,0xf5,0x82,0xe4,0x3b,0xf5,0x83,0xe0,0xfe,0x8c,0x82,
+0x8d,0x83,0xf0,0x02,0x0f,0x0d,0x90,0xff,0xa3,0xe4,0xf0,0x02,0x0f,0x0d,0x7c,0xa2,
+0x7d,0xff,0x74,0x02,0x2a,0xf5,0x82,0xe4,0x3b,0xf5,0x83,0xe0,0xfe,0x43,0x06,0x80,
+0x8c,0x82,0x8d,0x83,0xee,0xf0,0x02,0x0f,0x0d,0x74,0x02,0x2a,0xfc,0xe4,0x3b,0xfd,
+0x8c,0x82,0x8d,0x83,0xe0,0x70,0x15,0x7c,0xa4,0x7d,0xff,0x90,0xff,0xa4,0xe0,0xfe,
+0x43,0x06,0x20,0x8c,0x82,0x8d,0x83,0xee,0xf0,0x02,0x0f,0x0d,0x7c,0xa4,0x7d,0xff,
+0x90,0xff,0xa4,0xe0,0xfe,0x53,0x06,0xdf,0x8c,0x82,0x8d,0x83,0xee,0xf0,0x02,0x0f,
+0x0d,0x74,0x02,0x2a,0xfc,0xe4,0x3b,0xfd,0x8c,0x82,0x8d,0x83,0xe0,0x60,0x15,0x7c,
+0xa4,0x7d,0xff,0x90,0xff,0xa4,0xe0,0xfe,0x43,0x06,0x10,0x8c,0x82,0x8d,0x83,0xee,
+0xf0,0x02,0x0f,0x0d,0x7c,0xa4,0x7d,0xff,0x90,0xff,0xa4,0xe0,0xfe,0x53,0x06,0xef,
+0x8c,0x82,0x8d,0x83,0xee,0xf0,0x02,0x0f,0x0d,0x74,0x02,0x2a,0xfc,0xe4,0x3b,0xfd,
+0x8c,0x82,0x8d,0x83,0xe0,0x60,0x15,0x7c,0xa2,0x7d,0xff,0x90,0xff,0xa2,0xe0,0xfe,
+0x43,0x06,0x08,0x8c,0x82,0x8d,0x83,0xee,0xf0,0x02,0x0f,0x0d,0x7c,0xa2,0x7d,0xff,
+0x90,0xff,0xa2,0xe0,0xfe,0x53,0x06,0xf7,0x8c,0x82,0x8d,0x83,0xee,0xf0,0x80,0x4d,
+0x74,0x02,0x2a,0xfa,0xe4,0x3b,0xfb,0x8a,0x82,0x8b,0x83,0xe0,0x60,0x1c,0x7a,0xa3,
+0x7b,0xff,0x90,0xff,0xa3,0xe0,0xfc,0x74,0x04,0x4c,0xfd,0x8a,0x82,0x8b,0x83,0xf0,
+0x90,0xff,0xa3,0x43,0x04,0x20,0xec,0xf0,0x80,0x23,0x7a,0xa3,0x7b,0xff,0x90,0xff,
+0xa3,0xe0,0xfc,0x74,0xfb,0x5c,0xfd,0x8a,0x82,0x8b,0x83,0xf0,0x90,0xff,0xa3,0x53,
+0x04,0xdf,0xec,0xf0,0x80,0x07,0x12,0x0f,0x7f,0x90,0x00,0x01,0x22,0x90,0x00,0x00,
+0x22,0x90,0xf8,0xb9,0xe4,0xf0,0x90,0xff,0xa5,0xe0,0xfa,0x30,0xe0,0x0d,0x90,0xf8,
+0xb8,0xe0,0xfb,0x43,0x03,0x01,0x90,0xf8,0xb8,0xeb,0xf0,0xea,0x30,0xe1,0x0d,0x90,
+0xf8,0xb8,0xe0,0xfb,0x43,0x03,0x02,0x90,0xf8,0xb8,0xeb,0xf0,0xea,0x30,0xe2,0x0d,
+0x90,0xf8,0xb8,0xe0,0xfb,0x43,0x03,0x04,0x90,0xf8,0xb8,0xeb,0xf0,0xea,0x30,0xe3,
+0x0d,0x90,0xf8,0xb8,0xe0,0xfa,0x43,0x02,0x08,0x90,0xf8,0xb8,0xea,0xf0,0x75,0x08,
+0x02,0xe4,0xf5,0x09,0x90,0xf8,0xb8,0x75,0xf0,0x01,0x12,0x02,0x2e,0x90,0xff,0xa5,
+0xe0,0xfa,0x54,0x0f,0x60,0x08,0x90,0xff,0xa5,0x43,0x02,0x0f,0xea,0xf0,0x22,0x90,
+0xff,0xa6,0xe0,0xfa,0x30,0xe0,0x10,0x90,0xf8,0xaf,0xe0,0xfb,0x64,0x01,0xf0,0x90,
+0xff,0xa6,0x74,0x01,0x4a,0xfb,0xf0,0xea,0x30,0xe1,0x10,0x90,0xf8,0xaf,0xe0,0xfb,
+0x64,0x02,0xf0,0x90,0xff,0xa6,0x74,0x02,0x4a,0xfb,0xf0,0xea,0x30,0xe2,0x10,0x90,
+0xf8,0xaf,0xe0,0xfb,0x64,0x08,0xf0,0x90,0xff,0xa6,0x74,0x04,0x4a,0xfb,0xf0,0xea,
+0x30,0xe3,0x10,0x90,0xf8,0xaf,0xe0,0xfb,0x64,0x04,0xf0,0x90,0xff,0xa6,0x43,0x02,
+0x08,0xea,0xf0,0x90,0xf8,0xba,0xe4,0xf0,0x90,0xf8,0xaf,0xe0,0xfa,0x90,0xf8,0xbb,
+0xf0,0x75,0x08,0x02,0xe4,0xf5,0x09,0x90,0xf8,0xba,0x75,0xf0,0x01,0x02,0x02,0x2e,
+0xe5,0xf0,0x60,0x10,0x14,0x60,0x15,0x14,0x60,0x14,0x14,0x60,0x13,0x14,0x14,0x60,
+0x03,0x74,0xff,0x22,0xc0,0x00,0xa8,0x82,0xe6,0xd0,0x00,0x22,0xe0,0x22,0x93,0x22,
+0xc0,0x00,0xa8,0x82,0xe2,0xd0,0x00,0x22,0x75,0x82,0x00,0x22,0x75,0x81,0x2e,0x12,
+0x10,0x18,0xe5,0x82,0x60,0x03,0x02,0x00,0x0e,0x79,0x00,0xe9,0x44,0x00,0x60,0x1b,
+0x7a,0x00,0x90,0x10,0x81,0x78,0xbc,0x75,0xa0,0xf8,0xe4,0x93,0xf2,0xa3,0x08,0xb8,
+0x00,0x02,0x05,0xa0,0xd9,0xf4,0xda,0xf2,0x75,0xa0,0xff,0xe4,0x78,0xff,0xf6,0xd8,
+0xfd,0x78,0x00,0xe8,0x44,0x00,0x60,0x0a,0x79,0x00,0x75,0xa0,0x00,0xe4,0xf3,0x09,
+0xd8,0xfc,0x78,0xbc,0xe8,0x44,0x00,0x60,0x0c,0x79,0x01,0x90,0xf8,0x00,0xe4,0xf0,
+0xa3,0xd8,0xfc,0xd9,0xfa,0x75,0x00,0x87,0x75,0x01,0x87,0x75,0x02,0x87,0x02,0x00,
+0x0e
+};
+
+#endif /* _UTICOM_FW3410_H_ */