summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2009-05-09 19:23:08 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2009-05-09 19:23:08 +0000
commit12f3ea40e46deb8cb10e6c55ea6ad8d03dccdd85 (patch)
tree45bcb1bb48451b3d6c94686e0975928122e203ae /sys
parentf887e7365a5d4a9e35498e5183fe4506316e3823 (diff)
Initial console device driver for USB displays based on the DisplayLink
DL-120 / DL-160 graphic chips, using the wsdisplay(4) layer. Based on the reversed engineered specifications of Florian Echtler. The driver is disabled in GENERIC for now. Thanks to claudio@ for donating me a device and to oga@ and miod@ for giving me hints in the graphic and wsdisplay area. OK deraadt
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/conf/GENERIC5
-rw-r--r--sys/arch/amd64/conf/files.amd645
-rw-r--r--sys/dev/usb/files.usb6
-rw-r--r--sys/dev/usb/udl.c1344
-rw-r--r--sys/dev/usb/udl.h641
-rw-r--r--sys/dev/wscons/wsconsio.h3
6 files changed, 2000 insertions, 4 deletions
diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC
index b883278c365..368c1ea0f55 100644
--- a/sys/arch/amd64/conf/GENERIC
+++ b/sys/arch/amd64/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.262 2009/04/20 13:26:20 ariane Exp $
+# $OpenBSD: GENERIC,v 1.263 2009/05/09 19:23:07 mglocker Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -237,6 +237,9 @@ onewire* at uow?
uvideo* at uhub?
video* at uvideo?
+#udl* at uhub?
+#wsdisplay* at udl?
+
puc* at pci? # PCI "universal" communication device
#puc* at cardbus?
diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64
index 3a83fb1b39b..b3b74da2334 100644
--- a/sys/arch/amd64/conf/files.amd64
+++ b/sys/arch/amd64/conf/files.amd64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.amd64,v 1.47 2009/05/07 11:30:16 ariane Exp $
+# $OpenBSD: files.amd64,v 1.48 2009/05/09 19:23:07 mglocker Exp $
maxpartitions 16
maxusers 2 16 128
@@ -59,6 +59,9 @@ file arch/amd64/isa/clock.c
file arch/amd64/amd64/powernow-k8.c !small_kernel
file arch/amd64/amd64/est.c !small_kernel
+include "dev/rasops/files.rasops"
+include "dev/wsfont/files.wsfont"
+
include "dev/mii/files.mii"
include "scsi/files.scsi"
diff --git a/sys/dev/usb/files.usb b/sys/dev/usb/files.usb
index faacdb428ff..8cfbe15ba49 100644
--- a/sys/dev/usb/files.usb
+++ b/sys/dev/usb/files.usb
@@ -1,4 +1,4 @@
-# $OpenBSD: files.usb,v 1.82 2009/03/23 21:53:57 damien Exp $
+# $OpenBSD: files.usb,v 1.83 2009/05/09 19:23:07 mglocker Exp $
# $NetBSD: files.usb,v 1.16 2000/02/14 20:29:54 augustss Exp $
#
# Config file and device description for machine-independent USB code.
@@ -39,6 +39,10 @@ device uvideo: video, firmload
attach uvideo at uhub
file dev/usb/uvideo.c uvideo
+device udl: wsemuldisplaydev, rasops16
+attach udl at uhub
+file dev/usb/udl.c udl
+
# MIDI devices
device umidi: midibus
attach umidi at uhub
diff --git a/sys/dev/usb/udl.c b/sys/dev/usb/udl.c
new file mode 100644
index 00000000000..696946981c9
--- /dev/null
+++ b/sys/dev/usb/udl.c
@@ -0,0 +1,1344 @@
+/* $OpenBSD: udl.c,v 1.1 2009/05/09 19:23:07 mglocker Exp $ */
+
+/*
+ * Copyright (c) 2009 Marcus Glocker <mglocker@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Driver for the ``DisplayLink DL-120 / DL-160'' graphic chips based
+ * on the reversed engineered specifications of Florian Echtler
+ * <floe@butterbrot.org>:
+ *
+ * http://floe.butterbrot.org/displaylink/doku.php
+ *
+ * This driver has been inspired by the cfxga(4) driver because we have
+ * to deal with similar challenges, like no direct access to the video
+ * memory.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <uvm/uvm.h>
+
+#include <machine/bus.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usbdevs.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/rasops/rasops.h>
+
+#include <dev/usb/udl.h>
+
+/*
+ * Defines.
+ */
+#if 0
+#define UDL_DEBUG
+#endif
+#ifdef UDL_DEBUG
+int udl_debug = 1;
+#define DPRINTF(l, x...) do { if ((l) <= udl_debug) printf(x); } while (0)
+#else
+#define DPRINTF(l, x...)
+#endif
+
+#define DN(sc) ((sc)->sc_dev.dv_xname)
+#define FUNC __func__
+
+/*
+ * Prototypes.
+ */
+int udl_match(struct device *, void *, void *);
+void udl_attach(struct device *, struct device *, void *);
+int udl_detach(struct device *, int);
+int udl_activate(struct device *, enum devact);
+
+int udl_ioctl(void *, u_long, caddr_t, int, struct proc *);
+paddr_t udl_mmap(void *, off_t, int);
+int udl_alloc_screen(void *, const struct wsscreen_descr *,
+ void **, int *, int *, long *);
+void udl_free_screen(void *, void *);
+int udl_show_screen(void *, void *, int,
+ void (*)(void *, int, int), void *);
+void udl_burner(void *, u_int, u_int);
+
+void udl_copycols(void *, int, int, int, int);
+void udl_copyrows(void *, int, int, int);
+void udl_erasecols(void *, int, int, int, long);
+void udl_eraserows(void *, int, int, long);
+void udl_putchar(void *, int, int, u_int, long);
+void udl_do_cursor(struct rasops_info *);
+
+usbd_status udl_ctrl_msg(struct udl_softc *, uint8_t, uint8_t,
+ uint16_t, uint16_t, uint8_t *, size_t);
+usbd_status udl_poll(struct udl_softc *, uint32_t *);
+usbd_status udl_read_1(struct udl_softc *, uint16_t, uint8_t *);
+usbd_status udl_write_1(struct udl_softc *, uint16_t, uint8_t);
+usbd_status udl_read_edid(struct udl_softc *, uint8_t *);
+usbd_status udl_set_enc_key(struct udl_softc *, uint8_t *, uint8_t);
+usbd_status udl_set_decomp_table(struct udl_softc *, uint8_t *, uint16_t);
+
+usbd_status udl_cmd_alloc_xfer(struct udl_softc *);
+void udl_cmd_free_xfer(struct udl_softc *);
+int udl_cmd_alloc_buf(struct udl_softc *);
+void udl_cmd_free_buf(struct udl_softc *);
+void udl_cmd_insert_int_1(struct udl_softc *, uint8_t);
+void udl_cmd_insert_int_2(struct udl_softc *, uint16_t);
+void udl_cmd_insert_int_3(struct udl_softc *, uint32_t);
+void udl_cmd_insert_int_4(struct udl_softc *, uint32_t);
+void udl_cmd_insert_buf(struct udl_softc *, uint8_t *, uint32_t);
+void udl_cmd_insert_check(struct udl_cmd_buf *, int);
+void udl_cmd_write_reg_1(struct udl_softc *, uint8_t, uint8_t);
+void udl_cmd_write_reg_3(struct udl_softc *, uint8_t, uint32_t);
+usbd_status udl_cmd_send(struct udl_softc *);
+usbd_status udl_cmd_send_async(struct udl_softc *);
+void udl_cmd_send_async_cb(usbd_xfer_handle, usbd_private_handle,
+ usbd_status);
+
+usbd_status udl_init_chip(struct udl_softc *);
+void udl_init_fb_offsets(struct udl_softc *, uint32_t, uint32_t,
+ uint32_t, uint32_t);
+usbd_status udl_init_resolution(struct udl_softc *, uint8_t *, uint8_t);
+void udl_fb_off_write(struct udl_softc *, uint16_t, uint32_t,
+ uint8_t);
+void udl_fb_pos_write(struct udl_softc *, uint16_t, uint32_t,
+ uint32_t, uint32_t);
+void udl_fb_blk_write(struct udl_softc *, uint16_t, uint32_t,
+ uint32_t, uint32_t, uint32_t);
+void udl_fb_off_copy(struct udl_softc *, uint32_t, uint32_t,
+ uint8_t);
+void udl_fb_pos_copy(struct udl_softc *, uint32_t, uint32_t,
+ uint32_t, uint32_t, uint32_t);
+void udl_fb_blk_copy(struct udl_softc *, uint32_t, uint32_t,
+ uint32_t, uint32_t, uint32_t, uint32_t);
+void udl_draw_char(struct udl_softc *, uint32_t, uint32_t,
+ uint16_t, uint16_t, u_int);
+#ifdef UDL_DEBUG
+void udl_hexdump(void *, int, int);
+usbd_status udl_init_test(struct udl_softc *);
+#endif
+
+/*
+ * Driver glue.
+ */
+struct cfdriver udl_cd = {
+ NULL, "udl", DV_DULL
+};
+
+const struct cfattach udl_ca = {
+ sizeof(struct udl_softc),
+ udl_match,
+ udl_attach,
+ udl_detach,
+ udl_activate
+};
+
+/*
+ * wsdisplay glue.
+ */
+struct wsscreen_descr udl_stdscreen = {
+ "std", /* name */
+ 0, 0, /* ncols, nrows */
+ NULL, /* textops */
+ 0, 0, /* fontwidth, fontheight */
+ WSSCREEN_WSCOLORS /* capabilities */
+};
+
+const struct wsscreen_descr *udl_scrlist[] = {
+ &udl_stdscreen
+};
+
+struct wsscreen_list udl_screenlist = {
+ sizeof(udl_scrlist) / sizeof(struct wsscreen_descr *), udl_scrlist
+};
+
+struct wsdisplay_accessops udl_accessops = {
+ udl_ioctl,
+ udl_mmap,
+ udl_alloc_screen,
+ udl_free_screen,
+ udl_show_screen,
+ NULL,
+ NULL,
+ NULL,
+ udl_burner
+};
+
+/*
+ * Matching devices.
+ */
+static const struct usb_devno udl_devs[] = {
+ { USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_DL120 }
+};
+
+int
+udl_match(struct device *parent, void *match, void *aux)
+{
+ struct usb_attach_arg *uaa = aux;
+
+ if (uaa->iface != NULL)
+ return (UMATCH_NONE);
+
+ if (usb_lookup(udl_devs, uaa->vendor, uaa->product) != NULL)
+ return (UMATCH_VENDOR_PRODUCT);
+
+ return (UMATCH_NONE);
+}
+
+void
+udl_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct udl_softc *sc = (struct udl_softc *)self;
+ struct usb_attach_arg *uaa = aux;
+ struct wsemuldisplaydev_attach_args aa;
+ usbd_status error;
+ int err;
+
+ sc->sc_udev = uaa->device;
+
+ /*
+ * Set device configuration descriptor number.
+ */
+ error = usbd_set_config_no(sc->sc_udev, 1, 0);
+ if (error != USBD_NORMAL_COMPLETION)
+ return;
+
+ /*
+ * Create device handle to interface descriptor.
+ */
+ error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
+ if (error != USBD_NORMAL_COMPLETION)
+ return;
+
+ /*
+ * Allocate bulk command xfer.
+ */
+ error = udl_cmd_alloc_xfer(sc);
+ if (error != USBD_NORMAL_COMPLETION)
+ return;
+
+ /*
+ * Allocate command buffer.
+ */
+ err = udl_cmd_alloc_buf(sc);
+ if (err != 0)
+ return;
+
+ /*
+ * Open bulk TX pipe.
+ */
+ error = usbd_open_pipe(sc->sc_iface, 0x01, USBD_EXCLUSIVE_USE,
+ &sc->sc_tx_pipeh);
+ if (error != USBD_NORMAL_COMPLETION)
+ return;
+
+ /*
+ * Initialize chip.
+ */
+ error = udl_init_chip(sc);
+ if (error != USBD_NORMAL_COMPLETION)
+ return;
+
+ /*
+ * Initialize resolution.
+ */
+ sc->sc_width = 800; /* XXX shouldn't we do this somewhere else? */
+ sc->sc_height = 600;
+ sc->sc_depth = 16;
+
+ error = udl_init_resolution(sc, udl_reg_vals_800,
+ sizeof(udl_reg_vals_800));
+ if (error != USBD_NORMAL_COMPLETION)
+ return;
+
+ /*
+ * Attach wsdisplay.
+ */
+ aa.console = 0;
+ aa.scrdata = &udl_screenlist;
+ aa.accessops = &udl_accessops;
+ aa.accesscookie = sc;
+ aa.defaultscreens = 0;
+
+ sc->sc_wsdisplay = config_found(self, &aa, wsemuldisplaydevprint);
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, &sc->sc_dev);
+}
+
+int
+udl_detach(struct device *self, int flags)
+{
+ struct udl_softc *sc = (struct udl_softc *)self;
+
+ /*
+ * Close bulk TX pipe.
+ */
+ if (sc->sc_tx_pipeh != NULL) {
+ usbd_abort_pipe(sc->sc_tx_pipeh);
+ usbd_close_pipe(sc->sc_tx_pipeh);
+ }
+
+ /*
+ * Free command buffer.
+ */
+ udl_cmd_free_buf(sc);
+
+ /*
+ * Free command xfer.
+ */
+ udl_cmd_free_xfer(sc);
+
+ /*
+ * Detach wsdisplay.
+ */
+ if (sc->sc_wsdisplay != NULL)
+ config_detach(sc->sc_wsdisplay, DETACH_FORCE);
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, &sc->sc_dev);
+
+ return (0);
+}
+
+int
+udl_activate(struct device *self, enum devact act)
+{
+ switch (act) {
+ case DVACT_ACTIVATE:
+ return (EOPNOTSUPP);
+ case DVACT_DEACTIVATE:
+ break;
+ }
+
+ return (0);
+}
+
+/* ---------- */
+
+int
+udl_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct udl_softc *sc;
+
+ sc = v;
+
+ DPRINTF(1, "%s: %s\n", DN(sc), FUNC);
+
+ /* TODO */
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_DL;
+ break;
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+paddr_t
+udl_mmap(void *v, off_t off, int prot)
+{
+ struct udl_softc *sc;
+
+ sc = v;
+
+ DPRINTF(1, "%s: %s\n", DN(sc), FUNC);
+
+ return (NULL);
+}
+
+int
+udl_alloc_screen(void *v, const struct wsscreen_descr *type,
+ void **cookiep, int *curxp, int *curyp, long *attrp)
+{
+ struct udl_softc *sc = v;
+ struct wsdisplay_font *font;
+
+ DPRINTF(1, "%s: %s\n", DN(sc), FUNC);
+
+ if (sc->sc_nscreens > 0)
+ return (ENOMEM);
+
+ /*
+ * Initialize rasops.
+ */
+ sc->sc_ri.ri_depth = sc->sc_depth;
+ sc->sc_ri.ri_bits = NULL;
+ sc->sc_ri.ri_width = sc->sc_width;
+ sc->sc_ri.ri_height = sc->sc_height;
+ sc->sc_ri.ri_stride = sc->sc_width * sc->sc_height / 8;
+ sc->sc_ri.ri_hw = (void *)sc;
+ sc->sc_ri.ri_flg = 0;
+
+ /* swap B and R at 16 bpp */
+ if (sc->sc_depth == 16) {
+ sc->sc_ri.ri_rnum = 5;
+ sc->sc_ri.ri_rpos = 11;
+ sc->sc_ri.ri_gnum = 6;
+ sc->sc_ri.ri_gpos = 5;
+ sc->sc_ri.ri_bnum = 5;
+ sc->sc_ri.ri_bpos = 0;
+ }
+
+ rasops_init(&sc->sc_ri, 100, 100);
+
+ sc->sc_ri.ri_ops.copycols = udl_copycols;
+ sc->sc_ri.ri_ops.copyrows = udl_copyrows;
+ sc->sc_ri.ri_ops.erasecols = udl_erasecols;
+ sc->sc_ri.ri_ops.eraserows = udl_eraserows;
+ sc->sc_ri.ri_ops.putchar = udl_putchar;
+ sc->sc_ri.ri_do_cursor = udl_do_cursor;
+
+ sc->sc_ri.ri_ops.alloc_attr(&sc->sc_ri, 0, 0, 0, attrp);
+
+ udl_stdscreen.nrows = sc->sc_ri.ri_rows;
+ udl_stdscreen.ncols = sc->sc_ri.ri_cols;
+ udl_stdscreen.textops = &sc->sc_ri.ri_ops;
+ udl_stdscreen.fontwidth = sc->sc_ri.ri_font->fontwidth;
+ udl_stdscreen.fontheight = sc->sc_ri.ri_font->fontheight;
+ udl_stdscreen.capabilities = sc->sc_ri.ri_caps;
+
+ *cookiep = &sc->sc_ri;
+ *curxp = 0;
+ *curyp = 0;
+
+ sc->sc_nscreens++;
+
+ font = sc->sc_ri.ri_font;
+ DPRINTF(1, "%s: %s: using font %s (%dx%d)\n",
+ DN(sc), FUNC, font->name, sc->sc_ri.ri_cols, sc->sc_ri.ri_rows);
+
+ return (0);
+}
+
+void
+udl_free_screen(void *v, void *cookie)
+{
+ struct udl_softc *sc;
+
+ sc = v;
+
+ DPRINTF(1, "%s: %s\n", DN(sc), FUNC);
+}
+
+int
+udl_show_screen(void *v, void *cookie, int waitok,
+ void (*cb)(void *, int, int), void *cbarg)
+{
+ struct udl_softc *sc;
+
+ sc = v;
+
+ DPRINTF(1, "%s: %s\n", DN(sc), FUNC);
+
+ return (0);
+}
+
+void
+udl_burner(void *v, u_int on, u_int flags)
+{
+ struct udl_softc *sc;
+
+ sc = v;
+
+ DPRINTF(1, "%s: %s: %s\n", DN(sc), FUNC, on ? "on" : "off");
+
+ if (on)
+ udl_cmd_write_reg_1(sc, UDL_REG_BLANK_SCREEN, 0x01);
+ else
+ udl_cmd_write_reg_1(sc, UDL_REG_BLANK_SCREEN, 0x00);
+
+ udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0xff);
+
+ (void)udl_cmd_send(sc);
+}
+
+/* ---------- */
+
+void
+udl_copycols(void *cookie, int row, int src, int dst, int num)
+{
+ struct rasops_info *ri = cookie;
+ struct udl_softc *sc;
+ int sx, sy, dx, dy, cx, cy;
+
+ sc = ri->ri_hw;
+
+ DPRINTF(2, "%s: %s: row=%d, src=%d, dst=%d, num=%d\n",
+ DN(sc), FUNC, row, src, dst, num);
+
+ sx = src * ri->ri_font->fontwidth;
+ sy = row * ri->ri_font->fontheight;
+ dx = dst * ri->ri_font->fontwidth;
+ dy = row * ri->ri_font->fontheight;
+ cx = num * ri->ri_font->fontwidth;
+ cy = ri->ri_font->fontheight;
+
+ udl_fb_blk_copy(sc, sx, sy, dx, dy, cx, cy);
+
+ (void)udl_cmd_send_async(sc);
+}
+
+void
+udl_copyrows(void *cookie, int src, int dst, int num)
+{
+ struct rasops_info *ri = cookie;
+ struct udl_softc *sc;
+ int sy, dy, cx, cy;
+
+ sc = ri->ri_hw;
+
+ DPRINTF(2, "%s: %s: src=%d, dst=%d, num=%d\n",
+ DN(sc), FUNC, src, dst, num);
+
+ sy = src * sc->sc_ri.ri_font->fontheight;
+ dy = dst * sc->sc_ri.ri_font->fontheight;
+ cx = sc->sc_ri.ri_emuwidth;
+ cy = num * sc->sc_ri.ri_font->fontheight;
+
+ /* copy row block to off-screen first to fix overlay-copy problem */
+ udl_fb_blk_copy(sc, 0, sy, 0, sc->sc_ri.ri_emuheight, cx, cy);
+
+ /* copy row block back from off-screen now */
+ udl_fb_blk_copy(sc, 0, sc->sc_ri.ri_emuheight, 0, dy, cx, cy);
+
+ (void)udl_cmd_send_async(sc);
+}
+
+void
+udl_erasecols(void *cookie, int row, int col, int num, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct udl_softc *sc = ri->ri_hw;
+ int fg, bg;
+ int x, y, cx, cy;
+
+ sc = ri->ri_hw;
+
+ DPRINTF(2, "%s: %s: row=%d, col=%d, num=%d\n",
+ DN(sc), FUNC, row, col, num);
+
+ sc->sc_ri.ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
+
+ x = col * sc->sc_ri.ri_font->fontwidth;
+ y = row * sc->sc_ri.ri_font->fontheight;
+ cx = num * sc->sc_ri.ri_font->fontwidth;
+ cy = sc->sc_ri.ri_font->fontheight;
+
+ udl_fb_blk_write(sc, 0x0000, x, y, cx, cy);
+
+ (void)udl_cmd_send_async(sc);
+}
+
+void
+udl_eraserows(void *cookie, int row, int num, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct udl_softc *sc;
+ int x, y, cx, cy;
+
+ sc = ri->ri_hw;
+
+ DPRINTF(2, "%s: %s: row=%d, num=%d\n", DN(sc), FUNC, row, num);
+
+ x = 0;
+ y = row * sc->sc_ri.ri_font->fontheight;
+ cx = sc->sc_ri.ri_emuwidth;
+ cy = num * sc->sc_ri.ri_font->fontheight;
+
+ udl_fb_blk_write(sc, 0x0000, x, y, cx, cy);
+
+ (void)udl_cmd_send_async(sc);
+}
+
+void
+udl_putchar(void *cookie, int row, int col, u_int uc, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct udl_softc *sc = ri->ri_hw;
+ uint16_t fgc, bgc;
+ uint32_t x, y, fg, bg;
+
+ DPRINTF(2, "%s: %s\n", DN(sc), FUNC);
+
+ sc->sc_ri.ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
+ fgc = (uint16_t)sc->sc_ri.ri_devcmap[fg];
+ bgc = (uint16_t)sc->sc_ri.ri_devcmap[bg];
+
+ x = col * ri->ri_font->fontwidth;
+ y = row * ri->ri_font->fontheight;
+
+ if (uc == ' ') {
+ /*
+ * Writting a block for the space character instead rendering
+ * it from font bits is more slim.
+ */
+ udl_fb_blk_write(sc, bgc, x, y,
+ ri->ri_font->fontwidth, ri->ri_font->fontheight);
+ } else {
+ /* render a character from font bits */
+ udl_draw_char(sc, x, y, fgc, bgc, uc);
+ }
+
+ /*
+ * We don't call udl_cmd_send_async() here, since sending each
+ * character by itself gets the performance down bad. Instead the
+ * character will be buffered until another rasops function flush
+ * the buffer.
+ */
+}
+
+void
+udl_do_cursor(struct rasops_info *ri)
+{
+ struct udl_softc *sc = ri->ri_hw;
+ uint32_t x, y;
+
+ DPRINTF(2, "%s: %s: ccol=%d, crow=%d\n",
+ DN(sc), FUNC, ri->ri_ccol, ri->ri_crow);
+
+ x = ri->ri_ccol * ri->ri_font->fontwidth;
+ y = ri->ri_crow * ri->ri_font->fontheight;
+
+ if (sc->sc_cursor_on == 0) {
+ /* safe the last character block to off-screen */
+ udl_fb_blk_copy(sc, x, y, 0, sc->sc_ri.ri_emuheight,
+ ri->ri_font->fontwidth, ri->ri_font->fontheight);
+
+ /* draw cursor */
+ udl_fb_blk_write(sc, 0xffff, x, y,
+ ri->ri_font->fontwidth, ri->ri_font->fontheight);
+
+ sc->sc_cursor_on = 1;
+ } else {
+ /* restore the last safed character from off-screen */
+ udl_fb_blk_copy(sc, 0, sc->sc_ri.ri_emuheight, x, y,
+ ri->ri_font->fontwidth, ri->ri_font->fontheight);
+
+ sc->sc_cursor_on = 0;
+ }
+
+ (void)udl_cmd_send_async(sc);
+}
+
+/* ---------- */
+
+usbd_status
+udl_ctrl_msg(struct udl_softc *sc, uint8_t rt, uint8_t r,
+ uint16_t index, uint16_t value, uint8_t *buf, size_t len)
+{
+ usb_device_request_t req;
+ usbd_status error;
+
+ req.bmRequestType = rt;
+ req.bRequest = r;
+ USETW(req.wIndex, index);
+ USETW(req.wValue, value);
+ USETW(req.wLength, len);
+
+ error = usbd_do_request(sc->sc_udev, &req, buf);
+ if (error != USBD_NORMAL_COMPLETION) {
+ printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error));
+ return (error);
+ }
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+usbd_status
+udl_poll(struct udl_softc *sc, uint32_t *buf)
+{
+ uint8_t lbuf[4];
+ usbd_status error;
+
+ error = udl_ctrl_msg(sc, UT_READ_VENDOR_DEVICE,
+ UDL_CTRL_CMD_POLL, 0x0000, 0x0000, lbuf, 4);
+ if (error != USBD_NORMAL_COMPLETION) {
+ printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error));
+ return (error);
+ }
+ *buf = *(uint32_t *)lbuf;
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+usbd_status
+udl_read_1(struct udl_softc *sc, uint16_t addr, uint8_t *buf)
+{
+ uint8_t lbuf[1];
+ usbd_status error;
+
+ error = udl_ctrl_msg(sc, UT_READ_VENDOR_DEVICE,
+ UDL_CTRL_CMD_READ_1, addr, 0x0000, lbuf, 1);
+ if (error != USBD_NORMAL_COMPLETION) {
+ printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error));
+ return (error);
+ }
+ *buf = *(uint8_t *)lbuf;
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+usbd_status
+udl_write_1(struct udl_softc *sc, uint16_t addr, uint8_t buf)
+{
+ usbd_status error;
+
+ error = udl_ctrl_msg(sc, UT_WRITE_VENDOR_DEVICE,
+ UDL_CTRL_CMD_WRITE_1, addr, 0x0000, &buf, 1);
+ if (error != USBD_NORMAL_COMPLETION) {
+ printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error));
+ return (error);
+ }
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+usbd_status
+udl_read_edid(struct udl_softc *sc, uint8_t *buf)
+{
+ uint8_t lbuf[64];
+ uint16_t offset;
+ usbd_status error;
+
+ offset = 0;
+
+ error = udl_ctrl_msg(sc, UT_READ_VENDOR_DEVICE,
+ UDL_CTRL_CMD_READ_EDID, 0x00a1, (offset << 8), lbuf, 64);
+ if (error != USBD_NORMAL_COMPLETION)
+ goto fail;
+ bcopy(lbuf + 1, buf + offset, 63);
+ offset += 63;
+
+ error = udl_ctrl_msg(sc, UT_READ_VENDOR_DEVICE,
+ UDL_CTRL_CMD_READ_EDID, 0x00a1, (offset << 8), lbuf, 64);
+ if (error != USBD_NORMAL_COMPLETION)
+ goto fail;
+ bcopy(lbuf + 1, buf + offset, 63);
+ offset += 63;
+
+ error = udl_ctrl_msg(sc, UT_READ_VENDOR_DEVICE,
+ UDL_CTRL_CMD_READ_EDID, 0x00a1, (offset << 8), lbuf, 3);
+ if (error != USBD_NORMAL_COMPLETION)
+ goto fail;
+ bcopy(lbuf + 1, buf + offset, 2);
+
+ return (USBD_NORMAL_COMPLETION);
+fail:
+ printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error));
+ return (error);
+}
+
+usbd_status
+udl_set_enc_key(struct udl_softc *sc, uint8_t *buf, uint8_t len)
+{
+ usbd_status error;
+
+ error = udl_ctrl_msg(sc, UT_WRITE_VENDOR_DEVICE,
+ UDL_CTRL_CMD_SET_KEY, 0x0000, 0x0000, buf, len);
+ if (error != USBD_NORMAL_COMPLETION) {
+ printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error));
+ return (error);
+ }
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+usbd_status
+udl_set_decomp_table(struct udl_softc *sc, uint8_t *buf, uint16_t len)
+{
+ int err;
+
+ udl_cmd_insert_int_1(sc, UDL_BULK_SOC);
+ udl_cmd_insert_int_1(sc, UDL_BULK_CMD_DECOMP);
+ udl_cmd_insert_int_4(sc, 0x263871cd); /* magic number */
+ udl_cmd_insert_int_4(sc, 0x00000200); /* 512 byte chunks */
+ udl_cmd_insert_buf(sc, buf, len);
+
+ err = udl_cmd_send(sc);
+ if (err != 0)
+ return (USBD_INVAL);
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+/* ---------- */
+
+usbd_status
+udl_cmd_alloc_xfer(struct udl_softc *sc)
+{
+ int i;
+
+ for (i = 0; i < UDL_CMD_XFER_COUNT; i++) {
+ struct udl_cmd_xfer *cx = &sc->sc_cmd_xfer[i];
+
+ cx->sc = sc;
+
+ cx->xfer = usbd_alloc_xfer(sc->sc_udev);
+ if (cx->xfer == NULL) {
+ printf("%s: %s: can't allocate xfer handle!\n",
+ DN(sc), FUNC);
+ return (USBD_NOMEM);
+ }
+
+ cx->buf = usbd_alloc_buffer(cx->xfer, UDL_CMD_MAX_XFER_SIZE);
+ if (cx->buf == NULL) {
+ printf("%s: %s: can't allocate xfer buffer!\n",
+ DN(sc), FUNC);
+ return (USBD_NOMEM);
+ }
+ }
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+void
+udl_cmd_free_xfer(struct udl_softc *sc)
+{
+ int i;
+
+ for (i = 0; i < UDL_CMD_XFER_COUNT; i++) {
+ struct udl_cmd_xfer *cx = &sc->sc_cmd_xfer[i];
+
+ if (cx->xfer != NULL) {
+ usbd_free_xfer(cx->xfer);
+ cx->xfer = NULL;
+ }
+ }
+}
+
+int
+udl_cmd_alloc_buf(struct udl_softc *sc)
+{
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
+
+ cb->buf = malloc(UDL_CMD_MAX_XFER_SIZE, M_DEVBUF, 0);
+ if (cb->buf == NULL) {
+ printf("%s: %s: can't allocate buffer!\n",
+ DN(sc), FUNC);
+ return (ENOMEM);
+ }
+ cb->off = 0;
+
+ return (0);
+}
+
+void
+udl_cmd_free_buf(struct udl_softc *sc)
+{
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
+
+ free(cb->buf, M_DEVBUF);
+ cb->off = 0;
+}
+
+void
+udl_cmd_insert_int_1(struct udl_softc *sc, uint8_t value)
+{
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
+
+ udl_cmd_insert_check(cb, 1);
+
+ cb->buf[cb->off] = value;
+
+ cb->off += 1;
+}
+
+void
+udl_cmd_insert_int_2(struct udl_softc *sc, uint16_t value)
+{
+ uint16_t lvalue;
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
+
+ udl_cmd_insert_check(cb, 2);
+
+ lvalue = htobe16(value);
+ bcopy(&lvalue, cb->buf + cb->off, 2);
+
+ cb->off += 2;
+}
+
+void
+udl_cmd_insert_int_3(struct udl_softc *sc, uint32_t value)
+{
+ uint32_t lvalue;
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
+
+ udl_cmd_insert_check(cb, 3);
+#if BYTE_ORDER == BIG_ENDIAN
+ lvalue = htobe32(value) << 8;
+#else
+ lvalue = htobe32(value) >> 8;
+#endif
+ bcopy(&lvalue, cb->buf + cb->off, 3);
+
+ cb->off += 3;
+}
+
+void
+udl_cmd_insert_int_4(struct udl_softc *sc, uint32_t value)
+{
+ uint32_t lvalue;
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
+
+ udl_cmd_insert_check(cb, 4);
+
+ lvalue = htobe32(value);
+ bcopy(&lvalue, cb->buf + cb->off, 4);
+
+ cb->off += 4;
+}
+
+void
+udl_cmd_insert_buf(struct udl_softc *sc, uint8_t *buf, uint32_t len)
+{
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
+
+ udl_cmd_insert_check(cb, len);
+
+ bcopy(buf, cb->buf + cb->off, len);
+
+ cb->off += len;
+}
+
+void
+udl_cmd_insert_check(struct udl_cmd_buf *cb, int len)
+{
+ int total;
+
+ total = cb->off + len;
+
+ if (total >= UDL_CMD_MAX_XFER_SIZE) {
+ /* XXX */
+ panic("udl_cmd_insert_check: command buffer is full");
+ }
+}
+
+void
+udl_cmd_write_reg_1(struct udl_softc *sc, uint8_t reg, uint8_t val)
+{
+ udl_cmd_insert_int_1(sc, UDL_BULK_SOC);
+ udl_cmd_insert_int_1(sc, UDL_BULK_CMD_REG_WRITE_1);
+ udl_cmd_insert_int_1(sc, reg);
+ udl_cmd_insert_int_1(sc, val);
+}
+
+void
+udl_cmd_write_reg_3(struct udl_softc *sc, uint8_t reg, uint32_t val)
+{
+ udl_cmd_write_reg_1(sc, reg + 0, (val >> 16) & 0xff);
+ udl_cmd_write_reg_1(sc, reg + 1, (val >> 8) & 0xff);
+ udl_cmd_write_reg_1(sc, reg + 2, (val >> 0) & 0xff);
+}
+
+usbd_status
+udl_cmd_send(struct udl_softc *sc)
+{
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
+ struct udl_cmd_xfer *cx = &sc->sc_cmd_xfer[0];
+ int len;
+ usbd_status error;
+
+ /* mark end of command stack */
+ udl_cmd_insert_int_1(sc, UDL_BULK_SOC);
+ udl_cmd_insert_int_1(sc, UDL_BULK_CMD_EOC);
+
+ bcopy(cb->buf, cx->buf, cb->off);
+
+ len = cb->off;
+ error = usbd_bulk_transfer(cx->xfer, sc->sc_tx_pipeh,
+ USBD_NO_COPY | USBD_SHORT_XFER_OK, 1000, cx->buf, &len,
+ "udl_bulk_xmit");
+ if (error != USBD_NORMAL_COMPLETION) {
+ printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error));
+ /* we clear our buffer now to avoid growing out of bounds */
+ goto fail;
+ }
+ DPRINTF(1, "%s: %s: sent %d of %d bytes\n",
+ DN(sc), FUNC, len, cb->off);
+fail:
+ cb->off = 0;
+
+ return (error);
+}
+
+usbd_status
+udl_cmd_send_async(struct udl_softc *sc)
+{
+ struct udl_cmd_buf *cb = &sc->sc_cmd_buf;
+ struct udl_cmd_xfer *cx;
+ usbd_status error;
+ int i, s;
+
+ /* if the ring buffer is full, wait until it's flushed completely */
+ if (sc->sc_cmd_xfer_cnt == UDL_CMD_XFER_COUNT) {
+ DPRINTF(1, "%s: %s: ring buffer full, wait until flushed\n",
+ DN(sc), FUNC);
+ /*
+ * XXX
+ * Yes, this is ugly. But since we can't tsleep() here, I
+ * have no better idea how we can delay rasops so it doesn't
+ * blow up our command buffer.
+ */
+ while (sc->sc_cmd_xfer_cnt > 0)
+ delay(100);
+ }
+
+ s = splusb(); /* no callbacks please until accounting is done */
+
+ /* find a free ring buffer */
+ for (i = 0; i < UDL_CMD_XFER_COUNT; i++) {
+ if (sc->sc_cmd_xfer[i].busy == 0)
+ break;
+ }
+ if (i == UDL_CMD_XFER_COUNT) {
+ /* XXX this shouldn't happen */
+ panic("udl_cmd_send_async: buffer full");
+ }
+ cx = &sc->sc_cmd_xfer[i];
+
+ /* copy command buffer to xfer buffer */
+ bcopy(cb->buf, cx->buf, cb->off);
+
+ /* do xfer */
+ usbd_setup_xfer(cx->xfer, sc->sc_tx_pipeh, cx, cx->buf, cb->off,
+ USBD_NO_COPY, 1000, udl_cmd_send_async_cb);
+ error = usbd_transfer(cx->xfer);
+ if (error != 0 && error != USBD_IN_PROGRESS) {
+ printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error));
+ return (error);
+ }
+ DPRINTF(1, "%s: %s: sending %d bytes from buffer no. %d\n",
+ DN(sc), FUNC, cb->off, i);
+
+ /* free command buffer, lock xfer buffer */
+ cb->off = 0;
+ cx->busy = 1;
+ sc->sc_cmd_xfer_cnt++;
+
+ splx(s);
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+void
+udl_cmd_send_async_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
+ usbd_status status)
+{
+ struct udl_cmd_xfer *cx = priv;
+ struct udl_softc *sc = cx->sc;
+ int len;
+
+ if (status != USBD_NORMAL_COMPLETION) {
+ printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(status));
+
+ if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
+ return;
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sc->sc_tx_pipeh);
+ goto skip;
+ }
+ usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
+
+ DPRINTF(1, "%s: %s: sent %d bytes\n", DN(sc), FUNC, len);
+skip:
+ /* free xfer buffer */
+ cx->busy = 0;
+ sc->sc_cmd_xfer_cnt--;
+}
+
+/* ---------- */
+
+usbd_status
+udl_init_chip(struct udl_softc *sc)
+{
+ uint8_t ui8;
+ uint32_t ui32;
+ int8_t edid[128];
+ usbd_status error;
+
+ error = udl_poll(sc, &ui32);
+ if (error != USBD_NORMAL_COMPLETION)
+ return (error);
+ DPRINTF(1, "%s: %s: poll=0x%08x\n", DN(sc), FUNC, ui32);
+
+ error = udl_read_1(sc, 0xc484, &ui8);
+ if (error != USBD_NORMAL_COMPLETION)
+ return (error);
+ DPRINTF(1, "%s: %s: read 0x%02x from 0xc484\n", DN(sc), FUNC, ui8);
+
+ error = udl_write_1(sc, 0xc41f, 0x01);
+ if (error != USBD_NORMAL_COMPLETION)
+ return (error);
+ DPRINTF(1, "%s: %s: write 0x01 to 0xc41f\n", DN(sc), FUNC);
+
+ error = udl_read_edid(sc, edid);
+ if (error != USBD_NORMAL_COMPLETION)
+ return (error);
+ DPRINTF(1, "%s: %s: read EDID=\n", DN(sc), FUNC);
+#ifdef UDL_DEBUG
+ udl_hexdump(edid, sizeof(edid), 0);
+#endif
+ error = udl_set_enc_key(sc, udl_null_key_1, sizeof(udl_null_key_1));
+ if (error != USBD_NORMAL_COMPLETION)
+ return (error);
+ DPRINTF(1, "%s: %s: set encryption key\n", DN(sc), FUNC);
+
+ error = udl_write_1(sc, 0xc40b, 0x00);
+ if (error != USBD_NORMAL_COMPLETION)
+ return (error);
+ DPRINTF(1, "%s: %s: write 0x00 to 0xc40b\n", DN(sc), FUNC, ui8);
+
+ error = udl_set_decomp_table(sc, udl_decomp_table,
+ sizeof(udl_decomp_table));
+ if (error != USBD_NORMAL_COMPLETION)
+ return (error);
+ DPRINTF(1, "%s: %s: set decompression table\n", DN(sc), FUNC);
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+void
+udl_init_fb_offsets(struct udl_softc *sc, uint32_t start16, uint32_t stride16,
+ uint32_t start8, uint32_t stride8)
+{
+ udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0x00);
+ udl_cmd_write_reg_3(sc, UDL_REG_ADDR_START16, start16);
+ udl_cmd_write_reg_3(sc, UDL_REG_ADDR_STRIDE16, stride16);
+ udl_cmd_write_reg_3(sc, UDL_REG_ADDR_START8, start8);
+ udl_cmd_write_reg_3(sc, UDL_REG_ADDR_STRIDE8, stride8);
+ udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0xff);
+}
+
+usbd_status
+udl_init_resolution(struct udl_softc *sc, uint8_t *buf, uint8_t len)
+{
+ int i;
+ usbd_status error;
+
+ /* write resolution values and set video memory offsets */
+ udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0x00);
+ for (i = 0; i < len; i++)
+ udl_cmd_write_reg_1(sc, i, buf[i]);
+ udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0xff);
+
+ udl_init_fb_offsets(sc, 0x000000, 0x000a00, 0x555555, 0x000500);
+ error = udl_cmd_send(sc);
+ if (error != USBD_NORMAL_COMPLETION)
+ return (error);
+
+ /* clear screen */
+ udl_fb_blk_write(sc, 0x0000, 0, 0, sc->sc_width, sc->sc_height);
+ error = udl_cmd_send(sc);
+ if (error != USBD_NORMAL_COMPLETION)
+ return (error);
+
+ /* show framebuffer content */
+ udl_cmd_write_reg_1(sc, UDL_REG_BLANK_SCREEN, 0x00);
+ udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0xff);
+ error = udl_cmd_send(sc);
+ if (error != USBD_NORMAL_COMPLETION)
+ return (error);
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+void
+udl_fb_off_write(struct udl_softc *sc, uint16_t rgb16, uint32_t off,
+ uint8_t width)
+{
+ uint8_t buf[UDL_CMD_MAX_DATA_SIZE];
+ uint16_t lwidth, lrgb16;
+ uint32_t loff;
+ int i;
+
+ loff = off * 2;
+ lwidth = width * 2;
+
+ udl_cmd_insert_int_1(sc, UDL_BULK_SOC);
+ udl_cmd_insert_int_1(sc, UDL_BULK_CMD_FB_WRITE | UDL_BULK_CMD_FB_WORD);
+ udl_cmd_insert_int_3(sc, loff);
+ udl_cmd_insert_int_1(sc, width);
+
+ for (i = 0; i < lwidth; i += 2) {
+ lrgb16 = htobe16(rgb16);
+ bcopy(&lrgb16, buf + i, 2);
+ }
+
+ udl_cmd_insert_buf(sc, buf, lwidth);
+}
+
+void
+udl_fb_pos_write(struct udl_softc *sc, uint16_t rgb16, uint32_t x,
+ uint32_t y, uint32_t width)
+{
+ uint32_t off, block;
+
+ off = (y * sc->sc_width) + x;
+
+ while (width) {
+ if (width > UDL_CMD_MAX_PIXEL_COUNT)
+ block = UDL_CMD_MAX_PIXEL_COUNT;
+ else
+ block = width;
+
+ udl_fb_off_write(sc, rgb16, off, block);
+
+ off += block;
+ width -= block;
+ }
+}
+
+void
+udl_fb_blk_write(struct udl_softc *sc, uint16_t rgb16, uint32_t x,
+ uint32_t y, uint32_t width, uint32_t height)
+{
+ uint32_t i;
+
+ for (i = 0; i < height; i++)
+ udl_fb_pos_write(sc, rgb16, x, y + i, width);
+}
+
+void
+udl_fb_off_copy(struct udl_softc *sc, uint32_t src_off, uint32_t dst_off,
+ uint8_t width)
+{
+ uint32_t ldst_off, lsrc_off;
+
+ ldst_off = dst_off * 2;
+ lsrc_off = src_off * 2;
+
+ udl_cmd_insert_int_1(sc, UDL_BULK_SOC);
+ udl_cmd_insert_int_1(sc, UDL_BULK_CMD_FB_COPY | UDL_BULK_CMD_FB_WORD);
+ udl_cmd_insert_int_3(sc, ldst_off);
+ udl_cmd_insert_int_1(sc, width);
+ udl_cmd_insert_int_3(sc, lsrc_off);
+}
+
+void
+udl_fb_pos_copy(struct udl_softc *sc, uint32_t src_x, uint32_t src_y,
+ uint32_t dst_x, uint32_t dst_y, uint32_t width)
+{
+ uint32_t src_off, dst_off, block;
+
+ src_off = (src_y * sc->sc_width) + src_x;
+ dst_off = (dst_y * sc->sc_width) + dst_x;
+
+ while (width) {
+ if (width > UDL_CMD_MAX_PIXEL_COUNT)
+ block = UDL_CMD_MAX_PIXEL_COUNT;
+ else
+ block = width;
+
+ udl_fb_off_copy(sc, src_off, dst_off, block);
+
+ src_off += block;
+ dst_off += block;
+ width -= block;
+ }
+}
+
+void
+udl_fb_blk_copy(struct udl_softc *sc, uint32_t src_x, uint32_t src_y,
+ uint32_t dst_x, uint32_t dst_y, uint32_t width, uint32_t height)
+{
+ int i;
+
+ for (i = 0; i < height; i++)
+ udl_fb_pos_copy(sc, src_x, src_y + i, dst_x, dst_y + i, width);
+}
+
+void
+udl_draw_char(struct udl_softc *sc, uint32_t x, uint32_t y,
+ uint16_t fg, uint16_t bg, u_int uc)
+{
+ int i, j, lx, ly;
+ uint8_t *fontchar, fontbits, luc;
+ struct wsdisplay_font *font = sc->sc_ri.ri_font;
+
+ /* draw the characters background first */
+ udl_fb_blk_write(sc, bg, x, y, font->fontwidth, font->fontheight);
+
+ fontchar = (uint8_t *)(font->data + (uc - font->firstchar) *
+ sc->sc_ri.ri_fontscale);
+
+ lx = x;
+ ly = y;
+ for (i = 0; i < font->fontheight; i++) {
+ fontbits = *fontchar;
+
+ for (j = 7; j != -1; j--) {
+ luc = 1 << j;
+ if (fontbits & luc)
+ udl_fb_pos_write(sc, fg, lx, ly, 1);
+ lx++;
+ }
+ lx = x;
+ ly++;
+
+ fontchar += font->stride;
+ }
+}
+
+/* ---------- */
+#ifdef UDL_DEBUG
+void
+udl_hexdump(void *buf, int len, int quiet)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (quiet == 0) {
+ if (i % 16 == 0)
+ printf("%s%5i:", i ? "\n" : "", i);
+ if (i % 4 == 0)
+ printf(" ");
+ }
+ printf("%02x", (int)*((u_char *)buf + i));
+ }
+ printf("\n");
+}
+
+usbd_status
+udl_init_test(struct udl_softc *sc)
+{
+ int i, j, parts, loops;
+ uint16_t color;
+ uint16_t rgb24[3] = { 0xf800, 0x07e0, 0x001f };
+
+ loops = sc->sc_width * sc->sc_height / UDL_CMD_MAX_PIXEL_COUNT;
+ parts = loops / 3;
+ color = rgb24[0];
+
+ j = 1;
+ for (i = 0; i < loops; i++) {
+ if (i == parts) {
+ color = rgb24[j];
+ parts += parts;
+ j++;
+ }
+ udl_fb_off_write(sc, color, i * UDL_CMD_MAX_PIXEL_COUNT,
+ UDL_CMD_MAX_PIXEL_COUNT);
+ }
+ (void)udl_cmd_send(sc);
+
+ return (USBD_NORMAL_COMPLETION);
+}
+#endif
diff --git a/sys/dev/usb/udl.h b/sys/dev/usb/udl.h
new file mode 100644
index 00000000000..bda07c5c71a
--- /dev/null
+++ b/sys/dev/usb/udl.h
@@ -0,0 +1,641 @@
+/* $OpenBSD: udl.h,v 1.1 2009/05/09 19:23:07 mglocker Exp $ */
+
+/*
+ * Copyright (c) 2009 Marcus Glocker <mglocker@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Bulk command xfer structure.
+ */
+#define UDL_CMD_MAX_XFER_SIZE 1048576
+#define UDL_CMD_MAX_DATA_SIZE 256
+#define UDL_CMD_MAX_PIXEL_COUNT (UDL_CMD_MAX_DATA_SIZE / 2)
+
+struct udl_cmd_xfer {
+ struct udl_softc *sc;
+ usbd_xfer_handle xfer;
+ uint8_t busy;
+ uint8_t *buf;
+};
+
+struct udl_cmd_buf {
+ uint32_t off;
+ uint8_t *buf;
+};
+
+/*
+ * Our per device structure.
+ */
+struct udl_softc {
+ struct device sc_dev;
+ usbd_device_handle sc_udev;
+ usbd_interface_handle sc_iface;
+ usbd_pipe_handle sc_tx_pipeh;
+
+ /* wsdisplay glue */
+ struct device *sc_wsdisplay;
+ struct rasops_info sc_ri;
+ uint8_t sc_nscreens;
+
+#define UDL_CMD_XFER_COUNT 8
+ int sc_cmd_xfer_cnt;
+ struct udl_cmd_xfer sc_cmd_xfer[UDL_CMD_XFER_COUNT];
+ struct udl_cmd_buf sc_cmd_buf;
+ uint16_t sc_width;
+ uint16_t sc_height;
+ uint8_t sc_depth;
+ uint8_t sc_cursor_on;
+};
+
+/*
+ * Chip commands.
+ */
+#define UDL_CTRL_CMD_READ_EDID 0x02
+#define UDL_CTRL_CMD_WRITE_1 0x03
+#define UDL_CTRL_CMD_READ_1 0x04
+#define UDL_CTRL_CMD_POLL 0x06
+#define UDL_CTRL_CMD_SET_KEY 0x12
+
+#define UDL_BULK_SOC 0xaf /* start of command token */
+
+#define UDL_BULK_CMD_REG_WRITE_1 0x20 /* write 1 byte to register */
+#define UDL_BULK_CMD_EOC 0xa0 /* end of command stack */
+#define UDL_BULK_CMD_DECOMP 0xe0 /* send decompression table */
+
+#define UDL_BULK_CMD_FB_BASE 0x60
+#define UDL_BULK_CMD_FB_WORD 0x08
+#define UDL_BULK_CMD_FB_WRITE (UDL_BULK_CMD_FB_BASE | 0x00)
+#define UDL_BULK_CMD_FB_COPY (UDL_BULK_CMD_FB_BASE | 0x02)
+
+/*
+ * Chip registers.
+ */
+#define UDL_REG_ADDR_START16 0x20
+#define UDL_REG_ADDR_STRIDE16 0x23
+#define UDL_REG_ADDR_START8 0x26
+#define UDL_REG_ADDR_STRIDE8 0x29
+
+#define UDL_REG_BLANK_SCREEN 0x1f
+#define UDL_REG_SYNC 0xff
+
+/*
+ * Register values for screen resolution initialization.
+ */
+uint8_t udl_reg_vals_640[] = {
+ 0x00, 0x99, 0x30, 0x26, 0x94, 0x60, 0xa9, 0xce, 0x60, 0x07, 0xb3, 0x0f,
+ 0x79, 0xff, 0xff, 0x02, 0x80, 0x83, 0xbc, 0xff, 0xfc, 0xff, 0xff, 0x01,
+ 0xe0, 0x01, 0x02, 0xab, 0x13
+};
+uint8_t udl_reg_vals_800[] = {
+ 0x00, 0x20, 0x3c, 0x7a, 0xc9, 0x93, 0x60, 0xc8, 0xc7, 0x70, 0x53, 0xff,
+ 0xff, 0x21, 0x27, 0x03, 0x20, 0x91, 0x8f, 0xff, 0xff, 0xff, 0xf2, 0x02,
+ 0x58, 0x01, 0x02, 0x40, 0x1f
+};
+uint8_t udl_reg_vals_1024[] = {
+ 0x00, 0x36, 0x18, 0xd5, 0x10, 0x60, 0xa9, 0x7b, 0x33, 0xa1, 0x2b, 0x27,
+ 0x32, 0xff, 0xff, 0x04, 0x00, 0xd9, 0x9a, 0xff, 0xca, 0xff, 0xff, 0x03,
+ 0x00, 0x04, 0x03, 0xc8, 0x32
+};
+uint8_t udl_reg_vals_1280[] = {
+ 0x00, 0x98, 0xf8, 0x0d, 0x57, 0x2a, 0x55, 0x4d, 0x54, 0xca, 0x0d, 0xff,
+ 0xff, 0x94, 0x43, 0x05, 0x00, 0x9a, 0xa8, 0xff, 0xff, 0xff, 0xf9, 0x04,
+ 0x00, 0x04, 0x02, 0x60, 0x54
+};
+
+/*
+ * Encryption.
+ */
+uint8_t udl_null_key_1[] = {
+ 0x57, 0xcd, 0xdc, 0xa7, 0x1c, 0x88, 0x5e, 0x15, 0x60, 0xfe, 0xc6, 0x97,
+ 0x16, 0x3d, 0x47, 0xf2
+};
+
+/*
+ * Compression.
+ */
+uint8_t udl_decomp_table[] = {
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x60, 0x01, 0x00, 0x00, 0x00, 0x61,
+ 0x00, 0x00, 0x00, 0x01, 0x23, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x60, 0x05, 0x00, 0x00, 0x00, 0x61,
+ 0x00, 0x00, 0x00, 0x01, 0x67, 0x00, 0x01, 0x00, 0x01,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0x00, 0x00, 0x00, 0x01, 0x89, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x61, 0xab, 0x00, 0x00, 0x00, 0x61,
+ 0x00, 0x00, 0x00, 0x01, 0xcd, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x60, 0x0f, 0x00, 0x00, 0x00, 0x61,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x01, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 0x01, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x44, 0x00, 0x02, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x44, 0x00, 0x02, 0x00, 0x02,
+ 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x67, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x67, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0xc8, 0x00, 0x00, 0x01, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 0x01, 0x00, 0x02,
+ 0x00, 0x00, 0x01, 0x01, 0x2b, 0x00, 0x00, 0x01, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0xcc, 0x00, 0x02, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0xdd, 0x00, 0x04, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0xef, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x01, 0x01, 0xc4, 0x00, 0x00, 0x01, 0x03,
+ 0x00, 0x29, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0xb7, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x78, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x99, 0x00, 0x04, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0xaa, 0x00, 0x08, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0xbc, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0xde, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x04, 0x12, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x04, 0x34, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x04, 0x56, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x04, 0x78, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x04, 0x9a, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0xd7, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x02, 0x01,
+ 0x00, 0x00, 0x02, 0x04, 0xbb, 0x00, 0x00, 0x03, 0x04,
+ 0x00, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x08, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x04, 0xdd, 0x00, 0x10, 0x00, 0x04,
+ 0x00, 0x20, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x00, 0x05,
+ 0xff, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x05, 0x23, 0x00, 0x00, 0x00, 0x05,
+ 0x08, 0x00, 0x01, 0x00, 0x00, 0x08, 0x20, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x45, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x21, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x67, 0x00, 0x00, 0x00, 0x05,
+ 0xf8, 0x00, 0x01, 0x00, 0x00, 0xf7, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x89, 0x00, 0x00, 0x00, 0x05,
+ 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0xdf, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0xab, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x02, 0x01,
+ 0x00, 0x00, 0x02, 0x05, 0xcc, 0x00, 0x00, 0x03, 0x05,
+ 0x00, 0x12, 0x01, 0x00, 0x00, 0x00, 0x32, 0x01, 0x00,
+ 0x00, 0xce, 0x01, 0x00, 0x00, 0x00, 0xae, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0xde, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x05, 0xff, 0x00, 0x10, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x20, 0x00, 0x06,
+ 0x08, 0x41, 0x01, 0x00, 0x00, 0x08, 0x21, 0x01, 0x00,
+ 0x08, 0x61, 0x00, 0x06, 0x12, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x06, 0x34, 0x00, 0x00, 0x00, 0x06,
+ 0xf7, 0xbf, 0x01, 0x00, 0x00, 0xf7, 0xdf, 0x01, 0x00,
+ 0xf7, 0x9f, 0x00, 0x06, 0x56, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x06, 0x78, 0x00, 0x00, 0x00, 0x06,
+ 0x10, 0x61, 0x00, 0x06, 0x9a, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x41, 0x00, 0x06, 0x9b, 0x00, 0x00, 0x00, 0x06,
+ 0x08, 0x62, 0x00, 0x06, 0x9c, 0x00, 0x00, 0x00, 0x06,
+ 0x08, 0x40, 0x00, 0x06, 0x9d, 0x00, 0x00, 0x00, 0x06,
+ 0xef, 0x9f, 0x00, 0x06, 0xef, 0x00, 0x00, 0x00, 0x06,
+ 0xff, 0xbf, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x07,
+ 0xf7, 0x9e, 0x00, 0x06, 0xe1, 0x00, 0x00, 0x00, 0x07,
+ 0xf7, 0xc0, 0x00, 0x06, 0xe2, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x07, 0x34, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x03, 0x01,
+ 0x00, 0x00, 0x04, 0x07, 0x55, 0x00, 0x00, 0x06, 0x07,
+ 0x00, 0x00, 0x00, 0x07, 0x66, 0x00, 0x20, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x07, 0x77, 0x00, 0x40, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x07, 0x88, 0x00, 0x20, 0x00, 0x07,
+ 0x08, 0x01, 0x01, 0x00, 0x09, 0x10, 0x02, 0x00, 0x07,
+ 0xef, 0xfe, 0x00, 0x07, 0xab, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x07, 0xcf, 0xff, 0xff, 0xff, 0x7f,
+ 0x00, 0x00, 0x00, 0x07, 0xdd, 0xff, 0xe0, 0x00, 0x07,
+ 0xf7, 0xff, 0x01, 0x00, 0x0e, 0xef, 0xfe, 0x00, 0x07,
+ 0x10, 0x02, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x08, 0x1f, 0xff, 0xff, 0xff, 0x7f,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x08, 0x41, 0x00, 0x08,
+ 0x10, 0x41, 0x00, 0x06, 0x93, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x08, 0x45, 0x00, 0x00, 0x00, 0x08,
+ 0x08, 0x42, 0x00, 0x06, 0x96, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x01, 0x00, 0x09, 0xf7, 0xbf, 0x00, 0x08,
+ 0xef, 0xbf, 0x00, 0x06, 0xea, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x08, 0xbc, 0x00, 0x00, 0x00, 0x08,
+ 0xf7, 0xbe, 0x00, 0x06, 0xed, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x08, 0xef, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x03, 0x01,
+ 0x00, 0x00, 0x04, 0x09, 0x00, 0x00, 0x00, 0x06, 0x09,
+ 0x00, 0x00, 0x00, 0x09, 0x12, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x09, 0x33, 0x00, 0x40, 0x00, 0x09,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x04, 0x08, 0x41, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x09, 0x55, 0x08, 0x01, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x09, 0x66, 0xf7, 0xff, 0x00, 0x09,
+ 0x10, 0x42, 0x00, 0x06, 0x99, 0x10, 0x62, 0x00, 0x06,
+ 0xf8, 0x1f, 0x00, 0x06, 0x99, 0x00, 0x40, 0x00, 0x06,
+ 0x00, 0x00, 0x01, 0x00, 0x07, 0xf7, 0xbf, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x09, 0x88, 0xf7, 0xff, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x09, 0x99, 0x08, 0x01, 0x00, 0x09,
+ 0xef, 0xbe, 0x00, 0x06, 0xee, 0xef, 0x9e, 0x00, 0x06,
+ 0x07, 0xe1, 0x00, 0x06, 0xee, 0xff, 0xc0, 0x00, 0x06,
+ 0x00, 0x00, 0x01, 0x00, 0x0a, 0x08, 0x41, 0x00, 0x09,
+ 0xf8, 0x20, 0x00, 0x06, 0x99, 0x07, 0xff, 0x00, 0x06,
+ 0x08, 0x1f, 0x00, 0x06, 0x9b, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x09, 0xcd, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x1f, 0x00, 0x06, 0x99, 0xf8, 0x01, 0x00, 0x06,
+ 0xf8, 0x21, 0x00, 0x06, 0x9e, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x01, 0x00, 0x01, 0xf7, 0xbf, 0x00, 0x0a,
+ 0x07, 0xe0, 0x00, 0x06, 0xee, 0xf8, 0x01, 0x00, 0x06,
+ 0xf7, 0xe1, 0x00, 0x06, 0xe2, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x0a, 0x34, 0x00, 0x00, 0x00, 0x0a,
+ 0xff, 0xe1, 0x00, 0x06, 0xee, 0x07, 0xff, 0x00, 0x06,
+ 0x07, 0xdf, 0x00, 0x06, 0xe5, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x0a, 0x67, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x0a, 0x89, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x05, 0x01,
+ 0x00, 0x00, 0x08, 0x0a, 0xaa, 0x00, 0x00, 0x0c, 0x0a,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0xbb, 0x08, 0x41, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x0a, 0xcd, 0x10, 0x02, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x0a, 0xce, 0xef, 0xfe, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x0a, 0xff, 0xf7, 0xbf, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x0b, 0x01, 0xef, 0xfe, 0x00, 0x0b,
+ 0x00, 0x00, 0x00, 0x0b, 0x02, 0x10, 0x02, 0x00, 0x0b,
+ 0x00, 0x00, 0x01, 0x00, 0x03, 0x08, 0x41, 0x00, 0x0b,
+ 0x10, 0x21, 0x00, 0x06, 0x94, 0x00, 0x00, 0x00, 0x0b,
+ 0xef, 0xff, 0x00, 0x06, 0x95, 0x00, 0x00, 0x00, 0x0b,
+ 0x00, 0x00, 0x00, 0x0b, 0x66, 0x00, 0x20, 0x00, 0x0b,
+ 0x08, 0x22, 0x00, 0x06, 0x97, 0x00, 0x00, 0x00, 0x0b,
+ 0xf7, 0xfe, 0x00, 0x06, 0x98, 0x00, 0x00, 0x00, 0x0b,
+ 0x00, 0x00, 0x00, 0x0b, 0x99, 0x00, 0x20, 0x00, 0x0b,
+ 0x00, 0x00, 0x01, 0x00, 0x0a, 0xf7, 0xbf, 0x00, 0x0b,
+ 0xef, 0xdf, 0x00, 0x06, 0xeb, 0x00, 0x00, 0x00, 0x0b,
+ 0x10, 0x01, 0x00, 0x06, 0xec, 0x00, 0x00, 0x00, 0x0b,
+ 0x00, 0x00, 0x00, 0x0b, 0xdd, 0xff, 0xe0, 0x00, 0x0b,
+ 0xf7, 0xde, 0x00, 0x06, 0xee, 0x00, 0x00, 0x00, 0x0b,
+ 0x08, 0x02, 0x00, 0x06, 0xef, 0x00, 0x00, 0x00, 0x0b,
+ 0x00, 0x00, 0x00, 0x0c, 0x00, 0xff, 0xe0, 0x00, 0x0c,
+ 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x05, 0x01,
+ 0x00, 0x00, 0x08, 0x0c, 0x11, 0x00, 0x00, 0x0c, 0x0c,
+ 0x00, 0x00, 0x00, 0x0c, 0x23, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x01, 0x00, 0x04, 0x10, 0x82, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x0c, 0x56, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x0c, 0x77, 0x10, 0x02, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x0c, 0x88, 0xef, 0xfe, 0x00, 0x0c,
+ 0x00, 0x00, 0x01, 0x00, 0x09, 0xef, 0x7e, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x0c, 0xab, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x0c, 0xcc, 0xef, 0xfe, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x0c, 0xdd, 0x10, 0x02, 0x00, 0x0c,
+ 0x00, 0x00, 0x01, 0x00, 0x0e, 0x08, 0x41, 0x00, 0x0c,
+ 0x10, 0x01, 0x00, 0x06, 0x99, 0xf0, 0x1f, 0x00, 0x06,
+ 0x10, 0x00, 0x00, 0x0a, 0xcc, 0xf0, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x0c, 0xf0, 0x08, 0x41, 0x00, 0x0d,
+ 0x08, 0x02, 0x00, 0x06, 0x99, 0xf8, 0x1e, 0x00, 0x06,
+ 0x00, 0x02, 0x00, 0x0a, 0xcc, 0xff, 0xfe, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x0d, 0x12, 0x08, 0x41, 0x00, 0x0d,
+ 0x00, 0x00, 0x01, 0x00, 0x03, 0xf7, 0xbf, 0x00, 0x0d,
+ 0xef, 0xff, 0x00, 0x06, 0xee, 0x0f, 0xe1, 0x00, 0x06,
+ 0xf0, 0x00, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x00, 0x0b,
+ 0x00, 0x00, 0x00, 0x0d, 0x45, 0xf7, 0xbf, 0x00, 0x0d,
+ 0xf7, 0xfe, 0x00, 0x06, 0xee, 0x07, 0xe2, 0x00, 0x06,
+ 0xff, 0xfe, 0x00, 0x0b, 0x00, 0x00, 0x02, 0x00, 0x0b,
+ 0x00, 0x00, 0x00, 0x0d, 0x67, 0xf7, 0xbf, 0x00, 0x0d,
+ 0x00, 0x00, 0x00, 0x0d, 0x89, 0x00, 0x00, 0x00, 0x0d,
+ 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x09, 0x01,
+ 0x00, 0x00, 0x10, 0x0d, 0xaa, 0x00, 0x00, 0x18, 0x0d,
+ 0x00, 0x00, 0x00, 0x0d, 0xbb, 0x10, 0x82, 0x00, 0x0d,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00,
+ 0x08, 0x41, 0x00, 0x09, 0x44, 0x08, 0x61, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x0a, 0xcc, 0x20, 0x04, 0x00, 0x0d,
+ 0x00, 0x00, 0x00, 0x0a, 0xcd, 0xdf, 0xfc, 0x00, 0x0d,
+ 0x00, 0x00, 0x00, 0x0d, 0xee, 0xef, 0x7e, 0x00, 0x0d,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0xe0, 0x01, 0x00,
+ 0xf7, 0xbf, 0x00, 0x09, 0x77, 0xf7, 0x9f, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x0b, 0x0f, 0xdf, 0xfc, 0x00, 0x0d,
+ 0x00, 0x00, 0x00, 0x0b, 0x00, 0x20, 0x04, 0x00, 0x0e,
+ 0x00, 0x00, 0x01, 0x00, 0x01, 0x08, 0x41, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x0e, 0x23, 0x00, 0x00, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x0e, 0x44, 0x08, 0x41, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x0e, 0x56, 0x00, 0x00, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x0e, 0x77, 0x08, 0x41, 0x00, 0x0e,
+ 0x00, 0x00, 0x01, 0x00, 0x08, 0xf7, 0xbf, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x0e, 0x9a, 0x00, 0x00, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x0e, 0xbb, 0xf7, 0xbf, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x0e, 0xcd, 0x00, 0x00, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x0e, 0xee, 0xf7, 0xbf, 0x00, 0x0e,
+ 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x09, 0x01,
+ 0x00, 0x00, 0x10, 0x0e, 0xff, 0x00, 0x00, 0x18, 0x0e,
+ 0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x21, 0x04, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x0a, 0xc3, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x0a, 0xc4, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x01, 0x00, 0x05, 0xde, 0xfc, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x0b, 0x07, 0x00, 0x00, 0x00, 0x0f,
+ 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x41, 0x00, 0x0f,
+ 0x08, 0x00, 0x00, 0x0f, 0x9a, 0x0f, 0xff, 0x00, 0x0f,
+ 0xf8, 0x00, 0x00, 0x0f, 0xbc, 0xf0, 0x01, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x0c, 0xfd, 0x10, 0x82, 0x00, 0x0f,
+ 0x00, 0x01, 0x00, 0x0f, 0xec, 0xf8, 0x02, 0x00, 0x0f,
+ 0xff, 0xff, 0x00, 0x0f, 0xfa, 0x07, 0xfe, 0x00, 0x0f,
+ 0x00, 0x00, 0x00, 0x0d, 0x10, 0x10, 0x82, 0x00, 0x10,
+ 0x00, 0x00, 0x01, 0x00, 0x01, 0xf7, 0xbf, 0x00, 0x10,
+ 0xf8, 0x00, 0x00, 0x0f, 0xb2, 0xf0, 0x01, 0x00, 0x10,
+ 0x08, 0x00, 0x00, 0x0f, 0x93, 0x0f, 0xff, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x0d, 0x44, 0xef, 0x7e, 0x00, 0x10,
+ 0xff, 0xff, 0x00, 0x0f, 0xf3, 0x07, 0xfe, 0x00, 0x10,
+ 0x00, 0x01, 0x00, 0x0f, 0xe2, 0xf8, 0x02, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x0d, 0x65, 0xef, 0x7e, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x10, 0x67, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x11, 0x01,
+ 0x00, 0x00, 0x20, 0x10, 0x88, 0x00, 0x00, 0x30, 0x10,
+ 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x10,
+ 0x20, 0x04, 0x00, 0x0a, 0xcc, 0x40, 0x08, 0x00, 0x0a,
+ 0xdf, 0xfc, 0x00, 0x0a, 0xcc, 0xbf, 0xf8, 0x00, 0x0a,
+ 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10,
+ 0xdf, 0xfc, 0x00, 0x0b, 0x00, 0xbf, 0xf8, 0x00, 0x0b,
+ 0x20, 0x04, 0x00, 0x0b, 0x00, 0x40, 0x08, 0x00, 0x0b,
+ 0x00, 0x00, 0x01, 0x00, 0x0b, 0x08, 0x41, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x10, 0xcc, 0x08, 0x01, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x10, 0xdd, 0x08, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x10, 0xee, 0xf7, 0xff, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x10, 0xff, 0x00, 0x01, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x10, 0x82, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0x11, 0x08, 0x01, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0x22, 0xf7, 0xff, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0x33, 0x10, 0x82, 0x00, 0x11,
+ 0x00, 0x00, 0x01, 0x00, 0x04, 0xf7, 0xbf, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0x55, 0xf8, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0x66, 0xff, 0xff, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0x77, 0xef, 0x7e, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0x88, 0xef, 0x7e, 0x00, 0x11,
+ 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x11, 0x01,
+ 0x00, 0x00, 0x20, 0x11, 0x99, 0x00, 0x00, 0x30, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0xab, 0x00, 0x00, 0x00, 0x11,
+ 0x21, 0x04, 0x01, 0x00, 0x00, 0x42, 0x08, 0x01, 0x00,
+ 0xde, 0xfc, 0x01, 0x00, 0x00, 0xbd, 0xf8, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x0c, 0x08, 0x41, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0xde, 0x10, 0x02, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x11, 0xf0, 0x10, 0x00, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x12, 0x12, 0xef, 0xfe, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x02, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x0c, 0xf4, 0x21, 0x04, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x12, 0x56, 0x10, 0x02, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x11, 0xf7, 0xef, 0xfe, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x0d, 0x18, 0x21, 0x04, 0x00, 0x12,
+ 0x00, 0x00, 0x01, 0x00, 0x09, 0xf7, 0xbf, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x12, 0x5a, 0xf0, 0x00, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x11, 0xdb, 0xff, 0xfe, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x0d, 0x4c, 0xde, 0xfc, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x0d, 0x6d, 0xde, 0xfc, 0x00, 0x12,
+ 0x00, 0x00, 0x00, 0x12, 0xef, 0x00, 0x00, 0x00, 0x12,
+ 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x21, 0x01,
+ 0x00, 0x00, 0x40, 0x13, 0x00, 0x00, 0x00, 0x60, 0x13,
+ 0x00, 0x00, 0x01, 0x00, 0x01, 0x08, 0x41, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0x22, 0x08, 0x00, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0x33, 0x10, 0x02, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0x44, 0xff, 0xff, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0x55, 0x10, 0x00, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0x66, 0xf8, 0x00, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0x77, 0xef, 0xfe, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0x88, 0x00, 0x02, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0x99, 0x21, 0x04, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0xaa, 0x00, 0x01, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0xbb, 0x10, 0x02, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0xcc, 0xef, 0xfe, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0xdd, 0x21, 0x04, 0x00, 0x13,
+ 0x00, 0x00, 0x01, 0x00, 0x0e, 0xf7, 0xbf, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x13, 0xff, 0xf0, 0x00, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0xff, 0xfe, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x14, 0x11, 0xde, 0xfc, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x14, 0x22, 0xde, 0xfc, 0x00, 0x14,
+ 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x21, 0x01,
+ 0x00, 0x00, 0x40, 0x14, 0x33, 0x00, 0x00, 0x60, 0x14,
+ 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x41, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x04, 0x08, 0x41, 0x00, 0x14,
+ 0x00, 0x00, 0x01, 0x00, 0x05, 0x10, 0x00, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x11, 0xd6, 0x20, 0x04, 0x00, 0x14,
+ 0x00, 0x00, 0x01, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x11, 0xf8, 0x20, 0x00, 0x00, 0x14,
+ 0x00, 0x00, 0x01, 0x00, 0x09, 0xf0, 0x00, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x12, 0x1a, 0xdf, 0xfc, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x12, 0x1b, 0x00, 0x04, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x0c, 0xfc, 0x42, 0x08, 0x00, 0x14,
+ 0x00, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x12, 0x5e, 0x20, 0x04, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x11, 0xff, 0xdf, 0xfc, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x0d, 0x10, 0x42, 0x08, 0x00, 0x15,
+ 0x00, 0x00, 0x01, 0x00, 0x01, 0xf7, 0xbf, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x12, 0x52, 0xe0, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x11, 0xd3, 0xff, 0xfc, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x0d, 0x44, 0xbd, 0xf8, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x0d, 0x65, 0xbd, 0xf8, 0x00, 0x15,
+ 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x41, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x06, 0x08, 0x41, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x15, 0x77, 0x10, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x11, 0xd8, 0x00, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x15, 0x99, 0xff, 0xfe, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x11, 0xfa, 0x00, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x15, 0xbb, 0xf0, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x12, 0x1c, 0x00, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x12, 0x1d, 0x00, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x0c, 0xfe, 0x00, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x15, 0xff, 0x00, 0x02, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x12, 0x50, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x00, 0x11, 0xf1, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x00, 0x0d, 0x12, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x01, 0x00, 0x03, 0xf7, 0xbf, 0x00, 0x16,
+ 0x00, 0x00, 0x00, 0x12, 0x54, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x00, 0x11, 0xd5, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x00, 0x0d, 0x46, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x00, 0x0d, 0x67, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x41, 0x00, 0x16,
+ 0x00, 0x00, 0x01, 0x00, 0x09, 0x20, 0x00, 0x00, 0x16,
+ 0x20, 0x04, 0x00, 0x11, 0xdd, 0x40, 0x08, 0x00, 0x11,
+ 0x00, 0x00, 0x01, 0x00, 0x0a, 0xff, 0xfc, 0x00, 0x16,
+ 0x20, 0x00, 0x00, 0x11, 0xff, 0x40, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x01, 0x00, 0x0b, 0xe0, 0x00, 0x00, 0x16,
+ 0xdf, 0xfc, 0x00, 0x12, 0x11, 0xbf, 0xf8, 0x00, 0x12,
+ 0x00, 0x04, 0x00, 0x12, 0x11, 0x00, 0x08, 0x00, 0x12,
+ 0x42, 0x08, 0x00, 0x0c, 0xff, 0x83, 0xf0, 0x00, 0x0c,
+ 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x16,
+ 0x20, 0x04, 0x00, 0x12, 0x55, 0x40, 0x08, 0x00, 0x12,
+ 0xdf, 0xfc, 0x00, 0x11, 0xff, 0xbf, 0xf8, 0x00, 0x11,
+ 0x42, 0x08, 0x00, 0x0d, 0x11, 0x83, 0xf1, 0x00, 0x0d,
+ 0x00, 0x00, 0x01, 0x00, 0x0d, 0xf7, 0xbf, 0x00, 0x16,
+ 0xe0, 0x00, 0x00, 0x12, 0x55, 0xc0, 0x00, 0x00, 0x12,
+ 0xff, 0xfc, 0x00, 0x11, 0xdd, 0xff, 0xf8, 0x00, 0x11,
+ 0xbd, 0xf8, 0x00, 0x0d, 0x44, 0x7b, 0xf0, 0x00, 0x0d,
+ 0xbd, 0xf8, 0x00, 0x0d, 0x66, 0x74, 0x0f, 0x00, 0x0d,
+ 0x00, 0x00, 0x01, 0x00, 0x0e, 0x08, 0x41, 0x00, 0x16,
+ 0x00, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
+ 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17,
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x17,
+ 0x00, 0x00, 0x01, 0x00, 0x03, 0xf7, 0xbf, 0x00, 0x17,
+ 0x00, 0x00, 0x01, 0x00, 0x04, 0x08, 0x41, 0x00, 0x17,
+ 0x20, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00,
+ 0xff, 0xfc, 0x01, 0x00, 0x00, 0xff, 0xf8, 0x01, 0x00,
+ 0xe0, 0x00, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x01, 0x00,
+ 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x05, 0xf7, 0xbf, 0x00, 0x17,
+ 0x00, 0x00, 0x01, 0x00, 0x06, 0x08, 0x41, 0x00, 0x17,
+ 0x00, 0x00, 0x01, 0x00, 0x07, 0xf7, 0xbf, 0x00, 0x17,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x41, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0xf7, 0xbf, 0x01, 0x00,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f,
+ 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f
+};
diff --git a/sys/dev/wscons/wsconsio.h b/sys/dev/wscons/wsconsio.h
index e4ebe152ecd..1f7b473cbd8 100644
--- a/sys/dev/wscons/wsconsio.h
+++ b/sys/dev/wscons/wsconsio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsconsio.h,v 1.50 2009/03/12 19:10:22 kettenis Exp $ */
+/* $OpenBSD: wsconsio.h,v 1.51 2009/05/09 19:23:07 mglocker Exp $ */
/* $NetBSD: wsconsio.h,v 1.74 2005/04/28 07:15:44 martin Exp $ */
/*
@@ -303,6 +303,7 @@ struct wsmouse_calibcoords {
#define WSDISPLAY_TYPE_LEGSS 55 /* DEC LEGSS (VS35x0) */
#define WSDISPLAY_TYPE_IFB 56 /* Sun Expert3D{,-Lite} */
#define WSDISPLAY_TYPE_RAPTOR 57 /* Tech Source Raptor */
+#define WSDISPLAY_TYPE_DL 58 /* DisplayLink DL-120/DL-160 */
/* Basic display information. Not applicable to all display types. */
struct wsdisplay_fbinfo {