From 7e882c700a96297ecac976bf49cf47f862506773 Mon Sep 17 00:00:00 2001 From: Oliver Schinagl Date: Thu, 17 Mar 2011 00:47:34 +0000 Subject: Remove unnessasery Webcam driver USB support for all w90n745 bits and pieces --- uClinux-2.4.20-uc1/drivers/usb/Config.in | 3 + uClinux-2.4.20-uc1/drivers/usb/Makefile | 6 +- uClinux-2.4.20-uc1/drivers/usb/W99683.c | 787 ----------- uClinux-2.4.20-uc1/drivers/usb/W99683.h | 263 ---- uClinux-2.4.20-uc1/drivers/usb/W99685ISP.h | 708 ---------- uClinux-2.4.20-uc1/drivers/usb/audio.c | 44 + uClinux-2.4.20-uc1/drivers/usb/hub.c | 24 +- uClinux-2.4.20-uc1/drivers/usb/serial/Config.in | 3 + uClinux-2.4.20-uc1/drivers/usb/serial/usbserial.c | 17 +- .../drivers/usb/storage/initializers.c | 19 + uClinux-2.4.20-uc1/drivers/usb/storage/protocol.c | 113 ++ uClinux-2.4.20-uc1/drivers/usb/storage/scsiglue.c | 8 + uClinux-2.4.20-uc1/drivers/usb/storage/transport.c | 45 + uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c | 499 +++++++ uClinux-2.4.20-uc1/drivers/usb/usb-ohci.h | 137 +- uClinux-2.4.20-uc1/drivers/usb/usb.c | 47 + uClinux-2.4.20-uc1/drivers/usb/wbusbd/Config.in | 17 + uClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile | 13 + .../drivers/usb/wbusbd/w90n745_mass.c | 1066 ++++++++++++++ .../drivers/usb/wbusbd/w90n745_mass.h | 250 ++++ .../drivers/usb/wbusbd/w90n745_vcom.c | 1477 ++++++++++++++++++++ .../drivers/usb/wbusbd/w90n745_vcom.h | 261 ++++ 22 files changed, 4042 insertions(+), 1765 deletions(-) delete mode 100755 uClinux-2.4.20-uc1/drivers/usb/W99683.c delete mode 100755 uClinux-2.4.20-uc1/drivers/usb/W99683.h delete mode 100755 uClinux-2.4.20-uc1/drivers/usb/W99685ISP.h create mode 100755 uClinux-2.4.20-uc1/drivers/usb/wbusbd/Config.in create mode 100755 uClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile create mode 100644 uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.c create mode 100644 uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.h create mode 100644 uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.c create mode 100644 uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.h diff --git a/uClinux-2.4.20-uc1/drivers/usb/Config.in b/uClinux-2.4.20-uc1/drivers/usb/Config.in index 3325275..a2895be 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/Config.in +++ b/uClinux-2.4.20-uc1/drivers/usb/Config.in @@ -113,6 +113,9 @@ if [ "$CONFIG_USB" = "y" -o "$CONFIG_USB" = "m" ]; then dep_tristate ' USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT source drivers/usb/serial/Config.in + comment 'Winbond USB Device 1.1 drivers' + source drivers/usb/wbusbd/Config.in + comment 'USB Miscellaneous drivers' dep_tristate ' USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL dep_tristate ' USB Auerswald ISDN support (EXPERIMENTAL)' CONFIG_USB_AUERSWALD $CONFIG_USB $CONFIG_EXPERIMENTAL diff --git a/uClinux-2.4.20-uc1/drivers/usb/Makefile b/uClinux-2.4.20-uc1/drivers/usb/Makefile index f927f5a..1c38089 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/Makefile +++ b/uClinux-2.4.20-uc1/drivers/usb/Makefile @@ -73,7 +73,6 @@ obj-$(CONFIG_USB_AUDIO) += audio.o obj-$(CONFIG_USB_EMI26) += emi26.o obj-$(CONFIG_USB_MIDI) += usb-midi.o obj-$(CONFIG_USB_IBMCAM) += ibmcam.o usbvideo.o ultracam.o -obj-$(CONFIG_USB_W99683) += W99683.o obj-$(CONFIG_USB_PWC) += pwc.o obj-$(CONFIG_USB_DC2XX) += dc2xx.o obj-$(CONFIG_USB_MDC800) += mdc800.o @@ -100,7 +99,7 @@ obj-$(CONFIG_USB_BRLVGER) += brlvger.o obj-$(CONFIG_USB_LCD) += usblcd.o # Object files in subdirectories -mod-subdirs := serial hcd +mod-subdirs := serial hcd wbusbd subdir-$(CONFIG_USB_SERIAL) += serial subdir-$(CONFIG_USB_STORAGE) += storage @@ -109,6 +108,9 @@ ifeq ($(CONFIG_USB_SERIAL),y) obj-y += serial/usb-serial.o endif +obj-$(CONFIG_WINBOND_USBD) += wbusbd/w90n745_usbd.o +subdir-$(CONFIG_WINBOND_USBD) += wbusbd + ifeq ($(CONFIG_USB_STORAGE),y) obj-y += storage/storage.o endif diff --git a/uClinux-2.4.20-uc1/drivers/usb/W99683.c b/uClinux-2.4.20-uc1/drivers/usb/W99683.c deleted file mode 100755 index f58e0b6..0000000 --- a/uClinux-2.4.20-uc1/drivers/usb/W99683.c +++ /dev/null @@ -1,787 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * - */ -/*------------------------ Now version 1.0 only support one camera-------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined (__i386__) - #include -#endif - -#include "W99683.h" - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.00 for Linux 2.4" -#define EMAIL "ypxin@winbond.com.tw" -#define DRIVER_AUTHOR "ypxin@winbond.com.tw" -#define DRIVER_DESC "W99683 USB Camera Driver" - -static UINT8 W685ISPFW[] = { - #include "W99685ISP.h" -}; -#define ISPFW_SIZE (sizeof(W685ISPFW)/sizeof(W685ISPFW[0])) -static struct usb_driver W99683_driver; - -/* table of devices that work with this driver */ -static struct usb_device_id W99683_table [] = { - { USB_DEVICE(W99683_VENDOR, W99683i_PRODUCT) }, - { USB_DEVICE(W99685ISP_VENDOR, W99685iISP_PRODUCT)}, - { USB_DEVICE(W99685_VENDOR, W99685i_PRODUCT)}, - {}, /* Terminating entry */ -}; - -static int video_nr = -1; /* next avail video device */ - -struct usb_W99683 *w683_debug = NULL; - -static int -W99683IO(struct usb_device *dev, int Action,struct usb_args *arg, unsigned char *buf); - -static int W99685_Reset2Ram(struct usb_device *dev) -{ - int result = 0; - int action; - struct usb_args init_args; - - INIT_USBARGS(&init_args, 0x16, 0x00, 0x02, 0x00); - action = USB_WRITE; - result = W99683IO(dev, action, &init_args, NULL); - if(result < 0) - { - printk("Reset to DRAM failed\n"); - goto out; - } -out: - return result; -} - -static int -W99685_ProgramPage(struct usb_device *dev) -{ - int result = 0; - int action; - struct usb_args init_args; - - INIT_USBARGS(&init_args, 0x11, 0x00, 0x00, 0x00); - action = USB_WRITE; - result = W99683IO(dev, action, &init_args, NULL); - if(result < 0) - { - printk("W99685 Program Page failed\n"); - goto out; - } -out: - return result; -} - -static int -W99685_WriteReg(struct usb_device *dev, UINT16 addr, UINT8 *buf, UINT16 len) -{ - int result = 0; - int action; - struct usb_args init_args; - - INIT_USBARGS(&init_args, 0x01, 0x00, addr, len); - action = USB_WRITE; - result = W99683IO(dev, action, &init_args, buf); - if(result < 0) - { - printk("Enable W99685 Write Register failed\n"); - goto out; - } -out: - return result; -} - -static int -W99685_DOISP(struct usb_device *dev) -{ - int result = 0; - int i, k; - UINT8 retry = 4; - UINT8 tmpbuf[W99685_RAM_PAGE_SIZE]; - UINT8 *firmware_datap = W685ISPFW; - int fw_page_num = ISPFW_SIZE/W99685_RAM_PAGE_SIZE; - printk("W99685 firmware size: %d\n", ISPFW_SIZE); - if(ISPFW_SIZE > W99685_RAM_SIZE) - { - printk("W99685 firmware size beyond DRAM size\n"); - result = -EFBIG; - goto out; - } - - for(i = 0; i < fw_page_num; i++) - { - for(k = 0; k < W99685_RAM_PAGE_SIZE; k+=W99685_ISP_WRITE_SIZE, firmware_datap+=W99685_ISP_WRITE_SIZE) - { -WriteReg_retry: - result = W99685_WriteReg(dev, W99685_ISP_BUFFER_ADDR+k, firmware_datap, W99685_ISP_WRITE_SIZE); - if(result == -ETIMEDOUT&&retry > 0) - { - retry--; - goto WriteReg_retry; - } - if(result < 0) - { - printk("Upload W99685 ISP firmware failed\n"); - goto out; - } - } - result = W99685_ProgramPage(dev); - if(result < 0) - { - printk("W99685 program firmware page failed\n"); - goto out; - } - } - - //handle not a multiple of 512 byte firmware data - if((fw_page_num < W99685_RAM_PAGE_NUM) && (ISPFW_SIZE%W99685_RAM_PAGE_SIZE)) { - memset(tmpbuf, 0xff, sizeof(tmpbuf)); - memcpy(tmpbuf, firmware_datap, ISPFW_SIZE%W99685_RAM_PAGE_SIZE); - firmware_datap = tmpbuf; - for(k = 0; k < W99685_RAM_PAGE_SIZE; k+=W99685_ISP_WRITE_SIZE, firmware_datap+=W99685_ISP_WRITE_SIZE) - { - result = W99685_WriteReg(dev, W99685_ISP_BUFFER_ADDR+k, firmware_datap, W99685_ISP_WRITE_SIZE); - if(result < 0) - { - printk("Upload W99685 ISP firmware failed\n"); - goto out; - } - } - result = W99685_ProgramPage(dev); - if(result < 0) - { - printk("W99685 program firmware page failed\n"); - goto out; - } - i++; - } - - memset(tmpbuf, 0xff, sizeof(tmpbuf)); - - for(; i < W99685_RAM_PAGE_NUM; i++) - { - firmware_datap = tmpbuf; - for(k = 0; k < W99685_RAM_PAGE_SIZE; k+=W99685_ISP_WRITE_SIZE, firmware_datap+=W99685_ISP_WRITE_SIZE) - { - result = W99685_WriteReg(dev, W99685_ISP_BUFFER_ADDR+k, firmware_datap, W99685_ISP_WRITE_SIZE); - if(result < 0) - { - printk("Upload W99685 ISP firmware failed\n"); - goto out; - } - } - result = W99685_ProgramPage(dev); - if(result < 0) - { - printk("W99685 program firmware page failed\n"); - goto out; - } - } -out: - return result; -} - -static int -W99685ISP_INIT(struct usb_device *dev) -{ - int result = 0; - int action; - struct usb_args init_args; - int i = 0; - // Here, Enable W99685 ISP mode - wait_ms(200); - if (usb_clear_halt(dev, usb_sndbulkpipe(dev, 0))) { - printk("Failed to reset control endpoint.\n"); - } - INIT_USBARGS(&init_args, 0x16, 0x00, 0x01, 0x00); - action = USB_WRITE; - result = W99683IO(dev, action, &init_args, NULL); - if(result < 0) - { - printk("Enable W99685 ISP mode failed\n"); - goto out; - } - - wait_ms(200); - result = W99685_DOISP(dev); - if(result < 0) - { - printk("W99685 do ISP failed\n"); - goto out; - } - - result = W99685_Reset2Ram(dev); - if(result < 0) - { - printk("W99685 reset to DRAM failed\n"); - goto out; - } -out: - return result; -} - -static int -W99683IO(struct usb_device *dev, int Action,struct usb_args *arg, unsigned char *buf) -{ - int result = 0; - //printk("request: %x, value: %x, index: %x, length: %x", arg->request, arg->value,\ - arg->index, arg->length); - if(Action == USB_WRITE) { - result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - arg->request, USB_TYPE_VENDOR| - USB_RECIP_DEVICE|USB_DIR_OUT, - arg->value, arg->index, buf, - arg->length, HZ*5); - //printk(" result: %d\n", result); - } - else - { - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - arg->request, USB_TYPE_VENDOR| - USB_RECIP_DEVICE|USB_DIR_IN, - arg->value, arg->index, buf, - arg->length, HZ*5); -// printk("get: %d\n", result); - } - return result; -} - -static int -w99683_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd, - void *arg) -{ - struct usb_W99683 *w683 = vdev->priv; - int args; - int pipe, nb, ret = 0; - struct ctrlmsg_ioctl cmsg; - - PDEBUG(5, "IOCtl: 0x%X", cmd); - //printk("IOCtl: 0x%X", cmd); - - if (!w683->dev) - return -EIO; - memset(w683->iobuf, 0, 64*sizeof(char)); - switch (cmd) { - case IOCTLGET: - PDEBUG(4, "IOCTLGET"); - if(arg == NULL) - return -EFAULT; - if (copy_from_user(&cmsg, (void *)arg, sizeof(cmsg))) - return -EFAULT; - - nb = le16_to_cpup(&cmsg.req.length); - - if (nb > (64*sizeof(char))) - return -EINVAL; - - ret = W99683IO(w683->dev, USB_READ, &(cmsg.req), w683->iobuf); - if (nb > 0 && copy_to_user(cmsg.data, w683->iobuf, nb)) - return -EFAULT; -// printk("get2: %d\n", ret); - return ret; - case IOCTLSET: - PDEBUG(4, "IOCTLSET"); - //printk("IOCTLSET"); - if (copy_from_user(&cmsg, (void *)arg, sizeof(cmsg))) - return -EFAULT; - - nb = le16_to_cpup(&cmsg.req.length); - - if (nb > (64*sizeof(char))) - return -EINVAL; - if(nb == 0) { - ret = W99683IO(w683->dev, USB_WRITE, &(cmsg.req), NULL); - } - else if(nb > 0) { - if (copy_from_user(w683->iobuf, cmsg.data, nb)) - return -EFAULT; - ret = W99683IO(w683->dev, USB_WRITE, &(cmsg.req), w683->iobuf); - } - else - return -EINVAL; - return ret; - case IOCTLGETCLASS: - if(!arg) - { - return -EINVAL; - } - if(copy_to_user(arg, vdev->name, strlen(vdev->name)+1)) - { - return -EFAULT; - } - return strlen(vdev->name)+1; - default: - PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd); - return -ENOIOCTLCMD; - } /* end switch */ - - return ret; -} - - -/**************************************************************************** - * - * V4L 1 API - * - ***************************************************************************/ -static int -w99683_v4l1_open(struct video_device *vdev, int flags) -{ - struct usb_W99683 *w683 = vdev->priv; - int err, i; - - PDEBUG(4, "opening"); - //printk(" debug: %x , orign: %x\n", w683_debug, w683); - down(&w683->lock); - - err = -EBUSY; - if (w683->user) { - PDEBUG(4, "erro user count: %d", w683->user); - goto out; - } - - err = -ENOMEM; - - /* In case app doesn't set them... */ - w683->user++; - err = 0; -out: - up(&w683->lock); - - return err; -} - -static void -w99683_v4l1_close(struct video_device *vdev) -{ - struct usb_W99683 *w683 = vdev->priv; - - PDEBUG(4, "W996983_close"); - - down(&w683->lock); - - w683->user--; - - up(&w683->lock); - - /* Device unplugged while open. Only a minimum of unregistration is done - * here; the disconnect callback already did the rest. */ - if (!w683->dev) { - video_unregister_device(&w683->vdev); - if(w683->rawbuf) { - kfree(w683->rawbuf); - kfree(w683->iobuf); - w683->rawbuf = NULL; - } - kfree(w683); - w683 = NULL; - } -} - -static inline long -w99683_v4l1_read(struct video_device *vdev, char *buf, unsigned long count, - int noblock) -{ - struct usb_W99683 *w683 = vdev->priv; - struct usb_device *dev = w683->dev; - int i, rc = 0; - int result; - char *ibuf = w683->rawbuf; - int partial; - - - if (down_interruptible(&w683->lock)) - return -EINTR; - - PDEBUG(4, "%ld bytes, noblock=%d", count, noblock); - - if (!vdev || !buf ) { - printk("vdev || !buf \n"); - rc = -EFAULT; - goto error; - } - - if (!w683->dev) { - printk("!w683->dev\n"); - rc = -EIO; - goto error; - } - - if(count > W683BUF_SIZE) { - printk("count > W683BUF_SIZE\n"); - rc = -EFAULT; - goto error; - } - - result = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, 1), ibuf, count, &partial, HZ*10); - - if(result < 0) { - printk("result < 0, %d\n", result); - rc = result; - goto error; - } - - rc = partial; - - if (copy_to_user(buf, ibuf, partial)) { - printk("copy_to_user\n"); - rc = -EFAULT; - goto error; - } - up(&w683->lock); - - return count; - -error: - up(&w683->lock); - return rc; -} - - -static long -w99683_v4l1_write(struct video_device *vdev, const char *buf, - unsigned long count, int noblock) -{ - return -EINVAL; -} - - -static int -w99683_v4l1_ioctl(struct video_device *vdev, unsigned int cmd, void *arg) -{ - int rc; - struct usb_W99683 *w683 = vdev->priv; - - if (down_interruptible(&w683->lock)) - return -EINTR; - //printk("ioctl: %x\n", cmd); - rc = w99683_v4l1_ioctl_internal(vdev, cmd, arg); - - up(&w683->lock); - return rc; -} - -static struct video_device vdev_template = { - owner: THIS_MODULE, - name: W99685_DEVICECLASS, //default for 685 - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_OV511, - open: w99683_v4l1_open, - close: w99683_v4l1_close, - read: w99683_v4l1_read, - write: w99683_v4l1_write, - ioctl: w99683_v4l1_ioctl, -}; - - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - -static struct proc_dir_entry *W99683_proc_entry = NULL; -extern struct proc_dir_entry *video_proc_entry; - -static void -proc_W99683_create(void) -{ - /* No current standard here. Alan prefers /proc/video/ as it keeps - * /proc "less cluttered than /proc/randomcardifoundintheshed/" - * -claudio - */ - if (video_proc_entry == NULL) { - err("Error: /proc/video/ does not exist"); - return; - } - - W99683_proc_entry = create_proc_entry("W99683", S_IFDIR, - video_proc_entry); - - if (W99683_proc_entry) - W99683_proc_entry->owner = THIS_MODULE; - else - err("Unable to create /proc/video/W99683"); -} - -static void -proc_W99683_destroy(void) -{ - PDEBUG(3, "removing /proc/video/W99683"); - - if (W99683_proc_entry == NULL) - return; - - remove_proc_entry("W99683", video_proc_entry); -} -#endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */ - -/**************************************************************************** - * - * USB routines - * - ***************************************************************************/ -static void * -W99683_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) -{ - struct usb_interface_descriptor *interface; - struct usb_endpoint_descriptor *endpoint; - struct usb_W99683 *w683; - int i; - int registered = 0; - UINT8 mul = 1; - - PDEBUG(1, "probing for device..."); - printk("probing for device..., %d\n", ifnum); - - /* We don't handle multi-config cameras */ - if (dev->descriptor.bNumConfigurations != 1) - return NULL; - - interface = &dev->actconfig->interface[ifnum].altsetting[0]; - endpoint = interface[ifnum].endpoint; - - /*printk("endponts: %d\n", interface->bNumEndpoints); - for(i = 0; i < interface->bNumEndpoints; i++) - { - if(IS_EP_BULK_IN(endpoint[i])) - printk("get bulk in: %d\n", i); - }*/ - /* Checking vendor/product should be enough, but what the hell */ - //printk("bInterfaceClass: %x, bInterfaceSubClass: %x\n", interface->bInterfaceClass, interface->bInterfaceSubClass); - if (interface->bInterfaceClass != 0x00) - return NULL; - if (interface->bInterfaceSubClass != 0x00) - return NULL; - - /* Since code below may sleep, we use this as a lock */ - MOD_INC_USE_COUNT; - - if ((w683 = kmalloc(sizeof(*w683), GFP_KERNEL)) == NULL) { - err("couldn't kmalloc ov struct"); - goto error_out; - } - - w683_debug = w683; - memset(w683, 0, sizeof(*w683)); - - //printk("probe: user: %d\n", w683->user); - w683->dev = dev; - w683->iface = interface->bInterfaceNumber; - w683->user = 0; - //printk("probe: user: %d\n", w683->user); - printk("probe: vendorID: %x, ProductID: %x\n", dev->descriptor.idVendor, dev->descriptor.idProduct); -#if 0 - if ((dev->descriptor.idVendor != W99683_VENDOR) || - (dev->descriptor.idProduct != W99683i_PRODUCT)) { - err("Unknown product ID 0x%x or Vendor ID 0x%x", dev->descriptor.idProduct, dev->descriptor.idVendor); - goto error_dealloc; - } -#endif - if ((dev->descriptor.idVendor == W99683_VENDOR) && - (dev->descriptor.idProduct == W99683i_PRODUCT)) { - strcpy(vdev_template.name, W99683_DEVICECLASS); - printk("Find W99683 USB Camera\n"); - goto init; - } - else if ((dev->descriptor.idVendor == W99685ISP_VENDOR) && - (dev->descriptor.idProduct == W99685iISP_PRODUCT)) { - printk("Find W99685 USB ISP\n"); - //usb_show_device(dev); - if(!strcmp(vdev_template.name, W99685_DEVICECLASS)) { - if(W99685ISP_INIT(dev) < 0) - goto error_dealloc; - } - else { - strcpy(vdev_template.name, W9968x_ISPMODE); - } - } - else if ((dev->descriptor.idVendor == W99685_VENDOR) && - (dev->descriptor.idProduct == W99685i_PRODUCT)) { - mul = 2; - strcpy(vdev_template.name, W99685_DEVICECLASS); - goto init; - } - else { - err("Unknown product ID 0x%x or Vendor ID 0x%x", dev->descriptor.idProduct, dev->descriptor.idVendor); - goto error_dealloc; - } -init: - init_waitqueue_head(&w683->wq); - - init_MUTEX(&w683->param_lock); - init_MUTEX(&w683->lock); - printk("video name: %s\n", vdev_template.name); - memcpy(&w683->vdev, &vdev_template, sizeof(vdev_template)); - w683->vdev.priv = w683; - - /* Use the next available one */ - if (video_register_device(&w683->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { - err("video_register_device failed"); - goto error; - } - - info("Device registered on minor %d", w683->vdev.minor); - - w683->rawbuf = kmalloc(W683BUF_SIZE*mul, GFP_KERNEL); - if (!w683->rawbuf) - goto error; - - w683->rawbuf = (char *)((unsigned long)w683->rawbuf|0x80000000); - - w683->iobuf = kmalloc(64*sizeof(unsigned char), GFP_KERNEL); - if (!w683->iobuf) - goto error1; - - w683->iobuf = (unsigned char *)((unsigned long)w683->iobuf|0x80000000); - - - MOD_DEC_USE_COUNT; - return w683; -error1: - kfree(w683->rawbuf); -error: - err("Camera initialization failed"); - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - /* Safe to call even if entry doesn't exist */ -#endif - - usb_driver_release_interface(&W99683_driver, - &dev->actconfig->interface[w683->iface]); - -error_dealloc: - if (w683) { - kfree(w683); - w683 = NULL; - } - -error_out: - MOD_DEC_USE_COUNT; - return NULL; -} - - -static void -W99683_disconnect(struct usb_device *dev, void *ptr) -{ - struct usb_W99683 *w683 = (struct usb_W99683 *) ptr; - int n; - - MOD_INC_USE_COUNT; - - printk("W99683 is disconnected\n"); - - /* We don't want people trying to open up the device */ -#if 1 - if (!w683->user) - video_unregister_device(&w683->vdev); - else { - //PDEBUG(3, "Device open...deferring video_unregister_device"); - printk("Device open...deferring video_unregister_device\n"); - //for later application to close ?? - } -#else - video_unregister_device(&w683->vdev); -#endif - - if (waitqueue_active(&w683->wq)) - wake_up_interruptible(&w683->wq); - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - // destroy_proc_ov511_cam(w683); -#endif - - usb_driver_release_interface(&W99683_driver, - &w683->dev->actconfig->interface[w683->iface]); - w683->dev = NULL; - - /* Free the memory */ - if(w683 && !w683->user) { - if(w683->rawbuf) { - kfree(w683->rawbuf); - kfree(w683->iobuf); - w683->rawbuf = NULL; - } - kfree(w683); - w683 = NULL; - } - - MOD_DEC_USE_COUNT; -} - -static struct usb_driver W99683_driver = { - name: "W99683", - id_table: W99683_table, - probe: W99683_probe, - disconnect: W99683_disconnect -}; - -/****************************************************************************** - * - * Module Routines - * - ******************************************************************************/ -static int __init -usb_W99683_init(void) -{ -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - proc_W99683_create(); -#endif - //printk("init start user: %x\n", &W99683_driver); - if(&W99683_driver == NULL) - return -1; -// printk("init start user: %d\n", w683_debug->user); - if (usb_register(&W99683_driver) < 0) { - printk("Can't register W99682 driver\n"); - return -1; - } - // FIXME: Don't know how to determine this yet -// ov51x_mmx_available = 0; - -#if defined (__i386__) -// if (test_bit(X86_FEATURE_MMX, &boot_cpu_data.x86_capability)) -// ov51x_mmx_available = 1; -#endif - info(DRIVER_VERSION " : " DRIVER_DESC); - return 0; -} - -static void __exit -usb_W99683_exit(void) -{ - usb_deregister(&W99683_driver); - info("driver deregistered"); - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) - proc_W99683_destroy(); -#endif -} - -module_init(usb_W99683_init); -module_exit(usb_W99683_exit); diff --git a/uClinux-2.4.20-uc1/drivers/usb/W99683.h b/uClinux-2.4.20-uc1/drivers/usb/W99683.h deleted file mode 100755 index 5a2f2d9..0000000 --- a/uClinux-2.4.20-uc1/drivers/usb/W99683.h +++ /dev/null @@ -1,263 +0,0 @@ -#ifndef __LINUX_W99683_H -#define __LINUX_W99683_H - -#include -#include -#include - - -//#define W99683_DEBUG /* Turn on debug messages */ - -#ifdef W99683_DEBUG - #define PDEBUG(level, fmt, args...) \ - info("[" __PRETTY_FUNCTION__ ":%d] " fmt,\ - __LINE__ , ## args) -#else - #define PDEBUG(level, fmt, args...) do {} while(0) -#endif - -/* some type defines */ -#define UINT16 unsigned short -#define INT16 short -#define UINT8 unsigned char -#define UINT32 unsigned int - -/*vendor ID and product ID */ -#define W99683_VENDOR 0x416 -#define W99683i_PRODUCT 0x6830 -#define W99685ISP_VENDOR 0x416 -#define W99685iISP_PRODUCT 0x9680 -#define W99685_VENDOR 0x416 -#define W99685i_PRODUCT 0x6850 - -#define W99683_DEVICECLASS "W99683usb" -#define W99685_DEVICECLASS "W99685usb" -#define W9968x_ISPMODE "W9968xisp" - -#define W99685_RAM_SIZE 16*1024 -#define W99685_RAM_PAGE_SIZE 512 -#define W99685_RAM_PAGE_NUM 32 -#define W99685_ISP_BUFFER_ADDR 0xa000 -#define W99685_ISP_WRITE_SIZE 64 - -//USB direction -#define USB_DIR_OUT 0 -#define USB_DIR_IN 0x80 - -//define Read and Write -#define USB_READ 0 -#define USB_WRITE 1 - -#define IS_EP_BULK(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0) -#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) - -//define resolution -#define R1280X1024 0x80 //No support currently -#define R1280X960 0x40 //No support currently -#define R640X480 0x20 -#define R352X288 0x10 -#define R320X240 0x08 -#define R176X144 0x04 -#define R160X120 0x02 //No support currently -#define R128X96 0x01 //No support currently - - -/*--------------------------------------- For the New W99683 ----------------------------------------*/ -typedef struct _VENDOR_COMMAND { - unsigned char rBits; - unsigned char bRequest; - unsigned short iValue; - unsigned short iIndex; - unsigned short DataLen; -}VENDOR_COMMAND, *PVENDOR_COMMAND; - -#define REG_READ 0x00 -#define REG_WRITE 0x01 -#define I2C_READ 0x02 -#define I2C_WRITE 0x03 -#define MEM_READ 0x04 -#define MEM_WRITE 0x05 -#define GET_VERSION 0x10 -#define ENABLE_ISP 0x11 -#define BULK_SETTING 0x13 - -#define FAIL_FUNCTION_CALL 1 - -#define ENGCLKCR 0x03 -#define ENGOPCR 0x04 -#define SystemCR 0x16 -#define DisplayOutputCR 0x9f -#define TVEncoderCR 0x2d0 -// For DSP engine -#define DSPFunctionCR 0x101 -#define DSPCropCR1 0x11c -#define DSPCropCR2 0x11d -#define DSPCropCR3 0x11e -#define DSPCropCR4 0x11f -#define DSPCropCR5 0x120 -#define DSPCropCR6 0x121 -#define DSPCropCR7 0x122 -#define DSPCropCR8 0x123 -#define DSPVideoQuaCR1 0x135 -#define DSPVideoQuaCR2 0x136 -#define DSPVideoQuaCR3 0x137 -#define DSPVideoQuaCR4 0x138 -#define DSPVideoQuaCR5 0x139 -#define DSPVideoQuaCR6 0x13a -#define DSPVideoQuaCR7 0x13b - -// For VPRE engine -#define PEConfig1 0x200 -#define PEConfig2 0x201 -#define CapYUVXScalM 0x220 -#define CapYUVXScalN 0x221 -#define CapYUVYScalM 0x222 -#define CapYUVYScalN 0x223 - -// For JPEG engine -#define JPEGModeCR 0x280 -#define JPEGHeaderCR 0x281 -#define JPEGPriScalUpCR 0x282 -#define JPEGPriHeightL 0x28B -#define JPEGPriHeightH 0x28C -#define JPEGPriWidthL 0x28D -#define JPEGPriWidthH 0x28E -#define JPEGPriRestartL 0x293 -#define JPEGPriRestartH 0x294 -#define JPEGYStrideL 0x2ac -#define JPEGYStrideH 0x2ad -#define JPEGUStrideL 0x2ae -#define JPEGUStrideH 0x2af -#define JPEGVStrideL 0x2b0 -#define JPEGVStrideH 0x2b1 - -#define JPEGLumQtblReg 0x300 -#define JPEGChroQtblReg 0x340 - -#define W683BUF_SIZE 32*1024 //same to the application - - -//W99683 struct -struct usb_W99683 { - struct video_device vdev; - - /* Device structure */ - struct usb_device *dev; - - int customid; - int desc; - unsigned char iface; - - /* Determined by sensor type */ - int maxwidth; - int maxheight; - int minwidth; - int minheight; - - int brightness; - int colour; - int contrast; - int hue; - int whiteness; - int exposure; - int auto_brt; /* Auto brightness enabled flag */ - int auto_gain; /* Auto gain control enabled flag */ - int auto_exp; /* Auto exposure enabled flag */ - int backlight; /* Backlight exposure algorithm flag */ - - struct semaphore lock; /* Serializes user-accessible operations */ - int user; /* user count for exclusive use */ - char *rawbuf; - char *iobuf; - wait_queue_head_t wq; /* Processes waiting */ - - int snap_enabled; /* Snapshot mode enabled */ - - struct semaphore param_lock; /* params lock for this camera */ - - /* /proc entries, relative to /proc/video/ov511/ */ - struct proc_dir_entry *proc_devdir; /* Per-device proc directory */ - struct proc_dir_entry *proc_info; /* /info entry */ - struct proc_dir_entry *proc_button; /* /button entry */ - struct proc_dir_entry *proc_control; /* /control entry */ -}; - -struct usb_args { - __u8 request; - __u16 value; - __u16 index; - __u16 length; -}; - -struct ctrlmsg_ioctl { - struct usb_args req; - void* data; -}; - -#define INIT_USBARGS(argp, req, val, ind, len) \ -do {\ - (argp)->request = req;\ - (argp)->value = val;\ - (argp)->index = ind;\ - (argp)->length = len;\ -}while(0) -#define IOCTLGET _IOR('v',1,struct ctrlmsg_ioctl) /* Get capabilities */ -#define IOCTLSET _IOR('v',2,struct ctrlmsg_ioctl) /* Set capabilities */ -#define IOCTLGETCLASS _IOR('v',3,UINT32) /* Get Device Class */ -#endif - -/* -bus/device idVendor/idProduct -001/001 0000/0000 - wTotalLength: 25 - bNumInterfaces: 1 - bConfigurationValue: 1 - iConfiguration: 0 - bmAttributes: 40h - MaxPower: 0 - bInterfaceNumber: 0 - bAlternateSetting: 0 - bNumEndpoints: 1 - bInterfaceClass: 9 - bInterfaceSubClass: 0 - bInterfaceProtocol: 0 - iInterface: 0 - bEndpointAddress: 81h - bmAttributes: 03h - wMaxPacketSize: 8 - bInterval: 255 - bRefresh: 0 - bSynchAddress: 0 -001/006 0416/6830 - wTotalLength: 103 - bNumInterfaces: 1 - bConfigurationValue: 1 - iConfiguration: 0 - bmAttributes: 80h - MaxPower: 250 - bInterfaceNumber: 0 - bAlternateSetting: 0 - bNumEndpoints: 3 - bInterfaceClass: 0 - bInterfaceSubClass: 0 - bInterfaceProtocol: 0 - iInterface: 0 - bEndpointAddress: 81h - bmAttributes: 02h - wMaxPacketSize: 64 - bInterval: 1 - bRefresh: 0 - bSynchAddress: 0 - bEndpointAddress: 02h - bmAttributes: 02h - wMaxPacketSize: 64 - bInterval: 1 - bRefresh: 0 - bSynchAddress: 0 - bEndpointAddress: 83h - bmAttributes: 03h - wMaxPacketSize: 8 - bInterval: 1 - bRefresh: 0 - bSynchAddress: 0 -*/ diff --git a/uClinux-2.4.20-uc1/drivers/usb/W99685ISP.h b/uClinux-2.4.20-uc1/drivers/usb/W99685ISP.h deleted file mode 100755 index 487282f..0000000 --- a/uClinux-2.4.20-uc1/drivers/usb/W99685ISP.h +++ /dev/null @@ -1,708 +0,0 @@ -#ifndef __W99685ISP_H__ -#define __W99685ISP_H__ - 0x02, 0x29, 0x50, 0x02, 0x00, 0x06, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, - 0x75, 0xD0, 0x08, 0x90, 0xB0, 0x06, 0xE0, 0x20, 0xE1, 0x03, 0x02, 0x00, 0xF8, 0x90, 0xB2, 0x4C, - 0xE0, 0x20, 0xE2, 0x03, 0x02, 0x00, 0xF8, 0x44, 0x04, 0xF0, 0x90, 0x80, 0xF2, 0xE0, 0x60, 0x10, - 0x90, 0x81, 0x62, 0xE0, 0xB4, 0x01, 0x09, 0x90, 0x80, 0xF2, 0xE0, 0x14, 0xF0, 0x02, 0x00, 0xF8, - 0x90, 0x81, 0x62, 0xE0, 0xB4, 0x01, 0x11, 0x90, 0x80, 0xEF, 0xE0, 0x60, 0x0B, 0x90, 0x80, 0xF2, - 0x74, 0x02, 0xF0, 0x90, 0x81, 0x7D, 0x14, 0xF0, 0x90, 0xB0, 0x55, 0xE0, 0x30, 0xE3, 0x08, 0x54, - 0xF1, 0xF0, 0x44, 0x06, 0xF0, 0x80, 0x0A, 0x90, 0xB0, 0x55, 0xE0, 0x54, 0xF1, 0xF0, 0x44, 0x08, - 0xF0, 0x90, 0x80, 0x00, 0xE0, 0x60, 0x03, 0x02, 0x00, 0xF8, 0x90, 0x81, 0x7C, 0xE0, 0x60, 0x68, - 0x90, 0x81, 0x69, 0xE0, 0x90, 0x81, 0x87, 0xF0, 0x90, 0x81, 0x63, 0xE0, 0x30, 0xE6, 0x2A, 0x90, - 0x81, 0x87, 0xE0, 0x75, 0xF0, 0x09, 0xA4, 0x24, 0xF1, 0xF9, 0x74, 0x24, 0x35, 0xF0, 0xFA, 0x7B, - 0xFF, 0x90, 0x81, 0x84, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0x7F, 0xBC, 0x7E, 0x02, - 0x7D, 0xF0, 0x7C, 0x00, 0x12, 0x23, 0x6C, 0x80, 0x28, 0x90, 0x81, 0x87, 0xE0, 0x75, 0xF0, 0x09, - 0xA4, 0x24, 0xBB, 0xF9, 0x74, 0x24, 0x35, 0xF0, 0xFA, 0x7B, 0xFF, 0x90, 0x81, 0x84, 0xEB, 0xF0, - 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0x7F, 0x80, 0x7E, 0x02, 0x7D, 0xE0, 0x7C, 0x01, 0x12, 0x23, - 0x6C, 0x90, 0x81, 0x7C, 0xE4, 0xF0, 0x80, 0x10, 0x90, 0xB0, 0x04, 0xE0, 0x44, 0x08, 0xF0, 0x54, - 0xF7, 0xF0, 0x90, 0x80, 0x00, 0x74, 0x01, 0xF0, 0x90, 0xB0, 0x06, 0xE0, 0x20, 0xE3, 0x03, 0x02, - 0x02, 0x06, 0x90, 0xB2, 0x94, 0xE0, 0x20, 0xE3, 0x03, 0x02, 0x02, 0x06, 0x90, 0x80, 0x00, 0xE4, - 0xF0, 0x90, 0x81, 0x7B, 0x04, 0xF0, 0x90, 0xB2, 0xD6, 0xE0, 0x90, 0x81, 0x78, 0xF0, 0x90, 0xB2, - 0xD7, 0xE0, 0x90, 0x81, 0x79, 0xF0, 0x90, 0xB2, 0xD8, 0xE0, 0x90, 0x81, 0x7A, 0xF0, 0x90, 0xB2, - 0xA4, 0xE0, 0x30, 0xE0, 0x25, 0x90, 0x81, 0x74, 0x74, 0x01, 0xF0, 0x90, 0xB2, 0xD3, 0xE0, 0x90, - 0x81, 0x83, 0xF0, 0x90, 0xB2, 0xD4, 0xE0, 0x90, 0x81, 0x82, 0xF0, 0x90, 0xB2, 0xD5, 0xE0, 0x90, - 0x81, 0x81, 0xF0, 0x90, 0x81, 0x80, 0xE4, 0xF0, 0x80, 0x22, 0x90, 0x81, 0x74, 0xE4, 0xF0, 0x90, - 0xB2, 0xD0, 0xE0, 0x90, 0x81, 0x83, 0xF0, 0x90, 0xB2, 0xD1, 0xE0, 0x90, 0x81, 0x82, 0xF0, 0x90, - 0xB2, 0xD2, 0xE0, 0x90, 0x81, 0x81, 0xF0, 0x90, 0x81, 0x80, 0xE4, 0xF0, 0x90, 0xB2, 0x94, 0xE0, - 0x44, 0x88, 0xF0, 0x90, 0x81, 0x80, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, - 0xFF, 0x78, 0x01, 0x12, 0x2B, 0x8B, 0x90, 0x81, 0x80, 0x12, 0x2B, 0x9E, 0x90, 0x81, 0x80, 0xE0, - 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x02, 0xFF, 0xE4, 0x3E, 0xFE, 0xE4, - 0x3D, 0xFD, 0xE4, 0x3C, 0xFC, 0x90, 0x81, 0x80, 0x12, 0x2B, 0x9E, 0x90, 0xB0, 0x30, 0x74, 0x03, - 0xF0, 0x90, 0x81, 0x83, 0xE0, 0x90, 0xB0, 0x31, 0xF0, 0x90, 0x81, 0x82, 0xE0, 0x90, 0xB0, 0x32, - 0xF0, 0x90, 0x81, 0x81, 0xE0, 0x90, 0xB0, 0x33, 0xF0, 0x90, 0x81, 0x80, 0xE0, 0x90, 0xB0, 0x34, - 0xF0, 0x90, 0xB0, 0x30, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0xB0, 0x35, 0x74, 0xFF, 0xF0, 0xA3, 0x74, - 0xE1, 0xF0, 0x90, 0xB0, 0x35, 0xE4, 0xF0, 0xA3, 0x74, 0x04, 0xF0, 0x90, 0x80, 0xF1, 0xE0, 0x90, - 0xB0, 0x35, 0xF0, 0xA3, 0xE4, 0xF0, 0x90, 0xB0, 0x06, 0xE0, 0x30, 0xE5, 0x03, 0x12, 0x0B, 0x8A, - 0x90, 0xB0, 0x06, 0xE0, 0x30, 0xE6, 0x03, 0x12, 0x0B, 0x9D, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, - 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x12, 0x03, 0x9B, 0x75, 0xA8, 0x81, 0x90, 0x80, 0x01, 0xE0, 0xB4, - 0x01, 0x2C, 0xE4, 0xF0, 0x90, 0x80, 0xE7, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, - 0xE0, 0xFF, 0x90, 0x81, 0xA0, 0x12, 0x2B, 0x9E, 0xE4, 0x90, 0x81, 0xA4, 0xF0, 0x90, 0x80, 0xEB, - 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x16, 0x80, 0x90, 0x81, - 0x7D, 0xE0, 0x60, 0xC7, 0x90, 0x81, 0x9B, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x81, 0x7D, 0xF0, 0x90, - 0x80, 0xF1, 0xE0, 0x04, 0xFF, 0x74, 0x01, 0xC8, 0xEF, 0xC8, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, - 0xFC, 0x90, 0x81, 0x9B, 0xF0, 0x7F, 0x01, 0x90, 0x81, 0x9B, 0xE0, 0xFE, 0x90, 0x80, 0xF0, 0xE0, - 0x5E, 0x60, 0x12, 0x90, 0x80, 0xF1, 0xE0, 0x2F, 0xF0, 0xE0, 0xC3, 0x94, 0x04, 0x40, 0x12, 0xE0, - 0x24, 0xFC, 0xF0, 0x80, 0x0C, 0xEE, 0x25, 0xE0, 0x90, 0x81, 0x9B, 0xF0, 0x0F, 0xEF, 0xB4, 0x04, - 0xD6, 0x90, 0x80, 0xF1, 0xE0, 0x44, 0xF0, 0xFF, 0x90, 0x81, 0x9A, 0xF0, 0xFB, 0x7F, 0x4A, 0x7D, - 0x02, 0x12, 0x27, 0x31, 0x02, 0x02, 0x2B, 0x22, 0x41, 0x80, 0x00, 0x00, 0x41, 0x80, 0xA9, 0x00, - 0x41, 0x80, 0xAA, 0x00, 0x42, 0x80, 0xAB, 0x00, 0x00, 0x41, 0x80, 0xAD, 0x00, 0x41, 0x80, 0xAE, - 0x00, 0x41, 0x80, 0xAF, 0x00, 0x41, 0x80, 0xB0, 0x00, 0x41, 0x80, 0xB1, 0x00, 0x41, 0x80, 0xB2, - 0x00, 0x41, 0x80, 0xB3, 0x00, 0x41, 0x80, 0xB4, 0x00, 0x44, 0x80, 0xDD, 0x00, 0x00, 0x00, 0x00, - 0x41, 0x80, 0x01, 0x00, 0x44, 0x80, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x41, 0x80, 0xE5, 0x00, 0x41, - 0x80, 0xEF, 0x00, 0x41, 0x80, 0xF0, 0xFF, 0x41, 0x80, 0xF1, 0x00, 0x41, 0x80, 0xF2, 0x00, 0x41, - 0x80, 0xE6, 0x00, 0x41, 0x80, 0xF8, 0x00, 0x60, 0x63, 0x80, 0xFA, 0x00, 0x08, 0xF0, 0x03, 0x00, - 0x80, 0xE9, 0x0D, 0x88, 0x10, 0x80, 0x47, 0x40, 0x00, 0x01, 0x24, 0x08, 0x0C, 0xB7, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x40, 0x54, 0x0A, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, - 0x7D, 0x00, 0x41, 0x81, 0x7E, 0x00, 0x41, 0x81, 0x7F, 0x00, 0x00, 0x12, 0x03, 0xBA, 0x12, 0x05, - 0x18, 0x12, 0x09, 0x12, 0x12, 0x04, 0x09, 0x12, 0x09, 0x7B, 0x90, 0xB0, 0x03, 0xE0, 0x44, 0x40, - 0xF0, 0xA3, 0xE0, 0x44, 0x40, 0xF0, 0x12, 0x0B, 0x08, 0x22, 0x90, 0xB0, 0x00, 0xE0, 0x54, 0xBF, - 0xF0, 0x90, 0xB0, 0x41, 0x74, 0x3E, 0xF0, 0xA3, 0x74, 0xC0, 0xF0, 0x90, 0xB0, 0x46, 0x74, 0xD0, - 0xF0, 0x90, 0xB0, 0x48, 0x74, 0xF4, 0xF0, 0x90, 0xB0, 0x02, 0x74, 0xFF, 0xF0, 0xE4, 0xF0, 0xA3, - 0x74, 0xE2, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0x90, 0xB0, 0x50, 0x74, 0x10, 0xF0, 0xE4, 0xFF, 0xFE, - 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF8, 0xBF, 0xD0, 0xF5, 0x90, 0xB0, 0x00, 0xE0, 0x44, - 0x40, 0xF0, 0x90, 0xB0, 0x05, 0x74, 0xFF, 0xF0, 0x22, 0xE4, 0x90, 0x81, 0x9C, 0xF0, 0x90, 0xB0, - 0x16, 0x74, 0x06, 0xF0, 0xE4, 0x90, 0x81, 0x7C, 0xF0, 0x90, 0x81, 0x5D, 0x74, 0x02, 0xF0, 0xA3, - 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0xE0, 0xF0, 0x7F, 0x4A, 0x12, 0x27, 0x12, - 0xEF, 0x60, 0x0A, 0x90, 0x81, 0x62, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0xC0, 0xF0, 0x90, 0xB2, 0x4D, - 0x74, 0xE3, 0xF0, 0x90, 0xB0, 0x48, 0x74, 0x11, 0xF0, 0x7F, 0x42, 0x12, 0x27, 0x12, 0xEF, 0x60, - 0x0A, 0x90, 0x81, 0x62, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0x90, 0x81, 0x62, 0xE0, 0x24, - 0xFE, 0x60, 0x4B, 0x04, 0x60, 0x03, 0x02, 0x04, 0xEF, 0x90, 0x81, 0x6A, 0x74, 0x80, 0xF0, 0xA3, - 0x74, 0x08, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x90, 0xB2, 0x4D, 0x74, 0x53, - 0xF0, 0xA3, 0x74, 0x0C, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0x74, 0x0C, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, - 0x81, 0x63, 0xE0, 0x30, 0xE6, 0x07, 0x90, 0xB2, 0xA1, 0xE0, 0x44, 0x50, 0xF0, 0x90, 0x81, 0x64, - 0x74, 0x4A, 0xF0, 0x12, 0x28, 0x52, 0x90, 0x80, 0xE6, 0x74, 0x02, 0xF0, 0x80, 0x41, 0x90, 0x81, - 0x6A, 0x74, 0x60, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0x74, 0x10, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0xA3, - 0x74, 0x07, 0xF0, 0x90, 0xB2, 0x4D, 0x74, 0xE3, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, - 0xA3, 0xF0, 0x90, 0x81, 0x64, 0x74, 0x42, 0xF0, 0x12, 0x27, 0xFE, 0x90, 0x81, 0x9C, 0xE0, 0x60, - 0x08, 0x90, 0x80, 0xE6, 0x74, 0x01, 0xF0, 0x80, 0x06, 0x90, 0x80, 0xE6, 0x74, 0x02, 0xF0, 0x12, - 0x07, 0xE3, 0x90, 0xB2, 0x4E, 0xE0, 0x90, 0x81, 0x65, 0xF0, 0x90, 0xB2, 0x4F, 0xE0, 0x90, 0x81, - 0x66, 0xF0, 0x90, 0xB2, 0x50, 0xE0, 0x90, 0x81, 0x67, 0xF0, 0x90, 0xB2, 0x51, 0xE0, 0x90, 0x81, - 0x68, 0xF0, 0xE4, 0x90, 0x81, 0x61, 0xF0, 0x22, 0xE4, 0x90, 0xB2, 0x02, 0xF0, 0xA3, 0x74, 0xC2, - 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0x74, 0x1A, 0xF0, 0xA3, 0x74, 0x04, 0xF0, - 0xE4, 0xA3, 0xF0, 0xA3, 0x74, 0xB0, 0xF0, 0xA3, 0x74, 0x04, 0xF0, 0xE4, 0x90, 0xB2, 0x0E, 0xF0, - 0xA3, 0x74, 0x46, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0x74, 0x9E, 0xF0, 0xA3, - 0x74, 0x07, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0x74, 0x34, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x90, 0xB2, - 0x02, 0xE0, 0x90, 0xB2, 0xB8, 0xF0, 0x90, 0xB2, 0x03, 0xE0, 0x90, 0xB2, 0xB9, 0xF0, 0x90, 0xB2, - 0x04, 0xE0, 0x90, 0xB2, 0xBA, 0xF0, 0x90, 0xB2, 0x05, 0xE0, 0x90, 0xB2, 0xBB, 0xF0, 0x90, 0xB2, - 0x06, 0xE0, 0x90, 0xB2, 0xBC, 0xF0, 0x90, 0xB2, 0x07, 0xE0, 0x90, 0xB2, 0xBD, 0xF0, 0x90, 0xB2, - 0x08, 0xE0, 0x90, 0xB2, 0xBE, 0xF0, 0x90, 0xB2, 0x09, 0xE0, 0x90, 0xB2, 0xBF, 0xF0, 0x90, 0xB2, - 0x0A, 0xE0, 0x90, 0xB2, 0xC0, 0xF0, 0x90, 0xB2, 0x0E, 0xE0, 0x90, 0xB2, 0xC1, 0xF0, 0x90, 0xB2, - 0x0F, 0xE0, 0x90, 0xB2, 0xC2, 0xF0, 0x90, 0xB2, 0x10, 0xE0, 0x90, 0xB2, 0xC3, 0xF0, 0x90, 0xB2, - 0x11, 0xE0, 0x90, 0xB2, 0xC4, 0xF0, 0x90, 0xB2, 0x12, 0xE0, 0x90, 0xB2, 0xC5, 0xF0, 0x90, 0xB2, - 0x13, 0xE0, 0x90, 0xB2, 0xC6, 0xF0, 0x90, 0xB2, 0x14, 0xE0, 0x90, 0xB2, 0xC7, 0xF0, 0x90, 0xB2, - 0x15, 0xE0, 0x90, 0xB2, 0xC8, 0xF0, 0x90, 0xB2, 0x16, 0xE0, 0x90, 0xB2, 0xC9, 0xF0, 0xE4, 0x90, - 0xB2, 0xD0, 0xF0, 0xA3, 0x74, 0xCA, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0x74, - 0xF6, 0xF0, 0xA3, 0x74, 0x09, 0xF0, 0xE4, 0x90, 0xB2, 0x0B, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, - 0xB2, 0x17, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x9C, 0x12, 0x2B, 0xAA, 0x00, 0x16, 0x44, - 0x00, 0x90, 0x81, 0x9C, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x78, - 0x01, 0x12, 0x2B, 0x78, 0x90, 0x81, 0x9C, 0x12, 0x2B, 0x9E, 0x90, 0x81, 0x9F, 0xE0, 0x90, 0x81, - 0x75, 0xF0, 0x90, 0x81, 0x9E, 0xE0, 0x90, 0x81, 0x76, 0xF0, 0x90, 0x81, 0x9D, 0xE0, 0x90, 0x81, - 0x77, 0xF0, 0xE4, 0x90, 0xB2, 0x1A, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, - 0xF0, 0x90, 0xB2, 0x48, 0x74, 0x84, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0xB0, 0x58, - 0x74, 0x17, 0xF0, 0xA3, 0x74, 0x20, 0xF0, 0x90, 0xB2, 0xB0, 0x74, 0x04, 0xF0, 0xE4, 0xA3, 0xF0, - 0x90, 0xB2, 0xA1, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x81, 0xA0, 0x12, 0x2B, 0xAA, 0x00, 0x11, 0x94, - 0x00, 0x90, 0x81, 0xA0, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x02, - 0xFF, 0xE4, 0x3E, 0xFE, 0xE4, 0x3D, 0xFD, 0xE4, 0x3C, 0xFC, 0x90, 0x81, 0xA0, 0x12, 0x2B, 0x9E, - 0x90, 0xB0, 0x30, 0x74, 0x03, 0xF0, 0x90, 0x81, 0xA3, 0xE0, 0x90, 0xB0, 0x31, 0xF0, 0x90, 0x81, - 0xA2, 0xE0, 0x90, 0xB0, 0x32, 0xF0, 0x90, 0x81, 0xA1, 0xE0, 0x90, 0xB0, 0x33, 0xF0, 0xE4, 0xA3, - 0xF0, 0x90, 0xB0, 0x30, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0xB0, 0x35, 0x74, 0xFF, 0xF0, 0xA3, 0x74, - 0xE1, 0xF0, 0xE4, 0x90, 0xB0, 0x35, 0xF0, 0xA3, 0x74, 0x04, 0xF0, 0x90, 0x81, 0xA0, 0x12, 0x2B, - 0xAA, 0x00, 0x13, 0xEC, 0x00, 0x90, 0x81, 0xA0, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, - 0xA3, 0xE0, 0x24, 0x02, 0xFF, 0xE4, 0x3E, 0xFE, 0xE4, 0x3D, 0xFD, 0xE4, 0x3C, 0xFC, 0x90, 0x81, - 0xA0, 0x12, 0x2B, 0x9E, 0x90, 0xB0, 0x30, 0x74, 0x03, 0xF0, 0x90, 0x81, 0xA3, 0xE0, 0x90, 0xB0, - 0x31, 0xF0, 0x90, 0x81, 0xA2, 0xE0, 0x90, 0xB0, 0x32, 0xF0, 0x90, 0x81, 0xA1, 0xE0, 0x90, 0xB0, - 0x33, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0xB0, 0x30, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0xB0, 0x35, 0x74, - 0xFF, 0xF0, 0xA3, 0x74, 0xE1, 0xF0, 0xE4, 0x90, 0xB0, 0x35, 0xF0, 0xA3, 0x74, 0x04, 0xF0, 0x90, - 0x81, 0x9C, 0x12, 0x2B, 0xAA, 0x00, 0x16, 0x44, 0x00, 0x90, 0x81, 0x9C, 0xE0, 0xFC, 0xA3, 0xE0, - 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x02, 0xFF, 0xE4, 0x3E, 0xFE, 0xE4, 0x3D, 0xFD, 0xE4, - 0x3C, 0xFC, 0xA3, 0x12, 0x2B, 0x9E, 0x90, 0x81, 0x9C, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, - 0xFE, 0xA3, 0xE0, 0xFF, 0x78, 0x01, 0x12, 0x2B, 0x78, 0x90, 0x81, 0x9C, 0x12, 0x2B, 0x9E, 0x90, - 0x81, 0x9F, 0xE0, 0x90, 0x81, 0x75, 0xF0, 0x90, 0x81, 0x9E, 0xE0, 0x90, 0x81, 0x76, 0xF0, 0x90, - 0x81, 0x9D, 0xE0, 0x90, 0x81, 0x77, 0xF0, 0x90, 0xB0, 0x30, 0x74, 0x03, 0xF0, 0x90, 0x81, 0xA3, - 0xE0, 0x90, 0xB0, 0x31, 0xF0, 0x90, 0x81, 0xA2, 0xE0, 0x90, 0xB0, 0x32, 0xF0, 0x90, 0x81, 0xA1, - 0xE0, 0x90, 0xB0, 0x33, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0xB0, 0x30, 0xE0, 0x44, 0x04, 0xF0, 0x90, - 0xB0, 0x35, 0x74, 0xFF, 0xF0, 0xA3, 0x74, 0xE1, 0xF0, 0xE4, 0x90, 0xB0, 0x35, 0xF0, 0xA3, 0x74, - 0x04, 0xF0, 0x22, 0x90, 0x81, 0x62, 0xE0, 0xB4, 0x01, 0x23, 0x90, 0xB2, 0x52, 0x74, 0xBC, 0xF0, - 0xA3, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0xF0, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0xB2, 0x20, 0x74, 0x23, - 0xF0, 0xA3, 0x74, 0x20, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0xA3, 0xF0, 0x80, 0x1C, 0x90, 0xB2, 0x52, - 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0xE0, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0x90, - 0xB2, 0x20, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x9D, 0x12, 0x2B, 0xAA, 0x00, - 0x00, 0x00, 0x00, 0x90, 0xB2, 0x52, 0xE0, 0x90, 0x81, 0xA0, 0xF0, 0x90, 0xB2, 0x53, 0xE0, 0x90, - 0x81, 0x9F, 0xF0, 0x90, 0xB2, 0x21, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x90, 0x81, 0x9D, 0xE0, - 0xF8, 0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0x12, 0x2A, 0x4A, 0xEC, 0xC0, 0xE0, - 0xED, 0xC0, 0xE0, 0xEE, 0xC0, 0xE0, 0xEF, 0xC0, 0xE0, 0x90, 0xB2, 0x20, 0xE0, 0xFF, 0xE4, 0xFC, - 0xFD, 0xFE, 0xF8, 0xF9, 0xFA, 0xCB, 0xEF, 0xCB, 0xD0, 0xE0, 0xFF, 0xD0, 0xE0, 0xFE, 0xD0, 0xE0, - 0xFD, 0xD0, 0xE0, 0xFC, 0x12, 0x2A, 0xD5, 0x90, 0x81, 0x9D, 0x12, 0x2B, 0x9E, 0x90, 0x81, 0xA0, - 0xE0, 0x90, 0xB2, 0x36, 0xF0, 0x90, 0x81, 0x9F, 0xE0, 0x90, 0xB2, 0x37, 0xF0, 0x90, 0x81, 0x9D, - 0x12, 0x2B, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x90, 0xB2, 0x54, 0xE0, 0x90, 0x81, 0xA0, 0xF0, 0x90, - 0xB2, 0x55, 0xE0, 0x90, 0x81, 0x9F, 0xF0, 0x90, 0xB2, 0x23, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, - 0x90, 0x81, 0x9D, 0xE0, 0xF8, 0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0x12, 0x2A, - 0x4A, 0xEC, 0xC0, 0xE0, 0xED, 0xC0, 0xE0, 0xEE, 0xC0, 0xE0, 0xEF, 0xC0, 0xE0, 0x90, 0xB2, 0x22, - 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0xF8, 0xF9, 0xFA, 0xCB, 0xEF, 0xCB, 0xD0, 0xE0, 0xFF, 0xD0, - 0xE0, 0xFE, 0xD0, 0xE0, 0xFD, 0xD0, 0xE0, 0xFC, 0x12, 0x2A, 0xD5, 0x90, 0x81, 0x9D, 0x12, 0x2B, - 0x9E, 0x90, 0x81, 0xA0, 0xE0, 0x90, 0xB2, 0x38, 0xF0, 0x90, 0x81, 0x9F, 0xE0, 0x90, 0xB2, 0x39, - 0xF0, 0x22, 0x90, 0xB2, 0x00, 0x74, 0xAC, 0xF0, 0x54, 0x7F, 0xF0, 0xA3, 0x74, 0x35, 0xF0, 0x90, - 0xB2, 0x35, 0xE0, 0x54, 0xF8, 0xF0, 0x90, 0xB2, 0x4C, 0x74, 0x0F, 0xF0, 0x90, 0xB2, 0x00, 0xE0, - 0x44, 0x80, 0xF0, 0x54, 0x7F, 0xF0, 0x90, 0xB0, 0x04, 0xE0, 0x44, 0x02, 0xF0, 0x22, 0xE4, 0xFE, - 0xEE, 0x90, 0x0A, 0x3E, 0x93, 0xFF, 0x90, 0x0A, 0x83, 0x93, 0xFD, 0x74, 0x00, 0x2E, 0xF5, 0x82, - 0xE4, 0x34, 0xB1, 0xF5, 0x83, 0xED, 0xF0, 0x0E, 0xEE, 0xB4, 0x40, 0xE4, 0xE4, 0xFE, 0xEE, 0x90, - 0x0A, 0x3E, 0x93, 0xFF, 0x90, 0x0A, 0xC8, 0x93, 0xFD, 0x74, 0x40, 0x2E, 0xF5, 0x82, 0xE4, 0x34, - 0xB1, 0xF5, 0x83, 0xED, 0xF0, 0x0E, 0xEE, 0xB4, 0x40, 0xE4, 0x22, 0x90, 0xB0, 0x03, 0xE0, 0x44, - 0x08, 0xF0, 0x90, 0xB2, 0x94, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0xB2, 0x80, 0x74, 0x90, 0xF0, 0xA3, - 0x74, 0x70, 0xF0, 0xE4, 0x90, 0xB2, 0x83, 0xF0, 0x90, 0xB2, 0x86, 0x74, 0xF4, 0xF0, 0x90, 0xB2, - 0x38, 0xE0, 0x90, 0xB2, 0xDC, 0xF0, 0x90, 0xB2, 0x39, 0xE0, 0x90, 0xB2, 0xDD, 0xF0, 0x90, 0xB2, - 0x36, 0xE0, 0x90, 0xB2, 0xDE, 0xF0, 0x90, 0xB2, 0x37, 0xE0, 0x90, 0xB2, 0xDF, 0xF0, 0x90, 0xB2, - 0x88, 0x74, 0xE0, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x02, 0xF0, - 0x90, 0xB2, 0x90, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0xB2, 0xA0, 0x04, 0xF0, 0xE4, 0x90, 0xB2, 0xA2, - 0xF0, 0x90, 0xB2, 0x36, 0xE0, 0x90, 0x81, 0x9D, 0xF0, 0x90, 0xB2, 0x37, 0xE0, 0x90, 0x81, 0x9C, - 0xF0, 0xE0, 0xC3, 0x13, 0xFE, 0xA3, 0xE0, 0x13, 0xFF, 0x90, 0x81, 0x9C, 0xEE, 0xF0, 0xA3, 0xEF, - 0xF0, 0xE0, 0x90, 0xB2, 0xCA, 0xF0, 0x90, 0x81, 0x9C, 0xE0, 0x90, 0xB2, 0xCB, 0xF0, 0xEE, 0xC3, - 0x13, 0xFE, 0xEF, 0x13, 0xFF, 0x90, 0x81, 0x9C, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE0, 0x90, 0xB2, - 0xCC, 0xF0, 0x90, 0x81, 0x9C, 0xE0, 0x90, 0xB2, 0xCD, 0xF0, 0x90, 0xB2, 0xCC, 0xE0, 0x90, 0xB2, - 0xCE, 0xF0, 0x90, 0xB2, 0xCD, 0xE0, 0x90, 0xB2, 0xCF, 0xF0, 0x12, 0x09, 0x3E, 0x22, 0x00, 0x01, - 0x05, 0x06, 0x0E, 0x0F, 0x1B, 0x1C, 0x02, 0x04, 0x07, 0x0D, 0x10, 0x1A, 0x1D, 0x2A, 0x03, 0x08, - 0x0C, 0x11, 0x19, 0x1E, 0x29, 0x2B, 0x09, 0x0B, 0x12, 0x18, 0x1F, 0x28, 0x2C, 0x35, 0x0A, 0x13, - 0x17, 0x20, 0x27, 0x2D, 0x34, 0x36, 0x14, 0x16, 0x21, 0x26, 0x2E, 0x33, 0x37, 0x3C, 0x15, 0x22, - 0x25, 0x2F, 0x32, 0x38, 0x3B, 0x3D, 0x23, 0x24, 0x30, 0x31, 0x39, 0x3A, 0x3E, 0x3F, 0xFF, 0xDB, - 0x00, 0x43, 0x00, 0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E, 0x0D, 0x0E, 0x12, 0x11, 0x10, - 0x13, 0x18, 0x28, 0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1D, 0x28, 0x3A, 0x33, 0x3D, - 0x3C, 0x39, 0x33, 0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, - 0x6D, 0x51, 0x57, 0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79, 0x70, 0x64, 0x78, 0x5C, - 0x65, 0x67, 0x63, 0xFF, 0xDB, 0x00, 0x43, 0x01, 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2F, 0x1A, - 0x1A, 0x2F, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0xE4, 0x90, 0xB5, 0x40, 0xF0, 0x90, 0xB5, 0x42, - 0xF0, 0x90, 0xB5, 0x0B, 0xE0, 0x44, 0x20, 0xF0, 0xE4, 0x90, 0x80, 0xB5, 0xF0, 0xA3, 0xF0, 0x12, - 0x0B, 0x23, 0x22, 0x12, 0x0B, 0x27, 0x22, 0xE4, 0xFF, 0xFE, 0xEE, 0x90, 0x19, 0x3B, 0x93, 0xFD, - 0x74, 0x00, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xB5, 0xF5, 0x83, 0xED, 0xF0, 0x0E, 0xEE, 0xB4, 0x20, - 0xE9, 0x7E, 0x50, 0xCD, 0xEF, 0xCD, 0x0F, 0xED, 0x90, 0x19, 0x5B, 0x93, 0xFD, 0x74, 0x00, 0x2E, - 0xF5, 0x82, 0xE4, 0x34, 0xB5, 0xF5, 0x83, 0xED, 0xF0, 0x0E, 0xEE, 0xB4, 0x60, 0xE5, 0xE4, 0x90, - 0x80, 0xBA, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x80, 0xB7, 0xF0, 0xA3, 0xF0, 0xA3, - 0xF0, 0x90, 0x80, 0xBE, 0xF0, 0x90, 0x80, 0xC0, 0xF0, 0x90, 0x80, 0xC2, 0xF0, 0xA3, 0xF0, 0xA3, - 0xF0, 0x90, 0x80, 0x01, 0xF0, 0x90, 0x80, 0xE5, 0xF0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x90, - 0xB3, 0x21, 0xE0, 0xFF, 0x30, 0xE1, 0x03, 0x12, 0x16, 0x72, 0xD0, 0xD0, 0x22, 0xC0, 0xD0, 0x75, - 0xD0, 0x08, 0x90, 0xB5, 0x04, 0xE0, 0x90, 0x81, 0x88, 0xF0, 0xE0, 0x30, 0xE1, 0x0D, 0x7F, 0x00, - 0x7E, 0x06, 0xEF, 0x1F, 0x70, 0x01, 0x1E, 0x14, 0x4E, 0x70, 0xF7, 0x90, 0xB5, 0x04, 0xE0, 0x90, - 0x81, 0x88, 0xF0, 0xE0, 0x30, 0xE0, 0x03, 0x12, 0x0C, 0x5C, 0x90, 0x81, 0x88, 0xE0, 0x30, 0xE2, - 0x03, 0x12, 0x0C, 0x96, 0x90, 0x81, 0x88, 0xE0, 0x30, 0xE3, 0x03, 0x12, 0x0C, 0xA4, 0x90, 0x81, - 0x88, 0xE0, 0x30, 0xE5, 0x03, 0x12, 0x0C, 0xAB, 0x90, 0x81, 0x88, 0xE0, 0x30, 0xE6, 0x03, 0x12, - 0x0D, 0x05, 0x90, 0x81, 0x88, 0xE0, 0x30, 0xE7, 0x03, 0x12, 0x0D, 0x59, 0x90, 0xB5, 0x70, 0xE0, - 0x90, 0x81, 0x88, 0xF0, 0xE0, 0x30, 0xE6, 0x03, 0x12, 0x16, 0x56, 0x90, 0xB5, 0x05, 0xE0, 0x90, - 0x81, 0x88, 0xF0, 0xE0, 0x30, 0xE1, 0x03, 0x12, 0x0E, 0x1A, 0x90, 0x81, 0x88, 0xE0, 0x30, 0xE2, - 0x03, 0x12, 0x0E, 0x72, 0x90, 0x81, 0x88, 0xE0, 0x30, 0xE3, 0x03, 0x12, 0x0E, 0xA4, 0x90, 0x81, - 0x88, 0xE0, 0x30, 0xE4, 0x03, 0x12, 0x0F, 0x09, 0x90, 0x81, 0x88, 0xE0, 0x30, 0xE5, 0x03, 0x12, - 0x0F, 0x1A, 0x90, 0xB5, 0x41, 0xE0, 0x90, 0x81, 0x88, 0xF0, 0x90, 0xB5, 0x04, 0xE0, 0x90, 0x81, - 0x88, 0xF0, 0xE0, 0x30, 0xE1, 0x03, 0x12, 0x0C, 0x63, 0xD0, 0xD0, 0x22, 0x90, 0xB5, 0x06, 0x74, - 0x01, 0xF0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x90, 0x80, 0xB6, 0xE0, 0xFF, 0x70, 0x0B, 0xEF, - 0xF4, 0xF0, 0x90, 0xB5, 0x06, 0x74, 0x02, 0xF0, 0x80, 0x19, 0x90, 0xB5, 0x01, 0xE0, 0x54, 0xEF, - 0xF0, 0x90, 0xB0, 0x03, 0xE0, 0x54, 0xBF, 0xF0, 0x90, 0xB5, 0x06, 0x74, 0x02, 0xF0, 0xE4, 0x90, - 0x80, 0xB5, 0xF0, 0xD0, 0xD0, 0x22, 0x90, 0xB5, 0x06, 0x74, 0x04, 0xF0, 0x90, 0xB0, 0x40, 0xE0, - 0x54, 0x7F, 0xF0, 0x22, 0x90, 0xB5, 0x06, 0x74, 0x08, 0xF0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, - 0x12, 0x16, 0x3E, 0x90, 0x80, 0xB7, 0x74, 0x01, 0xF0, 0x90, 0x80, 0xB2, 0xF0, 0xA3, 0xF0, 0x90, - 0xB5, 0x18, 0xE0, 0xB4, 0x08, 0x30, 0x12, 0x0F, 0x88, 0x90, 0x18, 0xDA, 0xE4, 0x93, 0xFF, 0x7E, - 0x00, 0xD3, 0x90, 0x80, 0xDC, 0xE0, 0x9F, 0x90, 0x80, 0xDB, 0xE0, 0x9E, 0x50, 0x08, 0x90, 0xB5, - 0x08, 0x74, 0x08, 0xF0, 0x80, 0x16, 0x90, 0x80, 0xDB, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0xB5, - 0x08, 0x74, 0x08, 0xF0, 0x80, 0x06, 0x90, 0xB5, 0x08, 0x74, 0x02, 0xF0, 0x90, 0xB5, 0x06, 0x74, - 0x20, 0xF0, 0xD0, 0xD0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x12, 0x16, 0x3E, 0x90, 0x80, 0xB8, - 0x74, 0x01, 0xF0, 0x90, 0xB5, 0x18, 0xE0, 0xB4, 0x08, 0x30, 0x12, 0x0F, 0x88, 0x90, 0x18, 0xEE, - 0xE4, 0x93, 0xFF, 0x7E, 0x00, 0xD3, 0x90, 0x80, 0xDC, 0xE0, 0x9F, 0x90, 0x80, 0xDB, 0xE0, 0x9E, - 0x50, 0x08, 0x90, 0xB5, 0x08, 0x74, 0x08, 0xF0, 0x80, 0x16, 0x90, 0x80, 0xDB, 0xEE, 0xF0, 0xA3, - 0xEF, 0xF0, 0x90, 0xB5, 0x08, 0x74, 0x08, 0xF0, 0x80, 0x06, 0x90, 0xB5, 0x08, 0x74, 0x02, 0xF0, - 0x90, 0xB5, 0x06, 0x74, 0x40, 0xF0, 0xD0, 0xD0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x12, 0x16, - 0x3E, 0x90, 0x80, 0xB9, 0x74, 0x01, 0xF0, 0x90, 0xB5, 0x18, 0xE0, 0x64, 0x08, 0x60, 0x03, 0x02, - 0x0E, 0x0B, 0x12, 0x0F, 0x88, 0x90, 0xB5, 0x22, 0xE0, 0x70, 0x2A, 0x90, 0x19, 0x13, 0x93, 0xFF, - 0x7E, 0x00, 0xD3, 0x90, 0x80, 0xDC, 0xE0, 0x9F, 0x90, 0x80, 0xDB, 0xE0, 0x9E, 0x50, 0x08, 0x90, - 0xB5, 0x08, 0x74, 0x08, 0xF0, 0x80, 0x0E, 0x90, 0x80, 0xDB, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, - 0xB5, 0x08, 0x74, 0x08, 0xF0, 0x90, 0xB5, 0x22, 0xE0, 0xB4, 0x01, 0x2B, 0x90, 0x19, 0x17, 0xE4, - 0x93, 0xFF, 0x7E, 0x00, 0xD3, 0x90, 0x80, 0xDC, 0xE0, 0x9F, 0x90, 0x80, 0xDB, 0xE0, 0x9E, 0x50, - 0x08, 0x90, 0xB5, 0x08, 0x74, 0x08, 0xF0, 0x80, 0x0E, 0x90, 0x80, 0xDB, 0xEE, 0xF0, 0xA3, 0xEF, - 0xF0, 0x90, 0xB5, 0x08, 0x74, 0x08, 0xF0, 0x90, 0xB5, 0x22, 0xE0, 0xB4, 0x02, 0x33, 0x90, 0x19, - 0x27, 0xE4, 0x93, 0xFF, 0x7E, 0x00, 0xD3, 0x90, 0x80, 0xDC, 0xE0, 0x9F, 0x90, 0x80, 0xDB, 0xE0, - 0x9E, 0x50, 0x08, 0x90, 0xB5, 0x08, 0x74, 0x08, 0xF0, 0x80, 0x16, 0x90, 0x80, 0xDB, 0xEE, 0xF0, - 0xA3, 0xEF, 0xF0, 0x90, 0xB5, 0x08, 0x74, 0x08, 0xF0, 0x80, 0x06, 0x90, 0xB5, 0x08, 0x74, 0x02, - 0xF0, 0x90, 0xB5, 0x06, 0x74, 0x80, 0xF0, 0xD0, 0xD0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x12, - 0x16, 0x3E, 0x90, 0xB5, 0x18, 0xE0, 0xB4, 0x08, 0x27, 0x12, 0x0F, 0x88, 0x90, 0x80, 0xD5, 0xE0, - 0xFF, 0xB4, 0x40, 0x08, 0x90, 0x80, 0xBA, 0x74, 0x01, 0xF0, 0x80, 0x1A, 0xEF, 0xB4, 0xC0, 0x08, - 0x90, 0x80, 0xBB, 0x74, 0x01, 0xF0, 0x80, 0x0E, 0x90, 0xB5, 0x08, 0x74, 0x02, 0xF0, 0x80, 0x06, - 0x90, 0xB5, 0x08, 0x74, 0x02, 0xF0, 0x90, 0x80, 0xDB, 0xE0, 0x70, 0x02, 0xA3, 0xE0, 0x70, 0x03, - 0x12, 0x1C, 0x80, 0x90, 0xB5, 0x08, 0x74, 0x08, 0xF0, 0x90, 0xB5, 0x07, 0x74, 0x02, 0xF0, 0xD0, - 0xD0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x90, 0x80, 0xBC, 0xE0, 0xB4, 0x01, 0x05, 0x12, 0x10, - 0x4B, 0x80, 0x12, 0x90, 0x80, 0xBA, 0xE0, 0xB4, 0x01, 0x05, 0x12, 0x10, 0x4C, 0x80, 0x06, 0x90, - 0xB5, 0x08, 0x74, 0x02, 0xF0, 0x90, 0xB5, 0x08, 0x74, 0x08, 0xF0, 0x90, 0xB5, 0x07, 0x74, 0x04, - 0xF0, 0xD0, 0xD0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x90, 0x80, 0xBD, 0xE0, 0xB4, 0x01, 0x05, - 0x12, 0x13, 0xC2, 0x80, 0x36, 0x90, 0x80, 0xBB, 0xE0, 0xB4, 0x01, 0x05, 0x12, 0x13, 0xD2, 0x80, - 0x2A, 0x90, 0x80, 0xB7, 0xE0, 0xB4, 0x01, 0x05, 0x12, 0x15, 0x34, 0x80, 0x1E, 0x90, 0x80, 0xB8, - 0xE0, 0xB4, 0x01, 0x05, 0x12, 0x15, 0x34, 0x80, 0x12, 0x90, 0x80, 0xB9, 0xE0, 0xB4, 0x01, 0x05, - 0x12, 0x15, 0x34, 0x80, 0x06, 0x90, 0xB5, 0x08, 0x74, 0x02, 0xF0, 0x90, 0x80, 0xBE, 0xE0, 0xB4, - 0x01, 0x08, 0x90, 0xB5, 0x08, 0x74, 0x04, 0xF0, 0x80, 0x06, 0x90, 0xB5, 0x08, 0x74, 0x01, 0xF0, - 0x90, 0xB5, 0x07, 0x74, 0x08, 0xF0, 0xD0, 0xD0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x12, 0x16, - 0x3E, 0x90, 0xB5, 0x07, 0x74, 0x10, 0xF0, 0xD0, 0xD0, 0x22, 0xE4, 0x90, 0xB5, 0x40, 0xF0, 0x90, - 0xB5, 0x01, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, 0x90, 0x80, 0xA9, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, - 0xF0, 0x90, 0x80, 0xAF, 0x04, 0xF0, 0x90, 0xB5, 0x07, 0x74, 0x20, 0xF0, 0x22, 0xC0, 0xD0, 0x75, - 0xD0, 0x08, 0x90, 0xB5, 0x41, 0xE0, 0x30, 0xE7, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0x90, - 0x80, 0xC0, 0xEF, 0xF0, 0x60, 0x16, 0x90, 0x80, 0xB3, 0x74, 0x01, 0xF0, 0x90, 0xB0, 0x03, 0xE0, - 0x44, 0x40, 0xF0, 0x90, 0xB0, 0x40, 0xE0, 0x44, 0x40, 0xF0, 0x80, 0x13, 0xE4, 0x90, 0x80, 0xB3, - 0xF0, 0x90, 0xB5, 0x00, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0xB0, 0x40, 0xE0, 0x54, 0xBF, 0xF0, 0x90, - 0xB5, 0x42, 0x74, 0x10, 0xF0, 0xD0, 0xD0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x90, 0xB5, 0x20, - 0xE0, 0x90, 0x80, 0xD5, 0xF0, 0x90, 0xB5, 0x21, 0xE0, 0x90, 0x80, 0xD6, 0xF0, 0x90, 0xB5, 0x23, - 0xE0, 0x90, 0x80, 0xD7, 0xF0, 0x90, 0xB5, 0x22, 0xE0, 0x90, 0x80, 0xD8, 0xF0, 0x90, 0xB5, 0x25, - 0xE0, 0x90, 0x80, 0xD9, 0xF0, 0x90, 0xB5, 0x24, 0xE0, 0x90, 0x80, 0xDA, 0xF0, 0x90, 0xB5, 0x27, - 0xE0, 0x90, 0x80, 0xDB, 0xF0, 0x90, 0xB5, 0x26, 0xE0, 0x90, 0x80, 0xDC, 0xF0, 0x90, 0x80, 0xD6, - 0xE0, 0xFF, 0xB4, 0x05, 0x20, 0x90, 0xB5, 0x23, 0xE0, 0x90, 0x80, 0xD1, 0xF0, 0x90, 0xB5, 0x22, - 0xE0, 0x90, 0x80, 0xD2, 0xF0, 0x90, 0xB5, 0x25, 0xE0, 0x90, 0x80, 0xD3, 0xF0, 0x90, 0xB5, 0x24, - 0xE0, 0x90, 0x80, 0xD4, 0xF0, 0x90, 0x80, 0xB9, 0xE0, 0xB4, 0x01, 0x07, 0xE4, 0x90, 0x80, 0xD9, - 0xF0, 0xA3, 0xF0, 0xEF, 0x64, 0x04, 0x60, 0x05, 0xEF, 0x64, 0x05, 0x70, 0x2A, 0x90, 0xB5, 0x24, - 0xE0, 0xFE, 0x30, 0xE0, 0x08, 0x90, 0x80, 0xC2, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x80, - 0xC2, 0xF0, 0x90, 0xB5, 0x26, 0xE0, 0xFE, 0x30, 0xE0, 0x08, 0x90, 0x80, 0xC3, 0x74, 0x01, 0xF0, - 0x80, 0x05, 0xE4, 0x90, 0x80, 0xC3, 0xF0, 0xEF, 0x64, 0x02, 0x60, 0x04, 0xEF, 0xB4, 0x03, 0x08, - 0x90, 0xB5, 0x22, 0xE0, 0x90, 0x80, 0xC1, 0xF0, 0xD0, 0xD0, 0x22, 0x22, 0xC0, 0xD0, 0x75, 0xD0, - 0x08, 0x90, 0x80, 0xDD, 0x12, 0x2B, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x90, 0x80, 0xE1, 0x12, 0x2B, - 0xAA, 0x00, 0x00, 0x00, 0x00, 0x90, 0xB5, 0x18, 0xE0, 0x70, 0x03, 0x02, 0x13, 0xBF, 0xE0, 0xFF, - 0xD3, 0x90, 0x80, 0xDC, 0xE0, 0x9F, 0x90, 0x80, 0xDB, 0xE0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x12, - 0x3D, 0x90, 0x80, 0xD6, 0xE0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x11, 0x3B, 0x90, 0x81, 0x89, 0xF0, - 0xA3, 0xF0, 0x90, 0x80, 0xDB, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x81, 0x8A, 0xE0, 0x9F, - 0x90, 0x81, 0x89, 0xE0, 0x9E, 0x50, 0x2A, 0xA3, 0xE0, 0xFF, 0x24, 0x20, 0xF5, 0x82, 0xE4, 0x34, - 0xB5, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x02, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xEE, - 0xF0, 0x90, 0x81, 0x8A, 0xE0, 0x04, 0xF0, 0x70, 0x06, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, - 0xC1, 0x90, 0x80, 0xD9, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x00, 0xF9, 0x74, 0xB0, 0x3E, 0xFA, 0x90, - 0x81, 0x8B, 0x74, 0x01, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0xE4, 0x90, 0x81, 0x89, 0xF0, - 0xA3, 0xF0, 0x90, 0x80, 0xDB, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x81, 0x8A, 0xE0, 0x9F, - 0x90, 0x81, 0x89, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x12, 0x1F, 0xA3, 0xE0, 0x24, 0x02, 0xF5, 0x82, - 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x81, 0x8B, 0xE0, 0xFB, 0xA3, 0xE4, 0x75, 0xF0, - 0x01, 0x12, 0x2A, 0x34, 0xA9, 0xF0, 0xFA, 0xEF, 0x12, 0x2A, 0x22, 0x90, 0x81, 0x8A, 0xE0, 0x04, - 0xF0, 0x70, 0x06, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xB7, 0x90, 0x80, 0xD6, 0xE0, 0x64, - 0x03, 0x60, 0x03, 0x02, 0x11, 0xD6, 0x90, 0x81, 0x89, 0xF0, 0xA3, 0xF0, 0x90, 0x80, 0xDB, 0xE0, - 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x81, 0x8A, 0xE0, 0x9F, 0x90, 0x81, 0x89, 0xE0, 0x9E, 0x50, - 0x2A, 0xA3, 0xE0, 0xFF, 0x24, 0x20, 0xF5, 0x82, 0xE4, 0x34, 0xB5, 0xF5, 0x83, 0xE0, 0xFE, 0x74, - 0x02, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x81, 0x8A, 0xE0, 0x04, - 0xF0, 0x70, 0x06, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xC1, 0xE4, 0x90, 0x81, 0x89, 0xF0, - 0xA3, 0xF0, 0x90, 0x80, 0xDB, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x81, 0x8A, 0xE0, 0x9F, - 0x90, 0x81, 0x89, 0xE0, 0x9E, 0x50, 0x78, 0x90, 0x80, 0xC1, 0xE0, 0xFF, 0x90, 0x81, 0x8A, 0xE0, - 0xFE, 0x90, 0x80, 0xDA, 0xE0, 0x2E, 0xFD, 0x74, 0x02, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, - 0x83, 0xE0, 0xFB, 0x12, 0x25, 0xFD, 0x90, 0x81, 0x8A, 0xE0, 0x04, 0xF0, 0x70, 0x06, 0x90, 0x81, - 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xBC, 0xE4, 0x90, 0x81, 0x89, 0xF0, 0xA3, 0xF0, 0x90, 0x80, 0xDB, - 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x81, 0x8A, 0xE0, 0x9F, 0x90, 0x81, 0x89, 0xE0, 0x9E, - 0x50, 0x2A, 0xA3, 0xE0, 0xFF, 0x24, 0x20, 0xF5, 0x82, 0xE4, 0x34, 0xB5, 0xF5, 0x83, 0xE0, 0xFE, - 0x74, 0x02, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x81, 0x8A, 0xE0, - 0x04, 0xF0, 0x70, 0x06, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xC1, 0x12, 0x1C, 0x80, 0x90, - 0x80, 0xDB, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x80, 0xDA, 0xE0, 0x2F, 0xF0, 0x90, 0x80, 0xD9, - 0xE0, 0x3E, 0xF0, 0xE4, 0x90, 0x80, 0xDB, 0xF0, 0xA3, 0xF0, 0x02, 0x13, 0xBF, 0x90, 0x80, 0xD6, - 0xE0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x12, 0xFB, 0x90, 0x81, 0x89, 0xF0, 0xA3, 0xF0, 0x90, 0xB5, - 0x18, 0xE0, 0xFF, 0xC3, 0x90, 0x81, 0x8A, 0xE0, 0x9F, 0x74, 0x80, 0xF8, 0x90, 0x81, 0x89, 0xE0, - 0x64, 0x80, 0x98, 0x50, 0x2A, 0xA3, 0xE0, 0xFF, 0x24, 0x20, 0xF5, 0x82, 0xE4, 0x34, 0xB5, 0xF5, - 0x83, 0xE0, 0xFE, 0x74, 0x02, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xEE, 0xF0, 0x90, - 0x81, 0x8A, 0xE0, 0x04, 0xF0, 0x70, 0x06, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xBF, 0x90, - 0x80, 0xD9, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x00, 0xF9, 0x74, 0xB0, 0x3E, 0xFA, 0x90, 0x81, 0x8B, - 0x74, 0x01, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0xE4, 0x90, 0x81, 0x89, 0xF0, 0xA3, 0xF0, - 0x90, 0xB5, 0x18, 0xE0, 0xFF, 0xC3, 0x90, 0x81, 0x8A, 0xE0, 0x9F, 0x74, 0x80, 0xF8, 0x90, 0x81, - 0x89, 0xE0, 0x64, 0x80, 0x98, 0x40, 0x03, 0x02, 0x13, 0x9A, 0xA3, 0xE0, 0x24, 0x02, 0xF5, 0x82, - 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x81, 0x8B, 0xE0, 0xFB, 0xA3, 0xE4, 0x75, 0xF0, - 0x01, 0x12, 0x2A, 0x34, 0xA9, 0xF0, 0xFA, 0xEF, 0x12, 0x2A, 0x22, 0x90, 0x81, 0x8A, 0xE0, 0x04, - 0xF0, 0x70, 0x06, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xB5, 0x90, 0x80, 0xD6, 0xE0, 0x64, - 0x03, 0x60, 0x03, 0x02, 0x13, 0x9A, 0x90, 0x81, 0x89, 0xF0, 0xA3, 0xF0, 0x90, 0xB5, 0x18, 0xE0, - 0xFF, 0xC3, 0x90, 0x81, 0x8A, 0xE0, 0x9F, 0x74, 0x80, 0xF8, 0x90, 0x81, 0x89, 0xE0, 0x64, 0x80, - 0x98, 0x50, 0x2A, 0xA3, 0xE0, 0xFF, 0x24, 0x20, 0xF5, 0x82, 0xE4, 0x34, 0xB5, 0xF5, 0x83, 0xE0, - 0xFE, 0x74, 0x02, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x81, 0x8A, - 0xE0, 0x04, 0xF0, 0x70, 0x06, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xBF, 0xE4, 0x90, 0x81, - 0x89, 0xF0, 0xA3, 0xF0, 0x90, 0xB5, 0x18, 0xE0, 0xFF, 0xC3, 0x90, 0x81, 0x8A, 0xE0, 0x9F, 0x74, - 0x80, 0xF8, 0x90, 0x81, 0x89, 0xE0, 0x64, 0x80, 0x98, 0x50, 0x2F, 0x90, 0x80, 0xC1, 0xE0, 0xFF, - 0x90, 0x81, 0x8A, 0xE0, 0xFE, 0x90, 0x80, 0xDA, 0xE0, 0x2E, 0xFD, 0x74, 0x02, 0x2E, 0xF5, 0x82, - 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xE0, 0xFB, 0x12, 0x25, 0xFD, 0x90, 0x81, 0x8A, 0xE0, 0x04, 0xF0, - 0x70, 0x06, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xBA, 0x90, 0xB5, 0x18, 0xE0, 0xFF, 0x90, - 0x80, 0xDA, 0xE0, 0x2F, 0xF0, 0x90, 0x80, 0xD9, 0xE0, 0x34, 0x00, 0xF0, 0x90, 0xB5, 0x18, 0xE0, - 0xFF, 0xC3, 0x90, 0x80, 0xDC, 0xE0, 0x9F, 0xF0, 0x90, 0x80, 0xDB, 0xE0, 0x94, 0x00, 0xF0, 0xD0, - 0xD0, 0x22, 0x90, 0x80, 0xBE, 0x74, 0x01, 0xF0, 0x90, 0xB5, 0x09, 0xF0, 0xE4, 0x90, 0xB5, 0x30, - 0xF0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x90, 0x80, 0xDB, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xD3, - 0x94, 0x00, 0xEE, 0x94, 0x00, 0x50, 0x03, 0x02, 0x15, 0x2C, 0xD3, 0xEF, 0x94, 0x10, 0xEE, 0x94, - 0x00, 0x50, 0x10, 0x90, 0x80, 0xBE, 0x74, 0x01, 0xF0, 0x90, 0x80, 0xDC, 0xE0, 0x90, 0xB5, 0x09, - 0xF0, 0x80, 0x14, 0x90, 0x80, 0xDC, 0xE0, 0x24, 0xF0, 0xF0, 0x90, 0x80, 0xDB, 0xE0, 0x34, 0xFF, - 0xF0, 0x90, 0xB5, 0x09, 0x74, 0x10, 0xF0, 0x90, 0x80, 0xD6, 0xE0, 0xFC, 0x70, 0x4B, 0x90, 0x81, - 0x89, 0xF0, 0x90, 0xB5, 0x09, 0xE0, 0xFE, 0x90, 0x81, 0x89, 0xE0, 0xFD, 0xC3, 0x9E, 0x40, 0x03, - 0x02, 0x14, 0xF9, 0x90, 0x80, 0xD9, 0xE0, 0xFE, 0xA3, 0xE0, 0x7B, 0x01, 0x24, 0x00, 0xF9, 0x74, - 0xB0, 0x3E, 0xFA, 0x12, 0x29, 0xDC, 0xFF, 0x74, 0x02, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, - 0x83, 0xEF, 0xF0, 0x90, 0x80, 0xDA, 0xE0, 0x04, 0xF0, 0x70, 0x06, 0x90, 0x80, 0xD9, 0xE0, 0x04, - 0xF0, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xB9, 0xEC, 0xB4, 0x10, 0x3E, 0xE4, 0x90, 0x81, - 0x89, 0xF0, 0x90, 0xB5, 0x09, 0xE0, 0xFF, 0x90, 0x81, 0x89, 0xE0, 0xFE, 0xC3, 0x9F, 0x50, 0x79, - 0x90, 0x80, 0xDA, 0xE0, 0x90, 0x19, 0x39, 0x93, 0xFF, 0x74, 0x02, 0x2E, 0xF5, 0x82, 0xE4, 0x34, - 0x80, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x80, 0xDA, 0xE0, 0x04, 0xF0, 0x70, 0x06, 0x90, 0x80, 0xD9, - 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xC7, 0x90, 0x80, 0xD6, 0xE0, 0x64, - 0x02, 0x70, 0x43, 0x90, 0x81, 0x89, 0xF0, 0x90, 0xB5, 0x09, 0xE0, 0xFF, 0x90, 0x81, 0x89, 0xE0, - 0xC3, 0x9F, 0x50, 0x35, 0x90, 0x80, 0xC1, 0xE0, 0xFF, 0x90, 0x80, 0xDA, 0xE0, 0xFD, 0x12, 0x26, - 0x46, 0x90, 0x81, 0x89, 0xE0, 0x24, 0x02, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xEF, 0xF0, - 0x90, 0x80, 0xDA, 0xE0, 0x04, 0xF0, 0x70, 0x06, 0x90, 0x80, 0xD9, 0xE0, 0x04, 0xF0, 0x90, 0x81, - 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xC1, 0x12, 0x19, 0x6B, 0xE4, 0x90, 0x81, 0x89, 0xF0, 0x90, 0xB5, - 0x09, 0xE0, 0xFF, 0x90, 0x81, 0x89, 0xE0, 0xFE, 0xC3, 0x9F, 0x50, 0x25, 0x74, 0x02, 0x2E, 0xF5, - 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xE0, 0xFF, 0x74, 0x30, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xB5, - 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x81, 0x89, 0xE0, 0x04, 0xF0, 0x80, 0xD2, 0xE4, 0x90, 0xB5, 0x09, - 0xF0, 0xD0, 0xD0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x90, 0x80, 0xDB, 0xE0, 0xFE, 0xA3, 0xE0, - 0xFF, 0xD3, 0x94, 0x00, 0xEE, 0x94, 0x00, 0x50, 0x03, 0x02, 0x16, 0x36, 0xD3, 0xEF, 0x94, 0x10, - 0xEE, 0x94, 0x00, 0x50, 0x10, 0x90, 0x80, 0xBE, 0x74, 0x01, 0xF0, 0x90, 0x80, 0xDC, 0xE0, 0x90, - 0xB5, 0x09, 0xF0, 0x80, 0x14, 0x90, 0x80, 0xDC, 0xE0, 0x24, 0xF0, 0xF0, 0x90, 0x80, 0xDB, 0xE0, - 0x34, 0xFF, 0xF0, 0x90, 0xB5, 0x09, 0x74, 0x10, 0xF0, 0xE4, 0xFF, 0x90, 0xB5, 0x09, 0xE0, 0xFE, - 0xEF, 0xC3, 0x9E, 0x40, 0x03, 0x02, 0x16, 0x3B, 0x90, 0x80, 0xB7, 0xE0, 0xB4, 0x01, 0x18, 0x90, - 0x80, 0xDA, 0xE0, 0x90, 0x18, 0xDA, 0x93, 0xFE, 0x74, 0x30, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xB5, - 0xF5, 0x83, 0xEE, 0xF0, 0x02, 0x16, 0x24, 0x90, 0x80, 0xB8, 0xE0, 0xB4, 0x01, 0x17, 0x90, 0x80, - 0xDA, 0xE0, 0x90, 0x18, 0xEC, 0x93, 0xFE, 0x74, 0x30, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xB5, 0xF5, - 0x83, 0xEE, 0xF0, 0x80, 0x5F, 0x90, 0x80, 0xB9, 0xE0, 0x64, 0x01, 0x70, 0x57, 0x90, 0xB5, 0x22, - 0xE0, 0x70, 0x17, 0x90, 0x80, 0xDA, 0xE0, 0x90, 0x19, 0x13, 0x93, 0xFE, 0x74, 0x30, 0x2F, 0xF5, - 0x82, 0xE4, 0x34, 0xB5, 0xF5, 0x83, 0xEE, 0xF0, 0x80, 0x3A, 0x90, 0xB5, 0x22, 0xE0, 0xB4, 0x01, - 0x17, 0x90, 0x80, 0xDA, 0xE0, 0x90, 0x19, 0x17, 0x93, 0xFE, 0x74, 0x30, 0x2F, 0xF5, 0x82, 0xE4, - 0x34, 0xB5, 0xF5, 0x83, 0xEE, 0xF0, 0x80, 0x1C, 0x90, 0xB5, 0x22, 0xE0, 0xB4, 0x02, 0x15, 0x90, - 0x80, 0xDA, 0xE0, 0x90, 0x19, 0x27, 0x93, 0xFE, 0x74, 0x30, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xB5, - 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x80, 0xDA, 0xE0, 0x04, 0xF0, 0x70, 0x06, 0x90, 0x80, 0xD9, 0xE0, - 0x04, 0xF0, 0x0F, 0x02, 0x15, 0x7B, 0xE4, 0x90, 0xB5, 0x09, 0xF0, 0xD0, 0xD0, 0x22, 0xE4, 0x90, - 0x80, 0xBA, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x80, 0xB7, 0xF0, 0xA3, 0xF0, 0xA3, - 0xF0, 0x90, 0x80, 0xBE, 0xF0, 0x22, 0xC0, 0xD0, 0x75, 0xD0, 0x08, 0x12, 0x16, 0x61, 0xD0, 0xD0, - 0x22, 0x90, 0xB5, 0x70, 0xE0, 0x44, 0x40, 0xF0, 0x74, 0x10, 0xF0, 0x90, 0x80, 0xAE, 0x74, 0x01, - 0xF0, 0x22, 0x90, 0xB3, 0x21, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x80, 0xB4, 0x74, 0x01, 0xF0, 0x22, - 0x90, 0x81, 0x9C, 0x12, 0x2B, 0x9E, 0xE4, 0x90, 0x81, 0xA5, 0xF0, 0xA3, 0xF0, 0x90, 0x80, 0xAE, - 0xF0, 0x90, 0x80, 0xAB, 0xF0, 0xA3, 0xF0, 0x90, 0xB5, 0x40, 0xF0, 0x90, 0xB5, 0x01, 0xE0, 0x54, - 0xFE, 0xF0, 0x7F, 0x00, 0x7E, 0x02, 0x7D, 0x00, 0x7C, 0x00, 0x90, 0x81, 0xA0, 0xE0, 0xF8, 0xA3, - 0xE0, 0xF9, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0xC3, 0x12, 0x2B, 0x67, 0x40, 0x7B, 0x90, 0x81, - 0xA0, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x00, 0xFF, 0xEE, 0x34, - 0xFE, 0xFE, 0xED, 0x34, 0xFF, 0xFD, 0xEC, 0x34, 0xFF, 0xFC, 0x90, 0x81, 0xA0, 0x12, 0x2B, 0x9E, - 0x90, 0x81, 0xA4, 0xE0, 0x70, 0x30, 0x90, 0x81, 0xAB, 0x12, 0x2B, 0xAA, 0x00, 0x00, 0x02, 0x00, - 0xE4, 0x90, 0x81, 0xAF, 0xF0, 0x90, 0x81, 0x9C, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, - 0xA3, 0xE0, 0xFF, 0x12, 0x17, 0xDF, 0x7F, 0x00, 0x7E, 0x02, 0x7D, 0x00, 0x7C, 0x00, 0xE4, 0x90, - 0x81, 0xAB, 0xF0, 0x12, 0x17, 0x3A, 0x90, 0x81, 0x9C, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, - 0xFE, 0xA3, 0xE0, 0x24, 0x00, 0xFF, 0xEE, 0x34, 0x02, 0xFE, 0xE4, 0x3D, 0xFD, 0xE4, 0x3C, 0xFC, - 0x90, 0x81, 0x9C, 0x12, 0x2B, 0x9E, 0x02, 0x16, 0xA2, 0x22, 0x90, 0x81, 0xA7, 0x12, 0x2B, 0x9E, - 0xE4, 0x90, 0x80, 0xAE, 0xF0, 0x90, 0xB5, 0x70, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x81, 0xAB, 0xE0, - 0x70, 0x11, 0x90, 0xB3, 0xBD, 0x74, 0x03, 0xF0, 0xE4, 0x90, 0xB5, 0x71, 0xF0, 0xA3, 0xF0, 0xA3, - 0x74, 0xA0, 0xF0, 0x90, 0x81, 0xA7, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, - 0xE4, 0xFF, 0xEE, 0xE4, 0xFD, 0xFC, 0x78, 0x08, 0x12, 0x2B, 0x78, 0x90, 0xB5, 0x75, 0xEF, 0xF0, - 0x90, 0x81, 0xA7, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xE4, 0x90, - 0xB5, 0x74, 0xEF, 0xF0, 0x90, 0xB5, 0x0B, 0xE0, 0x44, 0x20, 0xF0, 0x90, 0xB5, 0x70, 0x74, 0x1A, - 0xF0, 0x90, 0xB5, 0x78, 0x74, 0x04, 0xF0, 0x90, 0xB5, 0x70, 0xE0, 0x44, 0x04, 0xF0, 0xE0, 0x54, - 0xFB, 0xF0, 0xE0, 0x44, 0x80, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x80, 0xAE, 0xE0, 0x70, 0x1F, 0x0F, - 0xBF, 0x00, 0x01, 0x0E, 0xD3, 0xEF, 0x94, 0x00, 0xEE, 0x94, 0x80, 0x40, 0xEC, 0x90, 0xB5, 0x70, - 0xE0, 0x20, 0xE5, 0xE5, 0x90, 0xB5, 0x78, 0x74, 0x04, 0xF0, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x90, - 0x81, 0xA7, 0x12, 0x2B, 0x9E, 0x90, 0x81, 0xAB, 0x12, 0x2B, 0xAA, 0x00, 0x00, 0x02, 0x00, 0xE4, - 0x90, 0x80, 0xB4, 0xF0, 0x90, 0x81, 0xA7, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, - 0xE0, 0xFF, 0x7B, 0x02, 0x7A, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0x2A, 0xD5, 0x90, 0x81, 0xA7, - 0x12, 0x2B, 0x9E, 0x90, 0x81, 0xAF, 0xE0, 0x70, 0x0E, 0x90, 0xB3, 0xBD, 0xF0, 0xE0, 0x44, 0x02, - 0xF0, 0x90, 0xB3, 0x20, 0x74, 0x52, 0xF0, 0x90, 0x81, 0xAB, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, - 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xE4, 0x90, 0xB3, 0x22, 0xEF, 0xF0, 0x90, 0x81, 0xAB, 0xE0, 0xFC, - 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xE4, 0xFF, 0xEE, 0xE4, 0xFD, 0xFC, 0x78, 0x08, - 0x12, 0x2B, 0x78, 0x90, 0xB3, 0x23, 0xEF, 0xF0, 0x90, 0x81, 0xAB, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, - 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xE4, 0xFF, 0xFE, 0xED, 0xE4, 0xFC, 0x78, 0x10, 0x12, 0x2B, 0x78, - 0x90, 0xB3, 0x24, 0xEF, 0xF0, 0x90, 0x81, 0xA7, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, - 0xA3, 0xE0, 0xE4, 0xFF, 0xFE, 0xED, 0xE4, 0xFC, 0x78, 0x10, 0x12, 0x2B, 0x78, 0x90, 0xB3, 0x27, - 0xEF, 0xF0, 0x90, 0x81, 0xA7, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xE4, - 0xFF, 0xEE, 0xE4, 0xFD, 0xFC, 0x78, 0x08, 0x12, 0x2B, 0x78, 0x90, 0xB3, 0x26, 0xEF, 0xF0, 0x90, - 0x81, 0xA7, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xE4, 0x90, 0xB3, - 0x25, 0xEF, 0xF0, 0x90, 0xB3, 0x20, 0xE0, 0x44, 0x01, 0xF0, 0xE0, 0x54, 0xFE, 0xF0, 0xE0, 0x44, - 0x04, 0xF0, 0x90, 0xB3, 0x21, 0xE0, 0x20, 0xE0, 0xF9, 0x22, 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, - 0x00, 0x10, 0x16, 0x04, 0x50, 0x68, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x09, 0x02, 0x27, 0x00, - 0x01, 0x01, 0x00, 0x80, 0xFA, 0x09, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x05, - 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x03, - 0x08, 0x00, 0x01, 0x04, 0x03, 0x09, 0x04, 0x10, 0x03, 0x57, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x42, - 0x00, 0x4F, 0x00, 0x4E, 0x00, 0x44, 0x00, 0x12, 0x03, 0x57, 0x00, 0x39, 0x00, 0x39, 0x00, 0x36, - 0x00, 0x38, 0x00, 0x35, 0x00, 0x43, 0x00, 0x46, 0x00, 0x01, 0x01, 0x0E, 0x00, 0xF1, 0x7F, 0x00, - 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x81, 0x82, 0x83, 0x84, 0x85, 0x03, 0x03, 0x01, 0x21, 0x16, - 0x04, 0x83, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, - 0xFF, 0xC4, 0x00, 0x13, 0x40, 0x01, 0x00, 0xC4, 0xFF, 0x00, 0x00, 0x90, 0x80, 0xD6, 0xE0, 0x12, - 0x2B, 0xDB, 0x19, 0x94, 0x32, 0x1A, 0xF5, 0x33, 0x1A, 0xFC, 0x36, 0x1B, 0x0C, 0x38, 0x1B, 0x16, - 0x39, 0x1B, 0x37, 0x3C, 0x1B, 0xD6, 0x3D, 0x1C, 0x55, 0x3F, 0x1C, 0x5F, 0x43, 0x1C, 0x77, 0x44, - 0x00, 0x00, 0x1C, 0x7F, 0x90, 0x81, 0x7B, 0xE0, 0x70, 0x0C, 0xFF, 0x7F, 0x06, 0x90, 0x80, 0x02, - 0xE4, 0xF0, 0xA3, 0xDF, 0xFC, 0x22, 0xE4, 0x90, 0x81, 0x7B, 0xF0, 0x90, 0x80, 0x01, 0x74, 0x01, - 0xF0, 0x90, 0xB5, 0x0B, 0x74, 0x81, 0xF0, 0x90, 0x81, 0x74, 0xE0, 0x70, 0x36, 0x90, 0x80, 0xEB, - 0xF0, 0x90, 0xB2, 0xD2, 0xE0, 0x90, 0x80, 0xEC, 0xF0, 0x90, 0xB2, 0xD1, 0xE0, 0x90, 0x80, 0xED, - 0xF0, 0x90, 0xB2, 0xD0, 0xE0, 0x90, 0x80, 0xEE, 0xF0, 0x90, 0x81, 0x77, 0xE0, 0x90, 0xB2, 0xD2, - 0xF0, 0x90, 0x81, 0x76, 0xE0, 0x90, 0xB2, 0xD1, 0xF0, 0x90, 0x81, 0x75, 0xE0, 0x90, 0xB2, 0xD0, - 0xF0, 0x80, 0x35, 0xE4, 0x90, 0x80, 0xEB, 0xF0, 0x90, 0xB2, 0xD5, 0xE0, 0x90, 0x80, 0xEC, 0xF0, - 0x90, 0xB2, 0xD4, 0xE0, 0x90, 0x80, 0xED, 0xF0, 0x90, 0xB2, 0xD3, 0xE0, 0x90, 0x80, 0xEE, 0xF0, - 0x90, 0x81, 0x77, 0xE0, 0x90, 0xB2, 0xD5, 0xF0, 0x90, 0x81, 0x76, 0xE0, 0x90, 0xB2, 0xD4, 0xF0, - 0x90, 0x81, 0x75, 0xE0, 0x90, 0xB2, 0xD3, 0xF0, 0x90, 0x80, 0xEC, 0xE0, 0x90, 0x81, 0x77, 0xF0, - 0x90, 0x80, 0xED, 0xE0, 0x90, 0x81, 0x76, 0xF0, 0x90, 0x80, 0xEE, 0xE0, 0x90, 0x81, 0x75, 0xF0, - 0x90, 0x80, 0xEB, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x78, 0x01, - 0x12, 0x2B, 0x8B, 0x90, 0x80, 0xEB, 0x12, 0x2B, 0x9E, 0x90, 0x80, 0xEE, 0xE0, 0x90, 0x80, 0x02, - 0xF0, 0x90, 0x80, 0xED, 0xE0, 0x90, 0x80, 0x03, 0xF0, 0x90, 0x80, 0xEC, 0xE0, 0x90, 0x80, 0x04, - 0xF0, 0x90, 0x81, 0x7A, 0xE0, 0xFF, 0xC3, 0x94, 0x01, 0x40, 0x06, 0x90, 0x80, 0xF8, 0xE0, 0x04, - 0xF0, 0xE4, 0x90, 0x80, 0xE7, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x81, 0x79, 0xE0, 0x90, 0x80, 0xE9, - 0xF0, 0x90, 0x81, 0x78, 0xE0, 0x90, 0x80, 0xEA, 0xF0, 0x90, 0x80, 0xE7, 0xE0, 0xFC, 0xA3, 0xE0, - 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x78, 0x01, 0x12, 0x2B, 0x8B, 0x90, 0x80, 0xE7, 0x12, - 0x2B, 0x9E, 0x90, 0x80, 0xEA, 0xE0, 0x90, 0x80, 0x05, 0xF0, 0x90, 0x80, 0xE9, 0xE0, 0x90, 0x80, - 0x06, 0xF0, 0x90, 0x80, 0xE8, 0xE0, 0x90, 0x80, 0x07, 0xF0, 0x90, 0x80, 0xE7, 0xE0, 0xFC, 0xA3, - 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0xFF, 0xFF, 0xEE, 0x34, 0x01, 0xFE, 0xE4, 0x3D, - 0xFD, 0xE4, 0x3C, 0xFC, 0x78, 0x09, 0x12, 0x2B, 0x78, 0x78, 0x09, 0x12, 0x2B, 0x8B, 0x90, 0x80, - 0xE7, 0x12, 0x2B, 0x9E, 0x22, 0x90, 0x80, 0x02, 0x74, 0x04, 0xF0, 0x22, 0x90, 0xB2, 0x80, 0xE0, - 0x54, 0x04, 0xFF, 0x13, 0x13, 0x54, 0x3F, 0x90, 0x80, 0x02, 0xF0, 0x22, 0x90, 0x80, 0x02, 0x74, - 0x3E, 0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0x90, 0xB2, 0x8A, 0xE0, 0x90, 0x80, 0x02, 0xF0, 0x90, 0xB2, - 0x8B, 0xE0, 0x90, 0x80, 0x03, 0xF0, 0x90, 0xB2, 0x88, 0xE0, 0x90, 0x80, 0x04, 0xF0, 0x90, 0xB2, - 0x89, 0xE0, 0x90, 0x80, 0x05, 0xF0, 0x22, 0x90, 0x80, 0xD7, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, - 0x60, 0x03, 0x02, 0x1C, 0x7F, 0xED, 0x24, 0xFE, 0x60, 0x2A, 0x14, 0x60, 0x53, 0x24, 0xFA, 0x50, - 0x7B, 0x24, 0x08, 0x60, 0x03, 0x02, 0x1C, 0x7F, 0xD3, 0x90, 0x81, 0x5E, 0xE0, 0x94, 0x60, 0x90, - 0x81, 0x5D, 0xE0, 0x94, 0x01, 0x50, 0x07, 0x90, 0x80, 0x02, 0x74, 0x01, 0xF0, 0x22, 0xE4, 0x90, - 0x80, 0x02, 0xF0, 0x22, 0x90, 0x81, 0x6F, 0xE0, 0x60, 0x20, 0x90, 0x81, 0x5D, 0xE0, 0xFE, 0xA3, - 0xE0, 0xFF, 0xC3, 0x74, 0x80, 0x9F, 0xFF, 0x74, 0x02, 0x9E, 0xFE, 0xEF, 0x78, 0x02, 0xCE, 0xC3, - 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x90, 0x80, 0x02, 0xF0, 0x22, 0xE4, 0x90, 0x80, 0x02, 0xF0, 0x22, - 0x90, 0x81, 0x6F, 0xE0, 0x60, 0x20, 0x90, 0x81, 0x5F, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x74, - 0xE0, 0x9F, 0xFF, 0x74, 0x01, 0x9E, 0xFE, 0xEF, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, - 0xF9, 0x90, 0x80, 0x02, 0xF0, 0x22, 0xE4, 0x90, 0x80, 0x02, 0xF0, 0x22, 0xCF, 0xED, 0xCF, 0xCE, - 0xEC, 0xCE, 0x12, 0x21, 0x73, 0x22, 0x90, 0x80, 0xD7, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, - 0x03, 0x02, 0x1C, 0x7F, 0xEF, 0x14, 0xB4, 0x08, 0x00, 0x40, 0x03, 0x02, 0x1C, 0x7F, 0x90, 0x1B, - 0xF5, 0xF8, 0x28, 0x28, 0x73, 0x02, 0x1C, 0x0D, 0x02, 0x1C, 0x16, 0x02, 0x1C, 0x1F, 0x02, 0x1C, - 0x28, 0x02, 0x1C, 0x31, 0x02, 0x1C, 0x3A, 0x02, 0x1C, 0x43, 0x02, 0x1C, 0x4C, 0x90, 0x81, 0x6F, - 0xE0, 0x90, 0x80, 0x02, 0xF0, 0x22, 0x90, 0x81, 0x71, 0xE0, 0x90, 0x80, 0x02, 0xF0, 0x22, 0x90, - 0x81, 0x73, 0xE0, 0x90, 0x80, 0x02, 0xF0, 0x22, 0x90, 0x81, 0x6A, 0xE0, 0x90, 0x80, 0x02, 0xF0, - 0x22, 0x90, 0x81, 0x6B, 0xE0, 0x90, 0x80, 0x02, 0xF0, 0x22, 0x90, 0x81, 0x6C, 0xE0, 0x90, 0x80, - 0x02, 0xF0, 0x22, 0x90, 0x81, 0x6D, 0xE0, 0x90, 0x80, 0x02, 0xF0, 0x22, 0x90, 0x81, 0x6E, 0xE0, - 0x90, 0x80, 0x02, 0xF0, 0x22, 0x90, 0x80, 0x02, 0x74, 0x01, 0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0x90, - 0x81, 0x62, 0xE0, 0x14, 0x60, 0x0A, 0x14, 0x70, 0x16, 0x90, 0x80, 0x02, 0x74, 0x06, 0xF0, 0x22, - 0x90, 0x80, 0x02, 0x74, 0x06, 0xF0, 0x22, 0x90, 0x80, 0xE6, 0xE0, 0x90, 0x80, 0x02, 0xF0, 0x22, - 0x90, 0x80, 0xD6, 0xE0, 0x24, 0xC9, 0x60, 0x31, 0x24, 0xFD, 0x60, 0x67, 0x24, 0xFC, 0x70, 0x03, - 0x02, 0x1D, 0xD1, 0x24, 0xFE, 0x70, 0x03, 0x02, 0x1F, 0x81, 0x24, 0xFB, 0x70, 0x03, 0x02, 0x1F, - 0xFD, 0x14, 0x70, 0x03, 0x02, 0x20, 0x88, 0x24, 0x11, 0x60, 0x03, 0x02, 0x20, 0xAD, 0x90, 0xB2, - 0x80, 0xE0, 0x44, 0x01, 0xF0, 0x54, 0xFE, 0xF0, 0x22, 0x90, 0xB2, 0x01, 0xE0, 0x54, 0xE7, 0xF0, - 0x90, 0x80, 0xD7, 0xE0, 0x70, 0x02, 0xA3, 0xE0, 0x60, 0x15, 0x90, 0x81, 0x61, 0x74, 0x01, 0xF0, - 0x90, 0xB2, 0x80, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0xB2, 0x01, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0xE4, - 0x90, 0x81, 0x61, 0xF0, 0x90, 0xB2, 0x80, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0xB2, 0x01, 0xE0, 0x44, - 0x10, 0xF0, 0x22, 0x90, 0x80, 0xD8, 0xE0, 0x90, 0x81, 0x8F, 0xF0, 0xE4, 0xFF, 0x90, 0x81, 0x8F, - 0xE0, 0xFE, 0x30, 0xE0, 0x07, 0x90, 0x81, 0x8E, 0xEF, 0xF0, 0x80, 0x0C, 0xEE, 0xC3, 0x13, 0x90, - 0x81, 0x8F, 0xF0, 0x0F, 0xEF, 0xB4, 0x08, 0xE5, 0x90, 0x81, 0x61, 0xE0, 0x70, 0x11, 0x90, 0xB2, - 0x80, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0xB2, 0x01, 0xE0, 0x54, 0xE7, 0xF0, 0x44, 0x10, 0xF0, 0x90, - 0x81, 0x8E, 0xE0, 0x90, 0x81, 0x69, 0xF0, 0x24, 0xFE, 0x60, 0x34, 0x14, 0x60, 0x43, 0x14, 0x60, - 0x53, 0x14, 0x60, 0x64, 0x24, 0x04, 0x70, 0x72, 0x90, 0xB2, 0x01, 0xE0, 0x54, 0xE7, 0xF0, 0x90, - 0xB2, 0x80, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0xB2, 0x01, 0xE0, 0x44, 0x08, 0xF0, 0x90, 0x81, 0x5D, - 0xE4, 0xF0, 0xA3, 0x74, 0xA0, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x74, 0x78, 0xF0, 0x80, 0x4B, 0x90, - 0x81, 0x5D, 0xE4, 0xF0, 0xA3, 0x74, 0xB0, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x74, 0x90, 0xF0, 0x80, - 0x39, 0x90, 0x81, 0x5D, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0x40, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x74, - 0xF0, 0xF0, 0x80, 0x26, 0x90, 0x81, 0x5D, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0x60, 0xF0, 0xA3, 0x74, - 0x01, 0xF0, 0xA3, 0x74, 0x20, 0xF0, 0x80, 0x12, 0x90, 0x81, 0x5D, 0x74, 0x02, 0xF0, 0xA3, 0x74, - 0x80, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0xE0, 0xF0, 0xE4, 0x90, 0x81, 0x72, 0xF0, 0xA3, - 0xF0, 0x90, 0x81, 0x70, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x6F, 0xF0, 0x90, 0x81, 0x7C, 0x04, 0xF0, - 0x22, 0x90, 0x80, 0xD7, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, 0x03, 0x02, 0x20, 0xAD, 0xEF, - 0x24, 0xFE, 0x70, 0x03, 0x02, 0x1F, 0x4F, 0x14, 0x70, 0x03, 0x02, 0x1F, 0x62, 0x24, 0xFA, 0x40, - 0x03, 0x02, 0x1F, 0x75, 0x24, 0x08, 0x60, 0x03, 0x02, 0x20, 0xAD, 0x90, 0x81, 0x6F, 0xE0, 0x60, - 0x03, 0x02, 0x1E, 0xCC, 0x90, 0x80, 0xD9, 0xE0, 0x70, 0x02, 0xA3, 0xE0, 0x70, 0x03, 0x02, 0x20, - 0xAD, 0xE4, 0x90, 0x81, 0x70, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x6F, 0x04, - 0xF0, 0x12, 0x20, 0xAE, 0x12, 0x21, 0x15, 0x90, 0xB2, 0x20, 0x74, 0x01, 0xF0, 0xA3, 0xF0, 0xA3, - 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x63, 0xE0, 0xFD, 0x20, 0xE7, 0x03, 0x02, 0x20, 0xAD, 0x30, 0xE6, - 0x09, 0x90, 0xB2, 0xA1, 0xE0, 0x54, 0x07, 0x44, 0x50, 0xF0, 0x90, 0x81, 0x5E, 0xE0, 0x90, 0xB2, - 0x52, 0xF0, 0x90, 0x81, 0x5D, 0xE0, 0x90, 0xB2, 0x53, 0xF0, 0xED, 0x30, 0xE6, 0x5D, 0x90, 0x81, - 0x5D, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xC3, 0x13, 0xED, 0x13, 0x90, 0xB2, 0xCA, 0xF0, 0xED, - 0xCE, 0xEC, 0xCE, 0x78, 0x02, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x90, 0xB2, 0xCC, 0xF0, - 0x90, 0xB2, 0xCE, 0xF0, 0x90, 0x81, 0x5F, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xC3, 0x13, 0xED, - 0x13, 0x90, 0xB2, 0x54, 0xF0, 0xEC, 0xC3, 0x13, 0xA3, 0xF0, 0x90, 0xB2, 0x52, 0xE0, 0x90, 0xB2, - 0x36, 0xF0, 0x90, 0xB2, 0x53, 0xE0, 0x90, 0xB2, 0x37, 0xF0, 0x90, 0xB2, 0x54, 0xE0, 0x90, 0xB2, - 0xDC, 0xF0, 0x90, 0xB2, 0x55, 0xE0, 0x90, 0xB2, 0xDD, 0xF0, 0x22, 0x90, 0x81, 0x60, 0xE0, 0x90, - 0xB2, 0x54, 0xF0, 0x90, 0x81, 0x5F, 0xE0, 0x90, 0xB2, 0x55, 0xF0, 0x22, 0x90, 0x80, 0xD9, 0xE0, - 0x70, 0x02, 0xA3, 0xE0, 0x60, 0x03, 0x02, 0x20, 0xAD, 0x90, 0x81, 0x70, 0xF0, 0xA3, 0xF0, 0xA3, - 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x6F, 0xF0, 0x90, 0x81, 0x69, 0xE0, 0x90, 0x81, 0x8E, 0xF0, 0x90, - 0x81, 0x63, 0xE0, 0xFF, 0x20, 0xE7, 0x03, 0x02, 0x20, 0xAD, 0x30, 0xE6, 0x29, 0x90, 0x81, 0x8E, - 0xE0, 0x75, 0xF0, 0x09, 0xA4, 0x24, 0xF1, 0xF9, 0x74, 0x24, 0x35, 0xF0, 0xFA, 0x7B, 0xFF, 0x90, - 0x81, 0x90, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0x7F, 0xBC, 0x7E, 0x02, 0x7D, 0xF0, - 0x7C, 0x00, 0x12, 0x23, 0x6C, 0x22, 0x90, 0x81, 0x8E, 0xE0, 0x75, 0xF0, 0x09, 0xA4, 0x24, 0xBB, - 0xF9, 0x74, 0x24, 0x35, 0xF0, 0xFA, 0x7B, 0xFF, 0x90, 0x81, 0x90, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, - 0xA3, 0xE9, 0xF0, 0x7F, 0x80, 0x7E, 0x02, 0x7D, 0xE0, 0x7C, 0x01, 0x12, 0x23, 0x6C, 0x22, 0x90, - 0x80, 0xDA, 0xE0, 0xFE, 0x33, 0x95, 0xE0, 0x90, 0x81, 0x70, 0xF0, 0xA3, 0xCE, 0xF0, 0x12, 0x20, - 0xAE, 0x22, 0x90, 0x80, 0xDA, 0xE0, 0xFE, 0x33, 0x95, 0xE0, 0x90, 0x81, 0x72, 0xF0, 0xA3, 0xCE, - 0xF0, 0x12, 0x21, 0x15, 0x22, 0x90, 0x80, 0xD7, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x21, 0xDC, - 0x22, 0x90, 0xB2, 0x00, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x80, 0xD7, 0xE0, 0x70, 0x02, 0xA3, 0xE0, - 0x70, 0x03, 0x02, 0x20, 0xAD, 0x90, 0xB2, 0x00, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x80, 0xD9, 0xE0, - 0x60, 0x1D, 0xA3, 0xE0, 0x54, 0x0F, 0x90, 0x80, 0xF0, 0xF0, 0xE0, 0xFF, 0xC4, 0x54, 0xF0, 0xFE, - 0xEF, 0x4E, 0xF0, 0x90, 0x80, 0xEF, 0x74, 0x01, 0xF0, 0x90, 0x80, 0xF2, 0x04, 0xF0, 0x22, 0xE4, - 0x90, 0x80, 0xEF, 0xF0, 0x90, 0x80, 0xF2, 0xF0, 0x90, 0x80, 0xDA, 0xE0, 0x54, 0x0F, 0x90, 0x80, - 0xF1, 0xF0, 0x90, 0x81, 0x64, 0xE0, 0xFF, 0x7D, 0x02, 0x12, 0x26, 0x46, 0x90, 0x81, 0x8F, 0xEF, - 0xF0, 0x54, 0xF0, 0xFF, 0xF0, 0x90, 0x80, 0xDA, 0xE0, 0x54, 0x0F, 0x4F, 0xFF, 0x90, 0x81, 0x8F, - 0xF0, 0xFB, 0x90, 0x81, 0x64, 0xE0, 0xFF, 0x7D, 0x02, 0x12, 0x25, 0xFD, 0x22, 0x90, 0x81, 0x62, - 0xE0, 0x64, 0x02, 0x70, 0x3C, 0x90, 0x80, 0xD7, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x01, 0x70, - 0x12, 0x90, 0x81, 0x64, 0xE0, 0xFF, 0x7D, 0x2B, 0x7B, 0x98, 0x12, 0x25, 0xFD, 0x90, 0x80, 0xE6, - 0x74, 0x01, 0xF0, 0x90, 0x80, 0xD7, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x02, 0x70, 0x12, 0x90, - 0x81, 0x64, 0xE0, 0xFF, 0x7D, 0x2B, 0xE4, 0xFB, 0x12, 0x25, 0xFD, 0x90, 0x80, 0xE6, 0x74, 0x02, - 0xF0, 0x90, 0x81, 0x62, 0xE0, 0x64, 0x01, 0x70, 0x64, 0x90, 0x80, 0xD7, 0xE0, 0xFE, 0xA3, 0xE0, - 0xFF, 0x64, 0x01, 0x4E, 0x70, 0x15, 0x90, 0xB2, 0x4E, 0x74, 0x0A, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, - 0x74, 0x10, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0x80, 0xE6, 0x04, 0xF0, 0xEF, 0x64, 0x02, 0x4E, 0x70, - 0x3C, 0x90, 0xB2, 0x4E, 0x74, 0x0C, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0x74, 0x0C, 0xF0, 0xE4, 0xA3, - 0xF0, 0x90, 0x80, 0xE6, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x80, 0xD7, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, - 0x4E, 0x60, 0x13, 0x90, 0xB2, 0x81, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x80, 0xD8, 0xE0, 0x90, 0xB2, - 0x90, 0xF0, 0xEE, 0xA3, 0xF0, 0x22, 0x90, 0xB2, 0x81, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x90, 0x81, - 0x63, 0xE0, 0x30, 0xE6, 0x18, 0x90, 0x81, 0x5D, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x74, 0xBC, - 0x9F, 0xFF, 0x74, 0x02, 0x9E, 0xC3, 0x13, 0xFC, 0xEF, 0x13, 0xFD, 0x80, 0x16, 0x90, 0x81, 0x5D, - 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x74, 0x80, 0x9F, 0xFF, 0x74, 0x02, 0x9E, 0xC3, 0x13, 0xFC, - 0xEF, 0x13, 0xFD, 0x90, 0x81, 0x66, 0xE0, 0xFE, 0x90, 0x81, 0x65, 0xE0, 0xFB, 0xEE, 0xEB, 0x2D, - 0xFD, 0xEE, 0x3C, 0xFC, 0x90, 0x81, 0x71, 0xE0, 0x25, 0xE0, 0xFF, 0x90, 0x81, 0x70, 0xE0, 0x33, - 0xFE, 0xEF, 0x2D, 0xFD, 0xEE, 0x3C, 0xFC, 0x90, 0xB2, 0x4E, 0xED, 0xF0, 0xEC, 0xFF, 0x33, 0x95, - 0xE0, 0xA3, 0xEF, 0xF0, 0x22, 0x90, 0x81, 0x5F, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x74, 0xE0, - 0x9F, 0xFF, 0x74, 0x01, 0x9E, 0xA2, 0xE7, 0x13, 0xFE, 0xEF, 0x13, 0xFD, 0xCC, 0xEE, 0xCC, 0x90, - 0x81, 0x73, 0xE0, 0x25, 0xE0, 0xFF, 0x90, 0x81, 0x72, 0xE0, 0x33, 0xFE, 0xEF, 0x2D, 0xFD, 0xEE, - 0x3C, 0xFC, 0x90, 0x81, 0x63, 0xE0, 0x30, 0xE6, 0x08, 0xEC, 0xA2, 0xE7, 0x13, 0xFC, 0xED, 0x13, - 0xFD, 0x90, 0x81, 0x68, 0xE0, 0xFE, 0x90, 0x81, 0x67, 0xE0, 0xFB, 0xEE, 0xEB, 0x2D, 0xFD, 0xEE, - 0x3C, 0xFC, 0x90, 0xB2, 0x50, 0xED, 0xF0, 0xCE, 0xEC, 0xCE, 0xEE, 0xFF, 0x33, 0x95, 0xE0, 0xA3, - 0xEF, 0xF0, 0x22, 0x90, 0x81, 0x62, 0xE0, 0x24, 0xFE, 0x60, 0x31, 0x04, 0x70, 0x5D, 0xEE, 0x70, - 0x5A, 0xEF, 0x24, 0xFB, 0x60, 0x11, 0x14, 0x60, 0x15, 0x14, 0x60, 0x19, 0x24, 0x03, 0x70, 0x4B, - 0x90, 0x80, 0x02, 0x74, 0xFF, 0xF0, 0x22, 0x90, 0x80, 0x02, 0x74, 0x0F, 0xF0, 0x22, 0x90, 0x80, - 0x02, 0x74, 0xFF, 0xF0, 0x22, 0x90, 0x80, 0x02, 0x74, 0x0F, 0xF0, 0x22, 0xEE, 0x70, 0x2C, 0xEF, - 0x24, 0xFB, 0x60, 0x0D, 0x14, 0x60, 0x10, 0x14, 0x60, 0x14, 0x14, 0x60, 0x18, 0x24, 0x04, 0x70, - 0x1A, 0xE4, 0x90, 0x80, 0x02, 0xF0, 0x22, 0x90, 0x80, 0x02, 0x74, 0x1F, 0xF0, 0x22, 0x90, 0x80, - 0x02, 0x74, 0x0F, 0xF0, 0x22, 0x90, 0x80, 0x02, 0x74, 0x07, 0xF0, 0x22, 0x90, 0x81, 0x93, 0xEE, - 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x81, 0x62, 0xE0, 0x24, 0xFE, 0x70, 0x03, 0x02, 0x22, 0xD6, 0x04, - 0x60, 0x03, 0x02, 0x23, 0x6B, 0x90, 0x81, 0x93, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, 0x03, - 0x02, 0x23, 0x6B, 0xEF, 0x24, 0xFB, 0x60, 0x25, 0x14, 0x60, 0x59, 0x14, 0x70, 0x03, 0x02, 0x22, - 0x9F, 0x24, 0x03, 0x60, 0x03, 0x02, 0x23, 0x6B, 0x90, 0x80, 0xDA, 0xE0, 0xFF, 0x90, 0x81, 0x6A, - 0xF0, 0xFB, 0x90, 0x81, 0x64, 0xE0, 0xFF, 0x7D, 0x0A, 0x12, 0x25, 0xFD, 0x22, 0x90, 0x80, 0xDA, - 0xE0, 0x90, 0x81, 0x6B, 0xF0, 0x90, 0x80, 0xD9, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, - 0x7B, 0x7F, 0xFA, 0xF9, 0xF8, 0x12, 0x2A, 0x4A, 0x7B, 0x0F, 0x7A, 0x00, 0x79, 0x00, 0x78, 0x00, - 0x12, 0x2A, 0xD5, 0x90, 0x81, 0x95, 0xEF, 0xF0, 0xFB, 0x90, 0x81, 0x64, 0xE0, 0xFF, 0x7D, 0x0B, - 0x12, 0x25, 0xFD, 0x22, 0x90, 0x80, 0xDA, 0xE0, 0xFF, 0x90, 0x81, 0x6C, 0xF0, 0x90, 0x80, 0xD9, - 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xC3, 0x94, 0x80, 0xEC, 0x94, 0x00, 0x50, 0x09, 0xED, 0x24, 0x80, - 0x90, 0x81, 0x95, 0xF0, 0x80, 0x09, 0xEF, 0x24, 0x80, 0x54, 0x7F, 0x90, 0x81, 0x95, 0xF0, 0x90, - 0x81, 0x64, 0xE0, 0xFF, 0x7D, 0x0D, 0x90, 0x81, 0x95, 0xE0, 0xFB, 0x12, 0x25, 0xFD, 0x22, 0x90, - 0x80, 0xDA, 0xE0, 0x90, 0x81, 0x6D, 0xF0, 0x90, 0x80, 0xD9, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xE4, - 0xFC, 0xFD, 0x7B, 0x7F, 0xFA, 0xF9, 0xF8, 0x12, 0x2A, 0x4A, 0x7B, 0x0F, 0x7A, 0x00, 0x79, 0x00, - 0x78, 0x00, 0x12, 0x2A, 0xD5, 0x90, 0x81, 0x95, 0xEF, 0xF0, 0xFB, 0x90, 0x81, 0x64, 0xE0, 0xFF, - 0x7D, 0x0C, 0x12, 0x25, 0xFD, 0x22, 0x90, 0x81, 0x93, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, - 0x03, 0x02, 0x23, 0x6B, 0xEF, 0x24, 0xF9, 0x60, 0x1F, 0x14, 0x60, 0x51, 0x24, 0x02, 0x70, 0x7B, - 0x90, 0x80, 0xDA, 0xE0, 0xFE, 0x90, 0x81, 0x6C, 0xF0, 0x90, 0x81, 0x64, 0xE0, 0xFF, 0x7D, 0x04, - 0xEE, 0x44, 0x20, 0xFB, 0x12, 0x25, 0xFD, 0x22, 0x90, 0x80, 0xDA, 0xE0, 0x90, 0x81, 0x6D, 0xF0, - 0x90, 0x81, 0x64, 0xE0, 0xFF, 0x7D, 0x03, 0x12, 0x26, 0x46, 0x90, 0x81, 0x95, 0xEF, 0xF0, 0x90, - 0x80, 0xDA, 0xE0, 0xFE, 0xC4, 0x54, 0xF0, 0xFE, 0xEF, 0x54, 0x0F, 0x4E, 0xFF, 0x90, 0x81, 0x95, - 0xF0, 0xFB, 0x90, 0x81, 0x64, 0xE0, 0xFF, 0x7D, 0x03, 0x12, 0x25, 0xFD, 0x22, 0x90, 0x80, 0xDA, - 0xE0, 0x90, 0x81, 0x6E, 0xF0, 0x7D, 0x26, 0x90, 0x80, 0xDA, 0x25, 0xE0, 0xFF, 0x90, 0x80, 0xD9, - 0xE0, 0x33, 0xFE, 0x74, 0x27, 0x2F, 0xF5, 0x82, 0xEE, 0x34, 0x25, 0xF5, 0x83, 0xE4, 0x93, 0x74, - 0x01, 0x93, 0xFB, 0x90, 0x81, 0x64, 0xE0, 0xFF, 0x12, 0x25, 0xFD, 0x22, 0x90, 0x81, 0x93, 0xEE, - 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0x90, 0x81, 0x65, - 0xE0, 0x90, 0xB2, 0x4E, 0xF0, 0x90, 0x81, 0x66, 0xE0, 0x90, 0xB2, 0x4F, 0xF0, 0x90, 0x81, 0x67, - 0xE0, 0x90, 0xB2, 0x50, 0xF0, 0x90, 0x81, 0x68, 0xE0, 0x90, 0xB2, 0x51, 0xF0, 0x90, 0x81, 0x94, - 0xE0, 0x90, 0xB2, 0x52, 0xF0, 0x90, 0x81, 0x93, 0xE0, 0x90, 0xB2, 0x53, 0xF0, 0xA3, 0xED, 0xF0, - 0xEC, 0xA3, 0xF0, 0xE4, 0xFF, 0x90, 0x81, 0x95, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xF9, - 0x8F, 0x82, 0x75, 0x83, 0x00, 0x12, 0x29, 0xF5, 0xFE, 0x74, 0x20, 0x2F, 0xF5, 0x82, 0xE4, 0x34, - 0xB2, 0xF5, 0x83, 0xEE, 0xF0, 0x0F, 0xEF, 0xB4, 0x04, 0xDB, 0xE4, 0xFF, 0x90, 0x81, 0x95, 0xE0, - 0xFB, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0x24, 0x04, 0xF9, 0xE4, 0x3A, 0xFA, 0xEF, 0x7C, 0x00, 0x29, - 0xF9, 0xEC, 0x3A, 0xFA, 0x12, 0x29, 0xDC, 0xFE, 0x74, 0x36, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xB2, - 0xF5, 0x83, 0xEE, 0xF0, 0x0F, 0xEF, 0xB4, 0x04, 0xD3, 0x90, 0x81, 0x95, 0xE0, 0xFB, 0xA3, 0xE0, - 0xFA, 0xA3, 0xE0, 0xF9, 0x90, 0x00, 0x08, 0x12, 0x29, 0xF5, 0xFF, 0x90, 0xB2, 0xA1, 0xE0, 0x54, - 0x07, 0x4F, 0xF0, 0x90, 0x81, 0x5E, 0xE0, 0x90, 0xB2, 0x8A, 0xF0, 0x90, 0x81, 0x5D, 0xE0, 0x90, - 0xB2, 0x8B, 0xF0, 0x90, 0x81, 0x60, 0xE0, 0x90, 0xB2, 0x88, 0xF0, 0x90, 0x81, 0x5F, 0xE0, 0x90, - 0xB2, 0x89, 0xF0, 0x90, 0xB2, 0x38, 0xE0, 0x90, 0xB2, 0xDC, 0xF0, 0x90, 0xB2, 0x39, 0xE0, 0x90, - 0xB2, 0xDD, 0xF0, 0x90, 0xB2, 0x36, 0xE0, 0x90, 0xB2, 0xDE, 0xF0, 0x90, 0xB2, 0x37, 0xE0, 0xFF, - 0x90, 0xB2, 0xDF, 0xF0, 0x90, 0xB2, 0xDE, 0xE0, 0x90, 0x81, 0x99, 0xF0, 0x90, 0x81, 0x98, 0xEF, - 0xF0, 0xE0, 0xC3, 0x13, 0xFE, 0xA3, 0xE0, 0x13, 0xFF, 0x90, 0x81, 0x98, 0xEE, 0xF0, 0xA3, 0xEF, - 0xF0, 0xE0, 0x90, 0xB2, 0xCA, 0xF0, 0x90, 0x81, 0x98, 0xE0, 0x90, 0xB2, 0xCB, 0xF0, 0xEE, 0xC3, - 0x13, 0xFE, 0xEF, 0x13, 0xFF, 0x90, 0x81, 0x98, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE0, 0x90, 0xB2, - 0xCC, 0xF0, 0x90, 0x81, 0x98, 0xE0, 0x90, 0xB2, 0xCD, 0xF0, 0x90, 0xB2, 0xCC, 0xE0, 0x90, 0xB2, - 0xCE, 0xF0, 0x90, 0xB2, 0xCD, 0xE0, 0x90, 0xB2, 0xCF, 0xF0, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x04, 0x01, 0xA0, 0x00, 0x90, 0x00, 0x00, 0x28, 0x0B, 0x0A, - 0x03, 0xB0, 0x00, 0x90, 0x00, 0x50, 0x02, 0x01, 0x02, 0x01, 0x40, 0x01, 0xF0, 0x00, 0x00, 0x14, - 0x0B, 0x05, 0x03, 0x60, 0x01, 0x20, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x80, 0x02, 0xE0, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x08, 0x02, 0x01, 0xA0, 0x00, - 0x78, 0x00, 0x00, 0x0A, 0x03, 0x05, 0x03, 0xB0, 0x00, 0x90, 0x00, 0x00, 0x23, 0x10, 0x01, 0x01, - 0x40, 0x01, 0xF0, 0x00, 0x00, 0x05, 0x03, 0x01, 0x01, 0xA4, 0x01, 0xF0, 0x00, 0x50, 0x23, 0x20, - 0x01, 0x01, 0x80, 0x02, 0xF0, 0x00, 0x50, 0x00, 0xC2, 0x00, 0xD2, 0x00, 0xF2, 0x00, 0xA2, 0x00, - 0x62, 0x00, 0xB2, 0x00, 0x72, 0x00, 0x32, 0x00, 0x3F, 0x00, 0x2F, 0x00, 0x20, 0x00, 0x1A, 0x00, - 0x16, 0x00, 0x0F, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x80, 0x00, 0x86, 0x00, 0x8A, 0x00, 0x8F, 0x00, - 0x96, 0x00, 0x9A, 0x00, 0x9F, 0x00, 0xAF, 0x90, 0xB0, 0x07, 0xE0, 0x44, 0x02, 0xF0, 0x44, 0x01, - 0xF0, 0x54, 0xFD, 0xF0, 0x54, 0xFE, 0xF0, 0x22, 0x7E, 0x80, 0xE4, 0xFD, 0xEE, 0x5F, 0x60, 0x09, - 0x90, 0xB0, 0x07, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x07, 0x90, 0xB0, 0x07, 0xE0, 0x54, 0xFD, 0xF0, - 0x90, 0xB0, 0x07, 0xE0, 0x44, 0x01, 0xF0, 0x54, 0xFE, 0xF0, 0xEE, 0xC3, 0x13, 0xFE, 0x0D, 0xED, - 0xB4, 0x08, 0xD9, 0x22, 0x90, 0xB0, 0x07, 0xE0, 0x44, 0x02, 0xF0, 0xE4, 0xFE, 0x90, 0xB0, 0x07, - 0xE0, 0xFF, 0x20, 0xE4, 0x09, 0x44, 0x01, 0xF0, 0x54, 0xFE, 0xF0, 0x7F, 0x01, 0x22, 0x0E, 0xEE, - 0xB4, 0x0A, 0xEA, 0x90, 0xB0, 0x07, 0xE0, 0x44, 0x01, 0xF0, 0x54, 0xFE, 0xF0, 0x7F, 0x00, 0x22, - 0x90, 0xB0, 0x07, 0xE0, 0x54, 0xFD, 0xF0, 0x44, 0x01, 0xF0, 0x44, 0x02, 0xF0, 0x22, 0xE4, 0xFF, - 0xFE, 0x90, 0xB0, 0x07, 0xE0, 0x54, 0xFE, 0xF0, 0x44, 0x01, 0xF0, 0x30, 0xE4, 0x08, 0xEF, 0x25, - 0xE0, 0x44, 0x01, 0xFF, 0x80, 0x04, 0xEF, 0x25, 0xE0, 0xFF, 0x0E, 0xEE, 0xB4, 0x08, 0xE2, 0x90, - 0xB0, 0x07, 0xE0, 0x54, 0xFE, 0xF0, 0x44, 0x01, 0xF0, 0x54, 0xFE, 0xF0, 0x22, 0xCC, 0xED, 0xCC, - 0x90, 0xB0, 0x07, 0x74, 0x03, 0xF0, 0xEF, 0x54, 0xFE, 0xFF, 0x12, 0x25, 0x57, 0x12, 0x25, 0x68, - 0x12, 0x25, 0x94, 0xEF, 0x70, 0x06, 0x12, 0x25, 0xC0, 0x7F, 0x00, 0x22, 0xCF, 0xEC, 0xCF, 0x12, - 0x25, 0x68, 0x12, 0x25, 0x94, 0xEF, 0x70, 0x06, 0x12, 0x25, 0xC0, 0x7F, 0x00, 0x22, 0xCF, 0xEB, - 0xCF, 0x12, 0x25, 0x68, 0x12, 0x25, 0x94, 0xEF, 0x70, 0x06, 0x12, 0x25, 0xC0, 0x7F, 0x00, 0x22, - 0x12, 0x25, 0xC0, 0x7F, 0x01, 0x22, 0xCC, 0xEF, 0xCC, 0xCB, 0xED, 0xCB, 0x90, 0xB0, 0x07, 0x74, - 0x03, 0xF0, 0xEC, 0x54, 0xFE, 0xFC, 0x12, 0x25, 0x57, 0xCF, 0xEC, 0xCF, 0x12, 0x25, 0x68, 0x12, - 0x25, 0x94, 0xEF, 0x70, 0x02, 0xFF, 0x22, 0xCF, 0xEB, 0xCF, 0x12, 0x25, 0x68, 0x12, 0x25, 0x94, - 0xEF, 0x70, 0x02, 0xFF, 0x22, 0x90, 0x81, 0x62, 0xE0, 0xB4, 0x02, 0x03, 0x12, 0x25, 0xC0, 0xEC, - 0x44, 0x01, 0xFC, 0x12, 0x25, 0x57, 0xCF, 0xEC, 0xCF, 0x12, 0x25, 0x68, 0x12, 0x25, 0x94, 0xEF, - 0x70, 0x02, 0xFF, 0x22, 0x12, 0x25, 0xCE, 0x12, 0x25, 0xC0, 0x22, 0x90, 0xB0, 0x07, 0xE0, 0x44, - 0x02, 0xF0, 0x44, 0x01, 0xF0, 0x54, 0xFD, 0xF0, 0x54, 0xFE, 0xF0, 0x22, 0x7E, 0x80, 0xE4, 0xFD, - 0xEE, 0x5F, 0x60, 0x09, 0x90, 0xB0, 0x07, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x07, 0x90, 0xB0, 0x07, - 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0xB0, 0x07, 0xE0, 0x44, 0x01, 0xF0, 0x54, 0xFE, 0xF0, 0xEE, 0xC3, - 0x13, 0xFE, 0x0D, 0xED, 0xB4, 0x08, 0xD9, 0x22, 0x90, 0xB0, 0x07, 0xE0, 0x44, 0x02, 0xF0, 0xE4, - 0xFE, 0x90, 0xB0, 0x07, 0xE0, 0xFF, 0x20, 0xE4, 0x09, 0x44, 0x01, 0xF0, 0x54, 0xFE, 0xF0, 0x7F, - 0x01, 0x22, 0x0E, 0xEE, 0xB4, 0x0A, 0xEA, 0x90, 0xB0, 0x07, 0xE0, 0x44, 0x01, 0xF0, 0x54, 0xFE, - 0xF0, 0x7F, 0x00, 0x22, 0x90, 0xB0, 0x07, 0xE0, 0x54, 0xFD, 0xF0, 0x44, 0x01, 0xF0, 0x44, 0x02, - 0xF0, 0x22, 0x90, 0xB0, 0x07, 0x74, 0x03, 0xF0, 0xEF, 0x54, 0xFE, 0xFF, 0x12, 0x26, 0x9B, 0x12, - 0x26, 0xAC, 0x12, 0x26, 0xD8, 0xEF, 0x70, 0x06, 0x12, 0x27, 0x04, 0x7F, 0x00, 0x22, 0x7F, 0x01, - 0x22, 0xCC, 0xED, 0xCC, 0x90, 0xB0, 0x07, 0x74, 0x03, 0xF0, 0xEF, 0x54, 0xFE, 0xFF, 0x12, 0x26, - 0x9B, 0x12, 0x26, 0xAC, 0x12, 0x26, 0xD8, 0xEF, 0x70, 0x06, 0x12, 0x27, 0x04, 0x7F, 0x00, 0x22, - 0xCF, 0xEC, 0xCF, 0x12, 0x26, 0xAC, 0x12, 0x26, 0xD8, 0xEF, 0x70, 0x06, 0x12, 0x27, 0x04, 0x7F, - 0x00, 0x22, 0xCF, 0xEB, 0xCF, 0x12, 0x26, 0xAC, 0x12, 0x26, 0xD8, 0xEF, 0x70, 0x06, 0x12, 0x27, - 0x04, 0x7F, 0x00, 0x22, 0x12, 0x27, 0x04, 0x7F, 0x01, 0x22, 0xE4, 0xFF, 0xFE, 0x90, 0xB0, 0x07, - 0xE0, 0x54, 0xFE, 0xF0, 0x44, 0x01, 0xF0, 0x30, 0xE4, 0x08, 0xEF, 0x25, 0xE0, 0x44, 0x01, 0xFF, - 0x80, 0x04, 0xEF, 0x25, 0xE0, 0xFF, 0x0E, 0xEE, 0xB4, 0x08, 0xE2, 0x90, 0xB0, 0x07, 0xE0, 0x54, - 0xFE, 0xF0, 0x44, 0x01, 0xF0, 0x54, 0xFE, 0xF0, 0x22, 0xCC, 0xEF, 0xCC, 0xCB, 0xED, 0xCB, 0x90, - 0xB0, 0x07, 0x74, 0x03, 0xF0, 0xEC, 0x54, 0xFE, 0xFC, 0x12, 0x26, 0x9B, 0xCF, 0xEC, 0xCF, 0x12, - 0x26, 0xAC, 0x12, 0x26, 0xD8, 0xEF, 0x70, 0x02, 0xFF, 0x22, 0xCF, 0xEB, 0xCF, 0x12, 0x26, 0xAC, - 0x12, 0x26, 0xD8, 0xEF, 0x70, 0x02, 0xFF, 0x22, 0x90, 0x81, 0x62, 0xE0, 0xB4, 0x02, 0x03, 0x12, - 0x27, 0x04, 0xEC, 0x44, 0x01, 0xFC, 0x12, 0x26, 0x9B, 0xCF, 0xEC, 0xCF, 0x12, 0x26, 0xAC, 0x12, - 0x26, 0xD8, 0xEF, 0x70, 0x02, 0xFF, 0x22, 0x12, 0x27, 0x7A, 0x12, 0x27, 0x04, 0x22, 0x90, 0xB0, - 0x07, 0x74, 0x03, 0xF0, 0x90, 0x80, 0xF9, 0x74, 0x42, 0xF0, 0xE4, 0x90, 0x81, 0x9D, 0xF0, 0x90, - 0x81, 0x9D, 0xE0, 0x25, 0xE0, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x28, 0xF5, 0x83, 0xE4, 0x93, - 0xFF, 0xF4, 0x60, 0x2D, 0x90, 0x81, 0x9D, 0xE0, 0xFE, 0xA3, 0xEF, 0xF0, 0xFD, 0xEE, 0x25, 0xE0, - 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x28, 0xF5, 0x83, 0xE4, 0x93, 0xFF, 0x90, 0x81, 0x9F, 0xF0, - 0xFB, 0x90, 0x81, 0x64, 0xE0, 0xFF, 0x12, 0x27, 0x31, 0x90, 0x81, 0x9D, 0xE0, 0x04, 0xF0, 0x80, - 0xBE, 0x22, 0xE4, 0x90, 0x81, 0x9D, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x9D, 0xF0, 0xA3, 0xF0, 0x7F, - 0x4A, 0x90, 0x81, 0x9E, 0xE0, 0xFD, 0x24, 0xFA, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xE0, - 0xFB, 0x12, 0x27, 0x31, 0x90, 0x81, 0x9E, 0xE0, 0x04, 0xF0, 0x70, 0x06, 0x90, 0x81, 0x9D, 0xE0, - 0x04, 0xF0, 0xC3, 0x90, 0x81, 0x9E, 0xE0, 0x94, 0x63, 0x90, 0x81, 0x9D, 0xE0, 0x64, 0x80, 0x94, - 0x80, 0x40, 0xCC, 0x7F, 0x00, 0x22, 0x12, 0x80, 0x03, 0xA4, 0x04, 0x30, 0x05, 0x44, 0x06, 0x60, - 0x11, 0x00, 0x12, 0x05, 0x13, 0xA3, 0x14, 0x04, 0x15, 0x04, 0x1F, 0x41, 0x20, 0xD0, 0x23, 0xDE, - 0x24, 0x88, 0x25, 0x70, 0x26, 0x32, 0x27, 0xE2, 0x28, 0x20, 0x2A, 0x91, 0x2B, 0x00, 0x2D, 0x05, - 0x2F, 0x9C, 0x30, 0x00, 0x31, 0xC4, 0x60, 0x86, 0x61, 0xE0, 0x62, 0x88, 0x63, 0x11, 0x64, 0x89, - 0x65, 0x00, 0x67, 0x94, 0x68, 0x7A, 0x69, 0x04, 0x6C, 0x11, 0x6D, 0x33, 0x6E, 0x22, 0x6F, 0x00, - 0x74, 0x20, 0x75, 0x0E, 0x77, 0xC4, 0xFF, 0xFF, 0x03, 0xA4, 0x06, 0x60, 0x2A, 0x91, 0x16, 0x00, - 0x1E, 0x00, 0x26, 0x32, 0x74, 0x20, 0xFF, 0xFF, 0x03, 0x64, 0x06, 0x78, 0x2A, 0x95, 0x16, 0x00, - 0x1E, 0x00, 0x26, 0xC2, 0x74, 0x60, 0xFF, 0xFF, 0x03, 0xC4, 0x27, 0xE2, 0x6C, 0x11, 0x6D, 0x33, - 0x6E, 0x22, 0x79, 0x80, 0x7A, 0x80, 0xFF, 0xFF, 0x03, 0x04, 0x27, 0xE2, 0x6C, 0xFF, 0x6D, 0xFF, - 0x6E, 0xFF, 0x79, 0x80, 0x7A, 0x80, 0xFF, 0xFF, 0x03, 0x04, 0x27, 0xEA, 0x6C, 0xFF, 0x6D, 0xFF, - 0x6E, 0xFF, 0x79, 0xA4, 0x7A, 0x35, 0xFF, 0xFF, 0x03, 0x04, 0x27, 0xEA, 0x6C, 0xFF, 0x6D, 0xFF, - 0x6E, 0xFF, 0x79, 0x1C, 0x7A, 0xA4, 0xFF, 0xFF, 0x2B, 0x00, 0xFF, 0xFF, 0x2B, 0x98, 0xFF, 0xFF, - 0x78, 0x7F, 0xE4, 0xF6, 0xD8, 0xFD, 0x75, 0x81, 0x17, 0x02, 0x29, 0x97, 0x02, 0x02, 0x25, 0xE4, - 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, 0x80, 0x01, 0xF2, 0x08, 0xDF, 0xF4, 0x80, - 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33, 0xC4, 0x54, 0x0F, 0x44, - 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF, 0xE4, 0x80, 0x0B, 0x01, - 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x02, 0xC8, 0xE4, 0x7E, 0x01, 0x93, 0x60, 0xBC, - 0xA3, 0xFF, 0x54, 0x3F, 0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE, 0xE4, 0x93, 0xA3, 0x60, 0x01, 0x0E, - 0xCF, 0x54, 0xC0, 0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8, 0xE4, 0x93, 0xA3, 0xFA, 0xE4, 0x93, 0xA3, - 0xF8, 0xE4, 0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xF0, 0xA3, 0xC8, 0xC5, - 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xDF, 0xE9, 0xDE, 0xE7, 0x80, 0xBE, 0xBB, 0x01, 0x06, 0x89, - 0x82, 0x8A, 0x83, 0xE0, 0x22, 0x50, 0x02, 0xE7, 0x22, 0xBB, 0xFE, 0x02, 0xE3, 0x22, 0x89, 0x82, - 0x8A, 0x83, 0xE4, 0x93, 0x22, 0xBB, 0x01, 0x0C, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, - 0xF5, 0x83, 0xE0, 0x22, 0x50, 0x06, 0xE9, 0x25, 0x82, 0xF8, 0xE6, 0x22, 0xBB, 0xFE, 0x06, 0xE9, - 0x25, 0x82, 0xF8, 0xE2, 0x22, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE4, - 0x93, 0x22, 0xBB, 0x01, 0x06, 0x89, 0x82, 0x8A, 0x83, 0xF0, 0x22, 0x50, 0x02, 0xF7, 0x22, 0xBB, - 0xFE, 0x01, 0xF3, 0x22, 0xA3, 0xF8, 0xE0, 0xC5, 0xF0, 0x25, 0xF0, 0xF0, 0xE5, 0x82, 0x15, 0x82, - 0x70, 0x02, 0x15, 0x83, 0xE0, 0xC8, 0x38, 0xF0, 0xE8, 0x22, 0xE8, 0x8F, 0xF0, 0xA4, 0xCC, 0x8B, - 0xF0, 0xA4, 0x2C, 0xFC, 0xE9, 0x8E, 0xF0, 0xA4, 0x2C, 0xFC, 0x8A, 0xF0, 0xED, 0xA4, 0x2C, 0xFC, - 0xEA, 0x8E, 0xF0, 0xA4, 0xCD, 0xA8, 0xF0, 0x8B, 0xF0, 0xA4, 0x2D, 0xCC, 0x38, 0x25, 0xF0, 0xFD, - 0xE9, 0x8F, 0xF0, 0xA4, 0x2C, 0xCD, 0x35, 0xF0, 0xFC, 0xEB, 0x8E, 0xF0, 0xA4, 0xFE, 0xA9, 0xF0, - 0xEB, 0x8F, 0xF0, 0xA4, 0xCF, 0xC5, 0xF0, 0x2E, 0xCD, 0x39, 0xFE, 0xE4, 0x3C, 0xFC, 0xEA, 0xA4, - 0x2D, 0xCE, 0x35, 0xF0, 0xFD, 0xE4, 0x3C, 0xFC, 0x22, 0x75, 0xF0, 0x08, 0x75, 0x82, 0x00, 0xEF, - 0x2F, 0xFF, 0xEE, 0x33, 0xFE, 0xCD, 0x33, 0xCD, 0xCC, 0x33, 0xCC, 0xC5, 0x82, 0x33, 0xC5, 0x82, - 0x9B, 0xED, 0x9A, 0xEC, 0x99, 0xE5, 0x82, 0x98, 0x40, 0x0C, 0xF5, 0x82, 0xEE, 0x9B, 0xFE, 0xED, - 0x9A, 0xFD, 0xEC, 0x99, 0xFC, 0x0F, 0xD5, 0xF0, 0xD6, 0xE4, 0xCE, 0xFB, 0xE4, 0xCD, 0xFA, 0xE4, - 0xCC, 0xF9, 0xA8, 0x82, 0x22, 0xB8, 0x00, 0xC1, 0xB9, 0x00, 0x59, 0xBA, 0x00, 0x2D, 0xEC, 0x8B, - 0xF0, 0x84, 0xCF, 0xCE, 0xCD, 0xFC, 0xE5, 0xF0, 0xCB, 0xF9, 0x78, 0x18, 0xEF, 0x2F, 0xFF, 0xEE, - 0x33, 0xFE, 0xED, 0x33, 0xFD, 0xEC, 0x33, 0xFC, 0xEB, 0x33, 0xFB, 0x10, 0xD7, 0x03, 0x99, 0x40, - 0x04, 0xEB, 0x99, 0xFB, 0x0F, 0xD8, 0xE5, 0xE4, 0xF9, 0xFA, 0x22, 0x78, 0x18, 0xEF, 0x2F, 0xFF, - 0xEE, 0x33, 0xFE, 0xED, 0x33, 0xFD, 0xEC, 0x33, 0xFC, 0xC9, 0x33, 0xC9, 0x10, 0xD7, 0x05, 0x9B, - 0xE9, 0x9A, 0x40, 0x07, 0xEC, 0x9B, 0xFC, 0xE9, 0x9A, 0xF9, 0x0F, 0xD8, 0xE0, 0xE4, 0xC9, 0xFA, - 0xE4, 0xCC, 0xFB, 0x22, 0x75, 0xF0, 0x10, 0xEF, 0x2F, 0xFF, 0xEE, 0x33, 0xFE, 0xED, 0x33, 0xFD, - 0xCC, 0x33, 0xCC, 0xC8, 0x33, 0xC8, 0x10, 0xD7, 0x07, 0x9B, 0xEC, 0x9A, 0xE8, 0x99, 0x40, 0x0A, - 0xED, 0x9B, 0xFD, 0xEC, 0x9A, 0xFC, 0xE8, 0x99, 0xF8, 0x0F, 0xD5, 0xF0, 0xDA, 0xE4, 0xCD, 0xFB, - 0xE4, 0xCC, 0xFA, 0xE4, 0xC8, 0xF9, 0x22, 0xEB, 0x9F, 0xF5, 0xF0, 0xEA, 0x9E, 0x42, 0xF0, 0xE9, - 0x9D, 0x42, 0xF0, 0xE8, 0x9C, 0x45, 0xF0, 0x22, 0xE8, 0x60, 0x0F, 0xEC, 0xC3, 0x13, 0xFC, 0xED, - 0x13, 0xFD, 0xEE, 0x13, 0xFE, 0xEF, 0x13, 0xFF, 0xD8, 0xF1, 0x22, 0xE8, 0x60, 0x0F, 0xEF, 0xC3, - 0x33, 0xFF, 0xEE, 0x33, 0xFE, 0xED, 0x33, 0xFD, 0xEC, 0x33, 0xFC, 0xD8, 0xF1, 0x22, 0xEC, 0xF0, - 0xA3, 0xED, 0xF0, 0xA3, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xA8, 0x82, 0x85, 0x83, 0xF0, 0xD0, - 0x83, 0xD0, 0x82, 0x12, 0x2B, 0xC1, 0x12, 0x2B, 0xC1, 0x12, 0x2B, 0xC1, 0x12, 0x2B, 0xC1, 0xE4, - 0x73, 0xE4, 0x93, 0xA3, 0xC5, 0x83, 0xC5, 0xF0, 0xC5, 0x83, 0xC8, 0xC5, 0x82, 0xC8, 0xF0, 0xA3, - 0xC5, 0x83, 0xC5, 0xF0, 0xC5, 0x83, 0xC8, 0xC5, 0x82, 0xC8, 0x22, 0xD0, 0x83, 0xD0, 0x82, 0xF8, - 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93, - 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3, 0xA3, 0xA3, 0x80, - 0xDF -#endif \ No newline at end of file diff --git a/uClinux-2.4.20-uc1/drivers/usb/audio.c b/uClinux-2.4.20-uc1/drivers/usb/audio.c index 2a6dd18..4fd0ff5 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/audio.c +++ b/uClinux-2.4.20-uc1/drivers/usb/audio.c @@ -1019,20 +1019,36 @@ static int usbin_start(struct usb_audiodev *as) bufsz = DESCFRAMES * maxsze; if (u->durb[0].urb.transfer_buffer) kfree(u->durb[0].urb.transfer_buffer); +#ifdef CONFIG_BOARD_W90N745 + u->durb[0].urb.transfer_buffer = ((unsigned long)kmalloc(bufsz, GFP_KERNEL) | 0x80000000); +#else u->durb[0].urb.transfer_buffer = kmalloc(bufsz, GFP_KERNEL); +#endif u->durb[0].urb.transfer_buffer_length = bufsz; if (u->durb[1].urb.transfer_buffer) kfree(u->durb[1].urb.transfer_buffer); +#ifdef CONFIG_BOARD_W90N745 + u->durb[1].urb.transfer_buffer = ((unsigned long)kmalloc(bufsz, GFP_KERNEL) | 0x80000000); +#else u->durb[1].urb.transfer_buffer = kmalloc(bufsz, GFP_KERNEL); +#endif u->durb[1].urb.transfer_buffer_length = bufsz; if (u->syncpipe) { if (u->surb[0].urb.transfer_buffer) kfree(u->surb[0].urb.transfer_buffer); +#ifdef CONFIG_BOARD_W90N745 + u->surb[0].urb.transfer_buffer = ((unsigned long)kmalloc(3*SYNCFRAMES, GFP_KERNEL) | 0x80000000); +#else u->surb[0].urb.transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL); +#endif u->surb[0].urb.transfer_buffer_length = 3*SYNCFRAMES; if (u->surb[1].urb.transfer_buffer) kfree(u->surb[1].urb.transfer_buffer); +#ifdef CONFIG_BOARD_W90N745 + u->surb[1].urb.transfer_buffer = ((unsigned long)kmalloc(3*SYNCFRAMES, GFP_KERNEL) | 0x80000000); +#else u->surb[1].urb.transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL); +#endif u->surb[1].urb.transfer_buffer_length = 3*SYNCFRAMES; } if (!u->durb[0].urb.transfer_buffer || !u->durb[1].urb.transfer_buffer || @@ -1384,20 +1400,36 @@ static int usbout_start(struct usb_audiodev *as) bufsz = DESCFRAMES * maxsze; if (u->durb[0].urb.transfer_buffer) kfree(u->durb[0].urb.transfer_buffer); +#ifdef CONFIG_BOARD_W90N745 + u->durb[0].urb.transfer_buffer = ((unsigned long)kmalloc(bufsz, GFP_KERNEL) | 0x80000000); +#else u->durb[0].urb.transfer_buffer = kmalloc(bufsz, GFP_KERNEL); +#endif u->durb[0].urb.transfer_buffer_length = bufsz; if (u->durb[1].urb.transfer_buffer) kfree(u->durb[1].urb.transfer_buffer); +#ifdef CONFIG_BOARD_W90N745 + u->durb[1].urb.transfer_buffer = ((unsigned long)kmalloc(bufsz, GFP_KERNEL) | 0x80000000); +#else u->durb[1].urb.transfer_buffer = kmalloc(bufsz, GFP_KERNEL); +#endif u->durb[1].urb.transfer_buffer_length = bufsz; if (u->syncpipe) { if (u->surb[0].urb.transfer_buffer) kfree(u->surb[0].urb.transfer_buffer); +#ifdef CONFIG_BOARD_W90N745 + u->surb[0].urb.transfer_buffer = ((unsigned long)kmalloc(3*SYNCFRAMES, GFP_KERNEL) | 0x80000000); +#else u->surb[0].urb.transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL); +#endif u->surb[0].urb.transfer_buffer_length = 3*SYNCFRAMES; if (u->surb[1].urb.transfer_buffer) kfree(u->surb[1].urb.transfer_buffer); +#ifdef CONFIG_BOARD_W90N745 + u->surb[1].urb.transfer_buffer = ((unsigned long)kmalloc(3*SYNCFRAMES, GFP_KERNEL) | 0x80000000); +#else u->surb[1].urb.transfer_buffer = kmalloc(3*SYNCFRAMES, GFP_KERNEL); +#endif u->surb[1].urb.transfer_buffer_length = 3*SYNCFRAMES; } if (!u->durb[0].urb.transfer_buffer || !u->durb[1].urb.transfer_buffer || @@ -2325,6 +2357,7 @@ static int usb_audio_mmap(struct file *file, struct vm_area_struct *vma) struct dmabuf *db; int ret = -EINVAL; +#ifndef CONFIG_BOARD_W90N745 lock_kernel(); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf_out(as)) != 0) @@ -2344,6 +2377,7 @@ static int usb_audio_mmap(struct file *file, struct vm_area_struct *vma) ret = dmabuf_mmap(db, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot); out: unlock_kernel(); +#endif return ret; } @@ -3674,6 +3708,12 @@ static void *usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffe dev->devnum, ctrlif, j); continue; } +#ifdef CONFIG_BOARD_W90N745 + if (iface->altsetting[2].bNumEndpoints < 1) { + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no endpoint\n", + dev->devnum, ctrlif, j); + continue; + } /* note: this requires the data endpoint to be ep0 and the optional sync ep to be ep1, which seems to be the case */ if (iface->altsetting[1].endpoint[0].bEndpointAddress & USB_DIR_IN) { @@ -3754,7 +3794,11 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum, return NULL; } buflen = buf[2] | (buf[3] << 8); +#ifdef CONFIG_BOARD_W90N745 + if (!(buffer = ((unsigned long)kmalloc(buflen, GFP_KERNEL) | 0x80000000))) +#else if (!(buffer = kmalloc(buflen, GFP_KERNEL))) +#endif return NULL; ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buffer, buflen); if (ret < 0) { diff --git a/uClinux-2.4.20-uc1/drivers/usb/hub.c b/uClinux-2.4.20-uc1/drivers/usb/hub.c index 841ae09..3ba5efe 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/hub.c +++ b/uClinux-2.4.20-uc1/drivers/usb/hub.c @@ -165,6 +165,9 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor err("Unable to kmalloc %Zd bytes for hub descriptor", sizeof(*hub->descriptor)); return -1; } +#ifdef CONFIG_BOARD_W90N745 + hub->descriptor = (struct usb_hub_descriptor *)((unsigned long)hub->descriptor | 0x80000000); +#endif /* Request the entire hub descriptor. */ ret = usb_get_hub_descriptor(dev, hub->descriptor, sizeof(*hub->descriptor)); @@ -198,7 +201,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor dbg("unknown reserved power switching mode"); break; } - +#ifndef CONFIG_BOARD_W90N745 switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) { case 0x00: dbg("global over-current protection"); @@ -211,7 +214,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor dbg("no over-current protection"); break; } - +#endif switch (dev->descriptor.bDeviceProtocol) { case 0: break; @@ -264,6 +267,9 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor kfree(hub->descriptor); return -1; } +#ifdef CONFIG_BOARD_W90N745 + hubstatus = (struct usb_hub_status *)((unsigned long)hubstatus | 0x80000000); +#endif ret = usb_get_hub_status(dev, hubstatus); if (ret < 0) { err("Unable to get hub status (err = %d)", ret); @@ -519,6 +525,9 @@ static int usb_hub_port_status(struct usb_device *hub, int port, portsts = kmalloc(sizeof(*portsts), GFP_KERNEL); if (portsts) { +#ifdef CONFIG_BOARD_W90N745 + portsts = (struct usb_port_status *)((unsigned long)portsts|0x80000000); +#endif ret = usb_get_port_status(hub, port + 1, portsts); if (ret < 0) err("%s (%d) failed (err = %d)", __FUNCTION__, hub->devnum, ret); @@ -757,8 +766,13 @@ static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port, if (len == sizeof dev->devpath) warn ("devpath size! usb/%03d/%03d path %s", dev->bus->busnum, dev->devnum, dev->devpath); +#ifndef CONFIG_BOARD_W90N745 info("new USB device %s-%s, assigned address %d", dev->bus->bus_name, dev->devpath, dev->devnum); +#else + info("new USB device %s, assigned address %d", + dev->devpath, dev->devnum); +#endif /* Run it through the hoops (find a driver, etc) */ if (!usb_new_device(dev)) @@ -877,6 +891,9 @@ static void usb_hub_events(void) if (!hubsts) { err("couldn't allocate hubsts"); } else { +#ifdef CONFIG_BOARD_W90N745 + hubsts = (struct usb_hub_status *)((unsigned long)hubsts|0x80000000); +#endif if (usb_get_hub_status(dev, hubsts) < 0) err("get_hub_status failed"); else { @@ -1055,6 +1072,9 @@ int usb_reset_device(struct usb_device *dev) if (!descriptor) { return -ENOMEM; } +#ifdef CONFIG_BOARD_W90N745 + descriptor = (struct usb_device_descriptor *)((unsigned long)descriptor|0x80000000); +#endif ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, descriptor, sizeof(*descriptor)); if (ret < 0) diff --git a/uClinux-2.4.20-uc1/drivers/usb/serial/Config.in b/uClinux-2.4.20-uc1/drivers/usb/serial/Config.in index 64dabbb..2d611fe 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/serial/Config.in +++ b/uClinux-2.4.20-uc1/drivers/usb/serial/Config.in @@ -8,6 +8,9 @@ dep_tristate 'USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB if [ "$CONFIG_USB_SERIAL" != "n" ]; then dep_bool ' USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG $CONFIG_USB_SERIAL dep_mbool ' USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC $CONFIG_USB_SERIAL +if [ "$CONFIG_USB_SERIAL_GENERIC" = "y" ]; then + bool ' Support Winbond VCOM with Generic Serial Driver' $CONFIG_WINBOND_VCOM +fi dep_tristate ' USB Belkin and Peracom Single Port Serial Driver' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL dep_tristate ' USB ConnectTech WhiteHEAT Serial Driver' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL dep_tristate ' USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL diff --git a/uClinux-2.4.20-uc1/drivers/usb/serial/usbserial.c b/uClinux-2.4.20-uc1/drivers/usb/serial/usbserial.c index 79979c6..06c3a47 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/serial/usbserial.c +++ b/uClinux-2.4.20-uc1/drivers/usb/serial/usbserial.c @@ -329,8 +329,14 @@ static void generic_shutdown (struct usb_serial *serial); #ifdef CONFIG_USB_SERIAL_GENERIC -static __u16 vendor = 0x05f9; -static __u16 product = 0xffff; +#ifdef CONFIG_WINBOND_VCOM +static __u16 vendor = 0x0416; +static __u16 product = 0x7021; +#else +static __u16 vendor = 0x05f9; +static __u16 product = 0xffff; +#endif +#endif static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ @@ -940,6 +946,13 @@ static int generic_write (struct usb_serial_port *port, int from_user, const uns usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer); +#ifdef CONFIG_WINBOND_VCOM + /* + Send vendor command to USBD regarding the following bulk out length. + */ + usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + 0xA0, 0x40, 0x12, count, NULL, 0, 100); +#endif /* set up our urb */ usb_fill_bulk_urb (port->write_urb, serial->dev, usb_sndbulkpipe (serial->dev, diff --git a/uClinux-2.4.20-uc1/drivers/usb/storage/initializers.c b/uClinux-2.4.20-uc1/drivers/usb/storage/initializers.c index dd03ef7..924ee88 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/storage/initializers.c +++ b/uClinux-2.4.20-uc1/drivers/usb/storage/initializers.c @@ -46,14 +46,33 @@ int usb_stor_euscsi_init(struct us_data *us) { unsigned char data = 0x1; int result; +#ifdef CONFIG_BOARD_W90N745 + unsigned char *datap = kmalloc(sizeof(unsigned char)*1, GFP_KERNEL); + + if(!datap) { + printk("Can't alloc memory for eusci_init\n"); + return 0; + } + datap = (unsigned char *)((unsigned long)datap | 0x80000000); +#endif US_DEBUGP("Attempting to init eUSCSI bridge...\n"); +#ifndef CONFIG_BOARD_W90N745 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0), 0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR, 0x01, 0x0, &data, 0x1, 5*HZ); US_DEBUGP("-- result is %d\n", result); US_DEBUGP("-- data afterwards is %d\n", data); +#else + result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0), + 0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR, + 0x01, 0x0, datap, 0x1, 5*HZ); + US_DEBUGP("-- result is %d\n", result); + US_DEBUGP("-- data afterwards is %d\n", *datap); + if(datap) + kfree((unsigned char *)((unsigned long)datap & 0x7fffffff)); +#endif return 0; } diff --git a/uClinux-2.4.20-uc1/drivers/usb/storage/protocol.c b/uClinux-2.4.20-uc1/drivers/usb/storage/protocol.c index ea93770..2b7b5f7 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/storage/protocol.c +++ b/uClinux-2.4.20-uc1/drivers/usb/storage/protocol.c @@ -91,7 +91,11 @@ void usb_stor_qic157_command(Scsi_Cmnd *srb, struct us_data *us) * a unsigned char cmnd[12], so we know we have storage available */ for (; srb->cmd_len<12; srb->cmd_len++) +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[srb->cmd_len] = 0; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[srb->cmd_len] = 0; +#endif /* set command length to 12 bytes */ srb->cmd_len = 12; @@ -118,7 +122,11 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us) /* Pad the ATAPI command with zeros */ for (; srb->cmd_len<12; srb->cmd_len++) +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[srb->cmd_len] = 0; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[srb->cmd_len] = 0; +#endif /* set command length to 12 bytes */ srb->cmd_len = 12; @@ -132,6 +140,7 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us) /* save the command so we can tell what it was */ old_cmnd = srb->cmnd[0]; +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[11] = 0; srb->cmnd[10] = 0; srb->cmnd[9] = 0; @@ -144,12 +153,27 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us) srb->cmnd[2] = srb->cmnd[2]; srb->cmnd[1] = srb->cmnd[1]; srb->cmnd[0] = srb->cmnd[0] | 0x40; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[11] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[10] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[9] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[8] = srb->cmnd[4]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[7] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[6] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[5] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[4] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[3] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[2] = srb->cmnd[2]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[1] = srb->cmnd[1]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[0] = srb->cmnd[0] | 0x40; +#endif break; /* change READ_6/WRITE_6 to READ_10/WRITE_10, which * are ATAPI commands */ case WRITE_6: case READ_6: +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[11] = 0; srb->cmnd[10] = 0; srb->cmnd[9] = 0; @@ -162,6 +186,20 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us) srb->cmnd[2] = 0; srb->cmnd[1] = srb->cmnd[1] & 0xE0; srb->cmnd[0] = srb->cmnd[0] | 0x20; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[11] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[10] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[9] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[8] = srb->cmnd[4]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[7] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[6] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[5] = srb->cmnd[3]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[4] = srb->cmnd[2]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[3] = srb->cmnd[1] & 0x1F; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[2] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[1] = srb->cmnd[1] & 0xE0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[0] = srb->cmnd[0] | 0x20; +#endif break; } /* end switch on cmnd[0] */ @@ -202,7 +240,11 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) /* for INQUIRY, UFI devices only ever return 36 bytes */ case INQUIRY: +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[4] = 36; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[4] = 36; +#endif break; /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */ @@ -211,12 +253,19 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) /* save the command so we can tell what it was */ old_cmnd = srb->cmnd[0]; +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[11] = 0; srb->cmnd[10] = 0; srb->cmnd[9] = 0; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[11] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[10] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[9] = 0; +#endif /* if we're sending data, we send all. If getting data, * get the minimum */ +#ifndef CONFIG_BOARD_W90N745 if (srb->cmnd[0] == MODE_SELECT) srb->cmnd[8] = srb->cmnd[4]; else @@ -230,6 +279,21 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) srb->cmnd[2] = srb->cmnd[2]; srb->cmnd[1] = srb->cmnd[1]; srb->cmnd[0] = srb->cmnd[0] | 0x40; +#else + if (srb->cmnd[0] == MODE_SELECT) + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[8] = srb->cmnd[4]; + else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[8] = 8; + + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[7] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[6] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[5] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[4] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[3] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[2] = srb->cmnd[2]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[1] = srb->cmnd[1]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[0] = srb->cmnd[0] | 0x40; +#endif break; /* again, for MODE_SENSE_10, we get the minimum (8) */ @@ -240,13 +304,18 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */ case REQUEST_SENSE: +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[4] = 18; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[4] = 18; +#endif break; /* change READ_6/WRITE_6 to READ_10/WRITE_10, which * are UFI commands */ case WRITE_6: case READ_6: +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[11] = 0; srb->cmnd[10] = 0; srb->cmnd[9] = 0; @@ -259,6 +328,20 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) srb->cmnd[2] = 0; srb->cmnd[1] = srb->cmnd[1] & 0xE0; srb->cmnd[0] = srb->cmnd[0] | 0x20; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[11] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[10] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[9] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[8] = srb->cmnd[4]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[7] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[6] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[5] = srb->cmnd[3]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[4] = srb->cmnd[2]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[3] = srb->cmnd[1] & 0x1F; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[2] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[1] = srb->cmnd[1] & 0xE0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[0] = srb->cmnd[0] | 0x20; +#endif break; } /* end switch on cmnd[0] */ @@ -297,6 +380,7 @@ void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us) case WRITE_6: case READ_6: srb->cmd_len = 12; +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[11] = 0; srb->cmnd[10] = 0; srb->cmnd[9] = 0; @@ -309,12 +393,27 @@ void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us) srb->cmnd[2] = 0; srb->cmnd[1] = srb->cmnd[1] & 0xE0; srb->cmnd[0] = srb->cmnd[0] | 0x20; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[11] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[10] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[9] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[8] = srb->cmnd[4]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[7] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[6] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[5] = srb->cmnd[3]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[4] = srb->cmnd[2]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[3] = srb->cmnd[1] & 0x1F; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[2] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[1] = srb->cmnd[1] & 0xE0; + ((unsigned char *)((unsigned long)srb->cmnd |0x80000000))[0] = srb->cmnd[0] | 0x20; +#endif break; /* convert MODE_SELECT data here */ case MODE_SENSE: case MODE_SELECT: srb->cmd_len = 12; +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[11] = 0; srb->cmnd[10] = 0; srb->cmnd[9] = 0; @@ -327,6 +426,20 @@ void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us) srb->cmnd[2] = srb->cmnd[2]; srb->cmnd[1] = srb->cmnd[1]; srb->cmnd[0] = srb->cmnd[0] | 0x40; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[11] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[10] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[9] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[8] = srb->cmnd[4]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[7] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[6] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[5] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[4] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[3] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[2] = srb->cmnd[2]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[1] = srb->cmnd[1]; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[0] = srb->cmnd[0] | 0x40; +#endif break; } /* switch (srb->cmnd[0]) */ } /* if (us->flags & US_FL_MODE_XLATE) */ diff --git a/uClinux-2.4.20-uc1/drivers/usb/storage/scsiglue.c b/uClinux-2.4.20-uc1/drivers/usb/storage/scsiglue.c index 316a7f5..cc9738f 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/storage/scsiglue.c +++ b/uClinux-2.4.20-uc1/drivers/usb/storage/scsiglue.c @@ -459,7 +459,11 @@ int usb_stor_scsiSense10to6( Scsi_Cmnd* the10 ) int sgLength=0; US_DEBUGP("-- converting 10 byte sense data to 6 byte\n"); +#ifndef CONFIG_BOARD_W90N745 the10->cmnd[0] = the10->cmnd[0] & 0xBF; +#else + ((unsigned char *)((unsigned long)the10->cmnd | 0x80000000))[0] = the10->cmnd[0] & 0xBF; +#endif /* Determine buffer locations */ usb_stor_scsiSenseParseBuffer( the10, &the6Locations, &the10Locations, @@ -638,7 +642,11 @@ int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 ) int lsb=0,lsi=0,ldb=0,ldi=0; US_DEBUGP("-- converting 6 byte sense data to 10 byte\n"); +#ifndef CONFIG_BOARD_W90N745 the6->cmnd[0] = the6->cmnd[0] | 0x40; +#else + ((unsigned char *)((unsigned long)the6->cmnd | 0x80000000))[0] = the6->cmnd[0] | 0x40; +#endif /* Determine buffer locations */ usb_stor_scsiSenseParseBuffer( the6, &the6Locations, &the10Locations, diff --git a/uClinux-2.4.20-uc1/drivers/usb/storage/transport.c b/uClinux-2.4.20-uc1/drivers/usb/storage/transport.c index 2955b17..9f41101 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/storage/transport.c +++ b/uClinux-2.4.20-uc1/drivers/usb/storage/transport.c @@ -368,6 +368,9 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, if (!dr) return -ENOMEM; +#ifdef CONFIG_BOARD_W90N745 + dr = (struct usb_ctrlrequest *)((unsigned long)dr | 0x80000000); +#endif /* fill in the structure */ dr->bRequestType = requesttype; dr->bRequest = request; @@ -708,12 +711,21 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) memcpy(old_cmnd, srb->cmnd, MAX_COMMAND_SIZE); /* set the command and the LUN */ +#ifndef CONFIG_BOARD_W90N745 srb->cmnd[0] = REQUEST_SENSE; srb->cmnd[1] = old_cmnd[1] & 0xE0; srb->cmnd[2] = 0; srb->cmnd[3] = 0; srb->cmnd[4] = 18; srb->cmnd[5] = 0; +#else + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[0] = REQUEST_SENSE; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[1] = old_cmnd[1] & 0xE0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[2] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[3] = 0; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[4] = 18; + ((unsigned char *)((unsigned long)srb->cmnd | 0x80000000))[5] = 0; +#endif /* set the transfer direction */ old_sc_data_direction = srb->sc_data_direction; @@ -739,7 +751,11 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) srb->request_bufflen = old_request_bufflen; srb->use_sg = old_sg; srb->sc_data_direction = old_sc_data_direction; +#ifndef CONFIG_BOARD_W90N745 memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE); +#else + memcpy(((unsigned char *)((unsigned long)srb->cmnd | 0x80000000)), old_cmnd, MAX_COMMAND_SIZE); +#endif if (temp_result == USB_STOR_TRANSPORT_ABORTED) { US_DEBUGP("-- auto-sense aborted\n"); @@ -826,10 +842,17 @@ void usb_stor_CBI_irq(struct urb *urb) } /* was this a command-completion interrupt? */ +#ifndef CONFIG_BOARD_W90N745 if (us->irqbuf[0] && (us->subclass != US_SC_UFI)) { US_DEBUGP("-- not a command-completion IRQ\n"); return; } +#else + if (((unsigned char *)((unsigned long)us->irqbuf | 0x80000000))[0] && (us->subclass != US_SC_UFI)) { + US_DEBUGP("-- not a command-completion IRQ\n"); + return; + } +#endif /* was this a wanted interrupt? */ if (!atomic_read(us->ip_wanted)) { @@ -841,8 +864,13 @@ void usb_stor_CBI_irq(struct urb *urb) atomic_set(us->ip_wanted, 0); /* copy the valid data */ +#ifndef CONFIG_BOARD_W90N745 us->irqdata[0] = us->irqbuf[0]; us->irqdata[1] = us->irqbuf[1]; +#else + us->irqdata[0] = ((unsigned char *)((unsigned long)us->irqbuf | 0x80000000))[0]; + us->irqdata[1] = ((unsigned char *)((unsigned long)us->irqbuf | 0x80000000))[1]; +#endif /* wake up the command thread */ US_DEBUGP("-- Current value of ip_waitq is: %d\n", @@ -942,7 +970,11 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) srb->cmnd[0] == INQUIRY) return USB_STOR_TRANSPORT_GOOD; else +#ifndef CONFIG_BOARD_W90N745 if (((unsigned char*)us->irq_urb->transfer_buffer)[0]) +#else + if (((unsigned char*)((unsigned long)us->irq_urb->transfer_buffer | 0x80000000))[0]) +#endif return USB_STOR_TRANSPORT_FAILED; else return USB_STOR_TRANSPORT_GOOD; @@ -1046,6 +1078,9 @@ int usb_stor_Bulk_max_lun(struct us_data *us) if (!data) { return 0; } +#ifdef CONFIG_BOARD_W90N745 + data = (unsigned char *)((unsigned long)data | 0x80000000); +#endif /* issue the command -- use usb_control_msg() because * the state machine is not yet alive */ @@ -1102,6 +1137,10 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) return USB_STOR_TRANSPORT_ERROR; } +#ifdef CONFIG_BOARD_W90N745 + bcb = (struct bulk_cb_wrap *)((unsigned long)bcb | 0x80000000); + bcs = (struct bulk_cs_wrap *)((unsigned long)bcs | 0x80000000); +#endif /* set up the command wrapper */ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = cpu_to_le32(usb_stor_transfer_length(srb)); @@ -1286,9 +1325,15 @@ int usb_stor_CB_reset(struct us_data *us) if (!us->pusb_dev) return SUCCESS; +#ifndef CONFIG_BOARD_W90N745 memset(cmd, 0xFF, sizeof(cmd)); cmd[0] = SEND_DIAGNOSTIC; cmd[1] = 4; +#else + memset((unsigned char*)((unsigned long)cmd | 0x80000000),0xFF,sizeof(cmd)); + ((unsigned char*)((unsigned long)cmd | 0x80000000))[0] = SEND_DIAGNOSTIC; + ((unsigned char*)((unsigned long)cmd | 0x80000000))[1] = 4; +#endif result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE, diff --git a/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c b/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c index b7c89c1..fc8911f 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c +++ b/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c @@ -53,7 +53,9 @@ #include #include +#ifndef CONFIG_BOARD_W90N745 #include +#endif #include #include #include @@ -78,12 +80,16 @@ #include "usb-ohci.h" +#ifndef CONFIG_BOARD_W90N745 #include "hcd.h" +#endif #ifdef CONFIG_PMAC_PBOOK #include #include +#ifndef CONFIG_BOARD_W90N745 #include +#endif #ifndef CONFIG_PM #define CONFIG_PM #endif @@ -129,7 +135,253 @@ static inline u32 roothub_status (struct ohci *hc) static u32 roothub_portstatus (struct ohci *hc, int i) { return read_roothub (hc, portstatus [i], 0xffe0fce0); } +#ifdef CONFIG_BOARD_W90N745 + + +extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, + int bustime, int isoc); +extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, + int isoc); +extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); + + /*pool support functions*/ +struct ohci_pool * +ohci_pool_create (const char *name, + size_t size, size_t align, size_t allocation, int flags) +{ + struct ohci_pool *retval; + + if (align == 0) + align = 1; + if (size == 0) + return 0; + else if (size < align) + size = align; + else if ((size % align) != 0) { + size += align + 1; + size &= ~(align - 1); + } + + if (allocation == 0) { + if (PAGE_SIZE < size) + allocation = size; + else + allocation = PAGE_SIZE; + // FIXME: round up for less fragmentation + } else if (allocation < size) + return 0; + + if (!(retval = kmalloc (sizeof *retval, flags))) + return retval; + +#ifdef CONFIG_PCIPOOL_DEBUG + flags |= SLAB_POISON; +#endif + + strncpy (retval->name, name, sizeof retval->name); + retval->name [sizeof retval->name - 1] = 0; + + INIT_LIST_HEAD (&retval->page_list); + spin_lock_init (&retval->lock); + retval->size = size; + retval->flags = flags; + retval->allocation = allocation; + retval->blocks_per_page = allocation / size; + init_waitqueue_head (&retval->waitq); + +#ifdef CONFIG_PCIPOOL_DEBUG + printk (KERN_DEBUG "pcipool create%s size %d, %d/page (%d alloc)\n", + retval->name, size, + retval->blocks_per_page, allocation); +#endif + + return retval; +} + +void * +ohci_pool_alloc (struct ohci_pool *pool, int mem_flags, dma_addr_t *handle) +{ + unsigned long flags; + struct list_head *entry; + struct pci_page *page; + int map, block; + size_t offset; + void *retval; + +restart: + spin_lock_irqsave (&pool->lock, flags); + list_for_each (entry, &pool->page_list) { + int i; + page = list_entry (entry, struct pci_page, page_list); + /* only cachable accesses here ... */ + for (map = 0, i = 0; + i < pool->blocks_per_page; + i += BITS_PER_LONG, map++) { + if (page->bitmap[map] == 0) + continue; + block = ffz (~ page->bitmap [map]); + if ((i + block) < pool->blocks_per_page) { + clear_bit (block, &page->bitmap [map]); + offset = (BITS_PER_LONG * map) + block; + offset *= pool->size; + goto ready; + } + } + } + if (!(page = pool_alloc_page (pool, mem_flags))) { + if (mem_flags == SLAB_KERNEL) { + DECLARE_WAITQUEUE (wait, current); + + current->state = TASK_INTERRUPTIBLE; + add_wait_queue (&pool->waitq, &wait); + spin_unlock_irqrestore (&pool->lock, flags); + + schedule_timeout (POOL_TIMEOUT_JIFFIES); + + current->state = TASK_RUNNING; + remove_wait_queue (&pool->waitq, &wait); + goto restart; + } + retval = 0; + goto done; + } + + clear_bit (0, &page->bitmap [0]); + offset = 0; +ready: + retval = offset + page->vaddr; + *handle = offset + page->dma; +done: + spin_unlock_irqrestore (&pool->lock, flags); + return retval; +} + +void +ohci_pool_free (struct ohci_pool *pool, void *vaddr, dma_addr_t dma) +{ + struct pci_page *page; + unsigned long flags; + int map, block; + + if ((page = pool_find_page (pool, dma)) == 0) { + printk (KERN_ERR "pci_pool_free %s, %p/%x (bad dma)\n", + pool->name, vaddr, (int) (dma & 0xffffffff)); + return; + } + + block = dma - page->dma; + block /= pool->size; + map = block / BITS_PER_LONG; + block %= BITS_PER_LONG; + + if (pool->flags & SLAB_POISON) + memset (vaddr, POOL_POISON_BYTE, pool->size); + + spin_lock_irqsave (&pool->lock, flags); + set_bit (block, &page->bitmap [map]); + if (waitqueue_active (&pool->waitq)) + wake_up (&pool->waitq); + /* + * Resist a temptation to do + * if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page); + * it is not interrupt safe. Better have empty pages hang around. + */ + spin_unlock_irqrestore (&pool->lock, flags); +} + +static struct pci_page * +pool_find_page (struct ohci_pool *pool, dma_addr_t dma) +{ + unsigned long flags; + struct list_head *entry; + struct pci_page *page; + + spin_lock_irqsave (&pool->lock, flags); + list_for_each (entry, &pool->page_list) { + page = list_entry (entry, struct pci_page, page_list); + if (dma < page->dma) + continue; + if (dma < (page->dma + pool->allocation)) + goto done; + } + page = 0; +done: + spin_unlock_irqrestore (&pool->lock, flags); + return page; +} + +void +ohci_pool_destroy (struct ohci_pool *pool) +{ + unsigned long flags; + + spin_lock_irqsave (&pool->lock, flags); + while (!list_empty (&pool->page_list)) { + struct pci_page *page; + page = list_entry (pool->page_list.next, + struct pci_page, page_list); + if (is_page_busy (pool->blocks_per_page, page->bitmap)) { + /* leak the still-in-use consistent memory */ + list_del (&page->page_list); + kfree ((void*)page); + } else + pool_free_page (pool, page); + } + spin_unlock_irqrestore (&pool->lock, flags); + kfree ((void*)pool); +} + +static struct pci_page * +pool_alloc_page (struct ohci_pool *pool, int mem_flags) +{ + struct pci_page *page; + int mapsize; + + mapsize = pool->blocks_per_page; + mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG; + mapsize *= sizeof (long); + + page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags); + if (!page) + return 0; + page->vaddr = ohci_alloc_consistent (pool->allocation, + &page->dma); + if (page->vaddr) { + memset (page->bitmap, 0xff, mapsize); // bit set == free + if (pool->flags & SLAB_POISON) + memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); + list_add (&page->page_list, &pool->page_list); + } else { + kfree ((void*)page); + page = 0; + } + return page; +} + +static void +pool_free_page (struct ohci_pool *pool, struct pci_page *page) +{ + dma_addr_t dma = page->dma; + + if (pool->flags & SLAB_POISON) + memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); + ohci_free_consistent (pool->allocation, page->vaddr, dma); + list_del (&page->page_list); + kfree ((void*)page); +} + +static inline int +is_page_busy (int blocks, unsigned long *bitmap) +{ + while (blocks > 0) { + if (*bitmap++ != ~0UL) + return 1; + blocks -= BITS_PER_LONG; + } + return 0; +} +#endif /*-------------------------------------------------------------------------* * URB support functions *-------------------------------------------------------------------------*/ @@ -157,17 +409,26 @@ static void urb_free_priv (struct ohci *hc, urb_priv_t * urb_priv) /* unmap CTRL URB setup */ if (usb_pipecontrol (td->urb->pipe)) { +#ifndef CONFIG_BOARD_W90N745 pci_unmap_single (hc->ohci_dev, td->data_dma, 8, PCI_DMA_TODEVICE); +#else + ohci_unmap_single(td->data_dma, 8, PCI_DMA_TODEVICE); +#endif /* CTRL data buffer starts at td 1 if len > 0 */ if (len && last > 0) td = urb_priv->td [1]; } +#ifndef CONFIG_BOARD_W90N745 /* unmap data buffer */ if (len && td->data_dma) pci_unmap_single (hc->ohci_dev, td->data_dma, len, dir); +#else + if (len && td->data_dma) + ohci_unmap_single(td->data_dma, 8, PCI_DMA_TODEVICE); +#endif for (i = 0; i <= last; i++) { td = urb_priv->td [i]; @@ -442,7 +703,9 @@ static void ohci_dump_roothub (ohci_t *controller, int verbose) static void ohci_dump (ohci_t *controller, int verbose) { +#ifndef CONFIG_BOARD_W90N745 dbg ("OHCI controller usb-%s state", controller->ohci_dev->slot_name); +#endif // dumps some of the state we know about ohci_dump_status (controller); @@ -483,12 +746,20 @@ static int sohci_return_urb (struct ohci *hc, struct urb * urb) switch (usb_pipetype (urb->pipe)) { case PIPE_INTERRUPT: +#ifdef CONFIG_BOARD_W90N745 + ohci_unmap_single(urb_priv->td [0]->data_dma, + urb->transfer_buffer_length, + usb_pipeout (urb->pipe) + ? PCI_DMA_TODEVICE + : PCI_DMA_FROMDEVICE); +#else pci_unmap_single (hc->ohci_dev, urb_priv->td [0]->data_dma, urb->transfer_buffer_length, usb_pipeout (urb->pipe) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); +#endif urb->complete (urb); /* implicitly requeued */ @@ -500,12 +771,20 @@ static int sohci_return_urb (struct ohci *hc, struct urb * urb) case PIPE_ISOCHRONOUS: for (urbt = urb->next; urbt && (urbt != urb); urbt = urbt->next); if (urbt) { /* send the reply and requeue URB */ +#ifdef CONFIG_BOARD_W90N745 + ohci_unmap_single(urb_priv->td [0]->data_dma, + urb->transfer_buffer_length, + usb_pipeout (urb->pipe) + ? PCI_DMA_TODEVICE + : PCI_DMA_FROMDEVICE); +#else pci_unmap_single (hc->ohci_dev, urb_priv->td [0]->data_dma, urb->transfer_buffer_length, usb_pipeout (urb->pipe) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); +#endif urb->complete (urb); spin_lock_irqsave (&usb_ed_lock, flags); urb->actual_length = 0; @@ -855,8 +1134,10 @@ static int sohci_free_dev (struct usb_device * usb_dev) if (ed->state != ED_NEW) { if (ed->state == ED_OPER) { /* driver on that interface didn't unlink an urb */ +#ifndef CONFIG_BOARD_W90N745 dbg ("driver usb-%s dev %d ed 0x%x unfreed URB", ohci->ohci_dev->slot_name, usb_dev->devnum, i); +#endif ep_unlink (ohci, ed); } ep_rm_ed (usb_dev, ed); @@ -900,8 +1181,10 @@ static int sohci_free_dev (struct usb_device * usb_dev) } } else { /* likely some interface's driver has a refcount bug */ +#ifndef CONFIG_BOARD_W90N745 err ("bus %s devnum %d deletion in interrupt", ohci->ohci_dev->slot_name, usb_dev->devnum); +#endif BUG (); } } @@ -1369,12 +1652,20 @@ static void td_submit_urb (struct urb * urb) urb_priv->td_cnt = 0; if (data_len) { +#ifdef CONFIG_BOARD_W90N745 + data = ohci_map_single(urb->transfer_buffer, data_len, + usb_pipeout (urb->pipe) + ? PCI_DMA_TODEVICE + : PCI_DMA_FROMDEVICE + ); +#else data = pci_map_single (ohci->ohci_dev, urb->transfer_buffer, data_len, usb_pipeout (urb->pipe) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE ); +#endif } else data = 0; @@ -1417,11 +1708,18 @@ static void td_submit_urb (struct urb * urb) case PIPE_CONTROL: info = TD_CC | TD_DP_SETUP | TD_T_DATA0; +#ifdef CONFIG_BOARD_W90N745 + td_fill (ohci, info, + ohci_map_single(urb->setup_packet, 8, + PCI_DMA_TODEVICE), + 8, urb, cnt++); +#else td_fill (ohci, info, pci_map_single (ohci->ohci_dev, urb->setup_packet, 8, PCI_DMA_TODEVICE), 8, urb, cnt++); +#endif if (data_len > 0) { info = usb_pipeout (urb->pipe)? TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; @@ -1814,8 +2112,10 @@ static int rh_send_irq (ohci_t * ohci, void * rh_data, int rh_len) num_ports = roothub_a (ohci) & RH_A_NDP; if (num_ports > MAX_ROOT_PORTS) { +#ifndef CONFIG_BOARD_W90N745 err ("bogus NDP=%d for OHCI usb-%s", num_ports, ohci->ohci_dev->slot_name); +#endif err ("rereads as NDP=%d", readl (&ohci->regs->roothub.a) & RH_A_NDP); /* retry later; "should not happen" */ @@ -2162,9 +2462,11 @@ static int hc_reset (ohci_t * ohci) /* Disable HC interrupts */ writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); +#ifndef CONFIG_BOARD_W90N745 dbg("USB HC reset_hc usb-%s: ctrl = 0x%x ;", ohci->ohci_dev->slot_name, readl (&ohci->regs->control)); +#endif /* Reset USB (needed by some controllers) */ writel (0, &ohci->regs->control); @@ -2309,7 +2611,9 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r) /* cardbus/... hardware gone before remove() */ } else if ((ints = readl (®s->intrstatus)) == ~(u32)0) { ohci->disabled++; +#ifndef CONFIG_BOARD_W90N745 err ("%s device removed!", ohci->ohci_dev->slot_name); +#endif return; /* interrupt for some other device? */ @@ -2321,8 +2625,10 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r) if (ints & OHCI_INTR_UE) { ohci->disabled++; +#ifndef CONFIG_BOARD_W90N745 err ("OHCI Unrecoverable Error, controller usb-%s disabled", ohci->ohci_dev->slot_name); +#endif // e.g. due to PCI Master/Target Abort #ifdef DEBUG @@ -2371,10 +2677,43 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r) writel (OHCI_INTR_MIE, ®s->intrenable); } +/*-------------alloc consistent not for pci-------------------------------------------*/ +#ifdef CONFIG_BOARD_W90N745 +void *ohci_alloc_consistent(size_t size, dma_addr_t *handle) +{ + void *__ret; + int __gfp = GFP_KERNEL; + + __ret = (void*)((unsigned long)consistent_alloc(__gfp, (size), (handle))|0x80000000); + return __ret; +} + +void ohci_free_consistent(size_t size, void *vaddr, + dma_addr_t dma_handle) +{ + consistent_free(vaddr, size, dma_handle); +} + +inline dma_addr_t +ohci_map_single(void *ptr, size_t size, int direction) +{ + consistent_sync(ptr, size, direction); + return virt_to_bus(ptr); +} + +inline void +ohci_unmap_single(dma_addr_t dma_addr, size_t size, int direction) +{ + /* nothing to do */ +} +#endif + + /*-------------------------------------------------------------------------*/ /* allocate OHCI */ +#ifndef CONFIG_BOARD_W90N745 static ohci_t * __devinit hc_alloc_ohci (struct pci_dev *dev, void * mem_base) { ohci_t * ohci; @@ -2419,7 +2758,51 @@ static ohci_t * __devinit hc_alloc_ohci (struct pci_dev *dev, void * mem_base) return ohci; } +#else +static ohci_t * __devinit hc_alloc_ohci (void * mem_base) +{ + ohci_t * ohci; + + ohci = (ohci_t *)kmalloc (sizeof *ohci, GFP_KERNEL); + if (!ohci) + return NULL; + + memset (ohci, 0, sizeof (ohci_t)); + + ohci->hcca = ohci_alloc_consistent(sizeof *ohci->hcca, + &ohci->hcca_dma); + + if (!ohci->hcca) { + kfree (ohci); + return NULL; + } + + memset (ohci->hcca, 0, sizeof (struct ohci_hcca)); + + ohci->disabled = 1; + ohci->sleeping = 0; + ohci->irq = -1; + ohci->regs = mem_base; + + INIT_LIST_HEAD (&ohci->ohci_hcd_list); + list_add (&ohci->ohci_hcd_list, &ohci_hcd_list); + + INIT_LIST_HEAD (&ohci->timeout_list); + + ohci->bus = usb_alloc_bus (&sohci_device_operations); + + + if (!ohci->bus) { + ohci_free_consistent (sizeof *ohci->hcca, + ohci->hcca, ohci->hcca_dma); + kfree (ohci); + return NULL; + } + ohci->bus->hcpriv = (void *) ohci; + return ohci; +} +#endif /*-------------------------------------------------------------------------*/ @@ -2427,7 +2810,9 @@ static ohci_t * __devinit hc_alloc_ohci (struct pci_dev *dev, void * mem_base) static void hc_release_ohci (ohci_t * ohci) { +#ifndef CONFIG_BOARD_W90N745 dbg ("USB HC release ohci usb-%s", ohci->ohci_dev->slot_name); +#endif /* disconnect all devices */ if (ohci->bus->root_hub) @@ -2440,7 +2825,9 @@ static void hc_release_ohci (ohci_t * ohci) free_irq (ohci->irq, ohci); ohci->irq = -1; } +#ifndef CONFIG_BOARD_W90N745 pci_set_drvdata(ohci->ohci_dev, NULL); +#endif if (ohci->bus) { if (ohci->bus->busnum != -1) usb_deregister_bus (ohci->bus); @@ -2456,8 +2843,13 @@ static void hc_release_ohci (ohci_t * ohci) /* unmap the IO address space */ iounmap (ohci->regs); +#ifndef CONFIG_BOARD_W90N745 pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca, ohci->hcca, ohci->hcca_dma); +#else + ohci_free_consistent(sizeof*ohci->hcca, + ohci->hcca, ohci->hcca_dma); +#endif kfree (ohci); } @@ -2468,6 +2860,7 @@ static void hc_release_ohci (ohci_t * ohci) static struct pci_driver ohci_pci_driver; +#ifndef CONFIG_BOARD_W90N745 static int __devinit hc_found_ohci (struct pci_dev *dev, int irq, void *mem_base, const struct pci_device_id *id) @@ -2542,7 +2935,69 @@ hc_found_ohci (struct pci_dev *dev, int irq, #endif return 0; } +#else +static int __devinit +hc_found_ohci (int irq, + void *mem_base, const struct pci_device_id *id) +{ + ohci_t * ohci; + //u8 latency, limit; + char buf[8], *bufp = buf; + int ret; + +#ifndef __sparc__ + sprintf(buf, "%d", irq); +#else + bufp = __irq_itoa(irq); +#endif + printk(": USB OHCI at membase 0x%lx, IRQ %s\n", + (unsigned long) mem_base, bufp); + + ohci = hc_alloc_ohci (mem_base); + if (!ohci) { + return -ENOMEM; + } + printk("hc_alloc_ohci\n"); + if ((ret = ohci_mem_init (ohci)) < 0) { + hc_release_ohci (ohci); + return ret; + } + ohci->flags = id->driver_data; + if (ohci->flags & OHCI_QUIRK_AMD756) + printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n"); + + printk("hc_reset\n"); + if (hc_reset (ohci) < 0) { + hc_release_ohci (ohci); + return -ENODEV; + } + //printk("writel\n"); + /* FIXME this is a second HC reset; why?? */ + writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control); + wait_ms (10); + + usb_register_bus (ohci->bus); + //CSR_WRITE (AIC_SCR9, 0x41); /* high-level sensitive, priority level 1 */ + if (request_irq (irq, hc_interrupt, SA_SHIRQ, + ohci_pci_driver.name, ohci) != 0) { + err ("request interrupt %s failed", bufp); + hc_release_ohci (ohci); + return -EBUSY; + } + ohci->irq = irq; + //printk("irq:%d\n",ohci->irq); + if (hc_start (ohci) < 0) { + err ("can't start usb"); + hc_release_ohci (ohci); + return -EBUSY; + } +#ifdef DEBUG + ohci_dump (ohci, 1); +#endif + return 0; +} +#endif /*-------------------------------------------------------------------------*/ #ifdef CONFIG_PM @@ -2589,6 +3044,7 @@ static void hc_restart (ohci_t *ohci) /* configured so that an OHCI device is always provided */ /* always called with process context; sleeping is OK */ +#ifndef CONFIG_BOARD_W90N745 static int __devinit ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) { @@ -2671,8 +3127,43 @@ ohci_pci_remove (struct pci_dev *dev) release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0)); pci_disable_device (dev); } +#else +static int __devinit +ohci_pci_probe (const struct pci_device_id *id) +{ + unsigned long mem_resource, mem_len; + void *mem_base; + int status; + + mem_resource = USB_HOST; + mem_len = 0x5C; + + mem_base = ioremap_nocache (mem_resource, mem_len); + + if (!mem_base) { + err("Error mapping OHCI memory"); + release_mem_region (mem_resource, mem_len); + return -EFAULT; + } + /* controller writes into our memory */ + /*dev->resource[0].start=mem_resource; + dev->resource[0].end=mem_resource + mem_len; + dev->irq = 9;*/ + + status = hc_found_ohci(INT_USBINT0, mem_base, id);//lsshi 2005-4-20 15:38 + if (status < 0) { + iounmap (mem_base); + release_mem_region (mem_resource, mem_len); + } + return status; +} +static void __devexit +ohci_pci_remove (struct pci_dev *dev) +{ +} +#endif #ifdef CONFIG_PM /*-------------------------------------------------------------------------*/ @@ -2917,14 +3408,22 @@ static struct pci_driver ohci_pci_driver = { static int __init ohci_hcd_init (void) { +#ifdef CONFIG_BOARD_W90N745 + printk("add a static ohci host controller device\n"); + ohci_pci_probe (ohci_pci_ids); + return 0; +#else return pci_module_init (&ohci_pci_driver); +#endif } /*-------------------------------------------------------------------------*/ static void __exit ohci_hcd_cleanup (void) { +#ifndef CONFIG_BOARD_W90N745 pci_unregister_driver (&ohci_pci_driver); +#endif } module_init (ohci_hcd_init); diff --git a/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.h b/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.h index 0f3329e..94b81ed 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.h +++ b/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.h @@ -6,8 +6,35 @@ * * usb-ohci.h */ - +/*define for no pci bus*/ +/* This defines the direction arg to the DMA mapping routines. */ +#define PCI_DMA_BIDIRECTIONAL 0 +#define PCI_DMA_TODEVICE 1 +#define PCI_DMA_FROMDEVICE 2 +#define PCI_DMA_NONE 3 + +#define PCI_ANY_ID (~0) +#define PCI_CLASS_SERIAL_USB 0x0c03 + +struct pci_device_id { + unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ + unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ + unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ + unsigned long driver_data; /* Data private to the driver */ +}; + +struct pci_driver { + struct list_head node; + char *name; + const struct pci_device_id *id_table; /* NULL if wants all devices */ + int (*probe) (const struct pci_device_id *id); /* New device inserted */ + void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ +}; + +/*-------------------end data struct from pci.h----------------------------------*/ + + static int cc_to_error[16] = { /* mapping of the OHCI CC status to error codes */ @@ -369,6 +396,16 @@ struct hash_list_t { * Note how the "proper" USB information is just * a subset of what the full implementation needs. (Linus) */ +struct ohci_pool { /* the pool */ + struct list_head page_list; + spinlock_t lock; + size_t blocks_per_page; + size_t size; + int flags; + size_t allocation; + char name [32]; + wait_queue_head_t waitq; +}; typedef struct ohci { @@ -402,11 +439,18 @@ typedef struct ohci { struct usb_device * dev[128]; struct virt_root_hub rh; +#ifndef CONFIG_BOARD_W90N745 /* PCI device handle, settings, ... */ struct pci_dev *ohci_dev; +#endif u8 pci_latency; +#ifndef CONFIG_BOARD_W90N745 struct pci_pool *td_cache; struct pci_pool *dev_cache; +#else + struct ohci_pool *td_cache; + struct ohci_pool *dev_cache; +#endif struct hash_list_t td_hash[TD_HASH_SIZE]; struct hash_list_t ed_hash[ED_HASH_SIZE]; @@ -424,6 +468,45 @@ struct ohci_device { // #define ohci_to_usb(ohci) ((ohci)->usb) #define usb_to_ohci(usb) ((struct ohci_device *)(usb)->hcpriv) +#ifdef CONFIG_BOARD_W90N745 +#define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) +#define POOL_POISON_BYTE 0xa7 + +struct pci_page { /* cacheable header for 'allocation' bytes */ + struct list_head page_list; + void *vaddr; + dma_addr_t dma; + unsigned long bitmap [0]; +}; + + +void *ohci_alloc_consistent(size_t size, dma_addr_t *handle); +void ohci_free_consistent(size_t size, void *vaddr, + dma_addr_t dma_handle); +inline dma_addr_t +ohci_map_single(void *ptr, size_t size, int direction); +inline void +ohci_unmap_single(dma_addr_t dma_addr, size_t size, int direction); + +struct ohci_pool * +ohci_pool_create (const char *name, + size_t size, size_t align, size_t allocation, int flags); +void ohci_pool_destroy (struct ohci_pool *pool); +void * +ohci_pool_alloc (struct ohci_pool *pool, int mem_flags, dma_addr_t *handle); +void +ohci_pool_free (struct ohci_pool *pool, void *vaddr, dma_addr_t dma); +static struct pci_page * +pool_alloc_page (struct ohci_pool *pool, int mem_flags); +static struct pci_page * +pool_alloc_page (struct ohci_pool *pool, int mem_flags); +static struct pci_page * +pool_find_page (struct ohci_pool *pool, dma_addr_t dma); +static inline int +is_page_busy (int blocks, unsigned long *bitmap); +static void +pool_free_page (struct ohci_pool *pool, struct pci_page *page); + /* hcd */ /* endpoint */ static int ep_link(ohci_t * ohci, ed_t * ed); @@ -438,6 +521,20 @@ static int rh_submit_urb(struct urb * urb); static int rh_unlink_urb(struct urb * urb); static int rh_init_int_timer(struct urb * urb); +/* hcd */ +/* endpoint */ +static int ep_link(ohci_t * ohci, ed_t * ed); +static int ep_unlink(ohci_t * ohci, ed_t * ed); +static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned int pipe, int interval, int load, int mem_flags); +static void ep_rm_ed(struct usb_device * usb_dev, ed_t * ed); +/* td */ +static void td_fill(ohci_t * ohci, unsigned int info, dma_addr_t data, int len, struct urb * urb, int index); +static void td_submit_urb(struct urb * urb); +/* root hub */ +static int rh_submit_urb(struct urb * urb); +static int rh_unlink_urb(struct urb * urb); +static int rh_init_int_timer(struct urb * urb); +#endif /*-------------------------------------------------------------------------*/ #define ALLOC_FLAGS (in_interrupt () || current->state != TASK_RUNNING ? GFP_ATOMIC : GFP_KERNEL) @@ -448,10 +545,12 @@ static int rh_init_int_timer(struct urb * urb); # define OHCI_MEM_FLAGS 0 #endif +#ifndef CONFIG_BOARD_W90N745 #ifndef CONFIG_PCI # error "usb-ohci currently requires PCI-based controllers" /* to support non-PCI OHCIs, you need custom bus/mem/... glue */ #endif +#endif /* Recover a TD/ED using its collision chain */ @@ -559,14 +658,22 @@ hash_free_td (struct ohci * hc, struct td * td) static int ohci_mem_init (struct ohci *ohci) { +#ifdef CONFIG_BOARD_W90N745 + ohci->td_cache = ohci_pool_create ("ohci_td", +#else ohci->td_cache = pci_pool_create ("ohci_td", ohci->ohci_dev, +#endif sizeof (struct td), 32 /* byte alignment */, 0 /* no page-crossing issues */, GFP_KERNEL | OHCI_MEM_FLAGS); if (!ohci->td_cache) return -ENOMEM; +#ifdef CONFIG_BOARD_W90N745 + ohci->dev_cache = ohci_pool_create ("ohci_dev", +#else ohci->dev_cache = pci_pool_create ("ohci_dev", ohci->ohci_dev, +#endif sizeof (struct ohci_device), 16 /* byte alignment */, 0 /* no page-crossing issues */, @@ -579,11 +686,19 @@ static int ohci_mem_init (struct ohci *ohci) static void ohci_mem_cleanup (struct ohci *ohci) { if (ohci->td_cache) { +#ifdef CONFIG_BOARD_W90N745 + ohci_pool_destroy (ohci->td_cache); +#else pci_pool_destroy (ohci->td_cache); +#endif ohci->td_cache = 0; } if (ohci->dev_cache) { +#ifdef CONFIG_BOARD_W90N745 + ohci_pool_destroy (ohci->td_cache); +#else pci_pool_destroy (ohci->dev_cache); +#endif ohci->dev_cache = 0; } } @@ -595,13 +710,21 @@ td_alloc (struct ohci *hc, int mem_flags) dma_addr_t dma; struct td *td; +#ifdef CONFIG_BOARD_W90N745 + td = ohci_pool_alloc (hc->td_cache, mem_flags, &dma); +#else td = pci_pool_alloc (hc->td_cache, mem_flags, &dma); +#endif if (td) { td->td_dma = dma; /* hash it for later reverse mapping */ if (!hash_add_td (hc, td)) { +#ifdef CONFIG_BOARD_W90N745 + ohci_pool_free (hc->td_cache, td, dma); +#else pci_pool_free (hc->td_cache, td, dma); +#endif return NULL; } } @@ -612,7 +735,11 @@ static inline void td_free (struct ohci *hc, struct td *td) { hash_free_td (hc, td); +#ifdef CONFIG_BOARD_W90N745 + ohci_pool_free (hc->td_cache, td, td->td_dma); +#else pci_pool_free (hc->td_cache, td, td->td_dma); +#endif } @@ -624,7 +751,11 @@ dev_alloc (struct ohci *hc, int mem_flags) struct ohci_device *dev; int i, offset; +#ifdef CONFIG_BOARD_W90N745 + dev = ohci_pool_alloc (hc->dev_cache, mem_flags, &dma); +#else dev = pci_pool_alloc (hc->dev_cache, mem_flags, &dma); +#endif if (dev) { memset (dev, 0, sizeof (*dev)); dev->dma = dma; @@ -639,6 +770,10 @@ dev_alloc (struct ohci *hc, int mem_flags) static inline void dev_free (struct ohci *hc, struct ohci_device *dev) { +#ifdef CONFIG_BOARD_W90N745 + ohci_pool_free (hc->dev_cache, dev, dev->dma); +#else pci_pool_free (hc->dev_cache, dev, dev->dma); +#endif } diff --git a/uClinux-2.4.20-uc1/drivers/usb/usb.c b/uClinux-2.4.20-uc1/drivers/usb/usb.c index 71920db..266b90b 100644 --- a/uClinux-2.4.20-uc1/drivers/usb/usb.c +++ b/uClinux-2.4.20-uc1/drivers/usb/usb.c @@ -38,7 +38,9 @@ #endif #include +#ifdef CONFIG_BOARD_W90N745 #include "hcd.h" +#endif static const int usb_bandwidth_option = #ifdef CONFIG_USB_BANDWIDTH @@ -945,6 +947,9 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus) if (!dev) return NULL; +#ifdef CONFIG_BOARD_W90N745 + dev = (struct usb_device *)((unsigned long)dev | 0x80000000); +#endif memset(dev, 0, sizeof(*dev)); usb_bus_get(bus); @@ -1032,6 +1037,9 @@ void usb_free_urb(struct urb* urb) /*-------------------------------------------------------------------*/ int usb_submit_urb(struct urb *urb) { +#ifdef CONFIG_BOARD_W90N745 + urb->transfer_buffer=(struct urb*)((unsigned long)(urb->transfer_buffer) | 0x80000000); +#endif if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op) return urb->dev->bus->op->submit_urb(urb); else @@ -1174,6 +1182,9 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u if (!dr) return -ENOMEM; +#ifdef CONFIG_BOARD_W90N745 + dr = (struct usb_ctrlrequest *)((unsigned long)dr | 0x80000000); +#endif dr->bRequestType = requesttype; dr->bRequest = request; dr->wValue = cpu_to_le16p(&value); @@ -1712,8 +1723,13 @@ void usb_disconnect(struct usb_device **pdev) *pdev = NULL; +#ifndef CONFIG_BOARD_W90N745 info("USB disconnect on device %s-%s address %d", dev->bus->bus_name, dev->devpath, dev->devnum); +#else + info("USB disconnect on device %s address %d", + dev->devpath, dev->devnum); +#endif if (dev->actconfig) { for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { @@ -1851,6 +1867,7 @@ int usb_get_status(struct usb_device *dev, int type, int target, void *data) int usb_get_protocol(struct usb_device *dev, int ifnum) { +#ifndef CONFIG_BOARD_W90N745 unsigned char type; int ret; @@ -1860,8 +1877,26 @@ int usb_get_protocol(struct usb_device *dev, int ifnum) return ret; return type; +#else + unsigned char *typeP = NULL; + int ret; + + typeP = kmalloc(sizeof(unsigned char), GFP_KERNEL); + if(!typeP) { + printk("usb_get_protocol kmalloc failed\n"); + return -ENOMEM; + } + typeP = (unsigned char *)((unsigned long)typeP | 0x80000000); + if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, ifnum, typeP, 1, HZ * GET_TIMEOUT)) < 0) + return ret; + + return *typeP; +#endif } + int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -1934,6 +1969,9 @@ int usb_clear_halt(struct usb_device *dev, int pipe) return -ENOMEM; } +#ifdef CONFIG_BOARD_W90N745 + buffer = (unsigned char *)((unsigned long)buffer | 0x80000000); +#endif result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp, buffer, sizeof(status), HZ * SET_TIMEOUT); @@ -2069,6 +2107,9 @@ int usb_get_configuration(struct usb_device *dev) err("unable to allocate memory for configuration descriptors"); return -ENOMEM; } +#ifdef CONFIG_BOARD_W90N745 + buffer = (unsigned char *)((unsigned long)buffer | 0x80000000); +#endif desc = (struct usb_config_descriptor *)buffer; for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) { @@ -2095,6 +2136,9 @@ int usb_get_configuration(struct usb_device *dev) goto err; } +#ifdef CONFIG_BOARD_W90N745 + bigbuffer = (unsigned char *)((unsigned long)bigbuffer | 0x80000000); +#endif /* Now that we know the length, get the whole thing */ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length); if (result < 0) { @@ -2146,6 +2190,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) if (!tbuf) return -ENOMEM; +#ifdef CONFIG_BOARD_W90N745 + tbuf = (unsigned char *)((unsigned long)tbuf | 0x80000000); +#endif /* get langid for strings if it's not yet known */ if (!dev->have_langid) { err = usb_get_string(dev, 0, 0, tbuf, 4); diff --git a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/Config.in b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/Config.in new file mode 100755 index 0000000..c0d0ad8 --- /dev/null +++ b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/Config.in @@ -0,0 +1,17 @@ +# +# Winbond W90N745 USB device configuration +# +mainmenu_option next_comment +comment 'Support for W90N745 USB Device 1.1' + +dep_bool 'Support W90N745 USB Device' CONFIG_WINBOND_USBD $CONFIG_USB + + if [ "$CONFIG_WINBOND_USBD" = "y" ]; then + choice ' usbd function support' \ + "VCOM CONFIG_WINBOND_USBD_VCOM\ + MASS CONFIG_WINBOND_USBD_MASS" MASS + fi + + +endmenu + diff --git a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile new file mode 100755 index 0000000..67c0de1 --- /dev/null +++ b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/Makefile @@ -0,0 +1,13 @@ +# + # Makefile for USB peripheral controller and gadget drivers + # for kbuild 2.4 + # + +O_TARGET := w90n745_usbd.o + +obj-$(CONFIG_WINBOND_USBD_MASS) += w90n745_mass.o +obj-$(CONFIG_WINBOND_USBD_VCOM) += w90n745_vcom.o + +#export-objs := w90n745_usb.o + +include $(TOPDIR)/Rules.make diff --git a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.c b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.c new file mode 100644 index 0000000..f7c5861 --- /dev/null +++ b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.c @@ -0,0 +1,1066 @@ +/**************************************************************************** + * * + * Copyright (c) 2005 - 2007 Winbond Electronics Corp. All rights reserved. * + * * + ****************************************************************************/ + +/**************************************************************************** + * + * FILENAME + * w90n745_mass.c + * + * VERSION + * 1.0 + * + * DESCRIPTION + * Winbond W90N745 USBD mass storage driver + * + * DATA STRUCTURES + * None + * + * FUNCTIONS + * None + * + * HISTORY + * 2005/08/01 Ver 1.0 + * 2005/08/16 Ver 1.1 + * + * AUTHOR + * PC34 Lsshi + * + * REMARK + * None + *************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "w90n745_mass.h" +//#define printk(fmt, ...) +#define DBGOUT(fmt, arg...) +//printk(fmt, ##arg) + +static const char driver_name [] = "Winbond W90N745 USB Device"; + +static int USB_Device[5] = { +0x01100112, 0x10000000, 0x96850416, 0x02010100, 0x00000100 }; + +static int USB_Config[10] = { +0x00270209, 0x40000101, 0x00040932, 0x05080300 , 0x05070050, 0x00400281, +0x02050701, 0x01004002, 0x03830507, 0x00010040 }; + +static int USB_Lang_Id_String[1] = { +0x04090304 }; + +static int USB_Vender_Id_String[4] = { +0x00570310, 0x004e0049, 0x004f0042, 0x0044004e }; + +static int USB_Device_Id_String[5] = { +0x00570312, 0x00390039, 0x00380036, 0x00430033, 0x00000046 }; + +static USB_INIT_T USBInit[6] = { + {0x00,0x000000e4}, //USB Control register + {0x08,0x000046f7}, //USB Interrupt Enable register + {0x14,0x00000030}, //USB Interface and string register + {0x38,0x00000000}, //USB SIE Status Register + {0x44,0x00000001}, //USB Configured Value register + {0x48,0x00000000} //USB Endpointer A Information register +}; + +static void USB_Init(wbusb_dev* dev); +static void USB_Irq_Init(wbusb_dev* dev); +static void SDRAM2USB_Bulk(wbusb_dev* dev,UINT8* buf ,UINT32 Tran_Size); +static void USB2SDRAM_Bulk(wbusb_dev* dev,UINT8* buf ,UINT32 Tran_Size); +static void SDRAM_USB_Transfer(wbusb_dev *dev,UINT8 epname,UINT8* buf ,UINT32 Tran_Size); +static UINT8 USB_Setup_Endpoint(wbusb_dev *dev,UINT8 epname,UINT8 epnum,UINT8 epdir,UINT8 eptype, + UINT8 epcon,UINT8 epinf,UINT16 epmaxps ); + + +void write_data(wbusb_dev *dev,UINT8* buf,UINT32 length); +void read_data(wbusb_dev *dev,UINT8* buf,UINT32 length); +int check_cbw(wbusb_dev *dev,void* cbw); + +static void start_write(wbusb_dev *dev,UINT8* buf,UINT32 length); +static void start_read(wbusb_dev *dev,UINT8* buf,UINT32 length); + +static void A_task_wake_up(wbusb_dev *dev);//write task + +static void B_task_block(wbusb_dev *dev);//idle and read task +static void B_task_wake_up(wbusb_dev *dev); + +#if 0 +static void dump_buffer(void *buf, int count) +{ + int i; + + printk("USB : "); + + for(i=0; i < count; i ++) + printk("%02x ", *((unsigned char *)buf + i)); + printk("\n"); + +} +#endif + +static void start_write(wbusb_dev *dev,UINT8* buf,UINT32 length) +{ + + DECLARE_WAITQUEUE(wait, current); + add_wait_queue(&dev->wusbd_wait_a, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + if(USB_READ(REG_USB_EPA_CTL)&0x00000004) + { + printk("device -> host DMA busy ...\n"); + goto quit; + } + + USB_WRITE(REG_USB_EPA_ADDR,(UINT32)buf);//Tell DMA the memory address + USB_WRITE(REG_USB_EPA_LENTH,length); + + USB_WRITE(REG_USB_EPA_CTL,USB_READ(REG_USB_EPA_CTL)|0x00000004);//The memory is ready for endpoint A to access + + schedule(); + +quit: + set_current_state(TASK_RUNNING); + remove_wait_queue(&dev->wusbd_wait_a, &wait); + + return ; +} + +static void start_read(wbusb_dev *dev,UINT8* buf,UINT32 length) +{ + + DECLARE_WAITQUEUE(wait, current); + add_wait_queue(&dev->wusbd_wait_b, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + if(USB_READ(REG_USB_EPB_CTL)&0x00000004) + { + printk("host -> device DMA busy ...\n"); + goto quit; + } + USB_WRITE(REG_USB_EPB_ADDR,(UINT32)buf);//Tell DMA the memory address + USB_WRITE(REG_USB_EPB_LENTH,length); + + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)|0x00000004);//The memory is ready for endpoint A to access + + schedule(); + +quit: + set_current_state(TASK_RUNNING); + remove_wait_queue(&dev->wusbd_wait_b, &wait); + + return ; +} + +#if 0 +static void A_task_block(wbusb_dev *dev) +{ + + + DECLARE_WAITQUEUE(wait, current); + add_wait_queue(&dev->wusbd_wait_a, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + schedule(); + + set_current_state(TASK_RUNNING); + remove_wait_queue(&dev->wusbd_wait_a, &wait); + + return ; +} + +#endif + +static void A_task_wake_up(wbusb_dev *dev) +{ + + wake_up_interruptible(&dev->wusbd_wait_a); + + return ; +} + + +static void B_task_block(wbusb_dev *dev) +{ + + + DECLARE_WAITQUEUE(wait, current); + add_wait_queue(&dev->wusbd_wait_b, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + schedule(); + + set_current_state(TASK_RUNNING); + remove_wait_queue(&dev->wusbd_wait_b, &wait); + + return ; +} + +static void B_task_wake_up(wbusb_dev *dev) +{ + + wake_up_interruptible(&dev->wusbd_wait_b); + + return ; +} + + +static UINT8 USB_Setup_Endpoint(wbusb_dev *dev,UINT8 epname,UINT8 epnum,UINT8 epdir,UINT8 eptype, + UINT8 epcon,UINT8 epinf,UINT16 epmaxps ) +{ + UINT32 tmp; + + if (epname == EP_A) + { + if ((epdir==Ep_In)&&(eptype==Ep_Bulk)&&(epcon==1)) + USB_WRITE(REG_USB_EPA_INFO,0x30000010); + else if ((epdir==Ep_In)&&(eptype==Ep_Int)&&(epcon==1)) + USB_WRITE(REG_USB_EPA_INFO,0x50000010); + else if ((epdir==Ep_In)&&(eptype==Ep_Iso)&&(epcon==1)) + USB_WRITE(REG_USB_EPA_INFO,0x70000010); + else if ((epdir==Ep_Out)&&(eptype==Ep_Bulk)&&(epcon==1)) + USB_WRITE(REG_USB_EPA_INFO,0x20000010); + else + return 0; + tmp = epinf; + tmp = tmp << 8; + USB_WRITE(REG_USB_EPA_INFO,(USB_READ(REG_USB_EPA_INFO)|tmp)); + tmp = epmaxps; + tmp = tmp << 16; + USB_WRITE(REG_USB_EPA_INFO,(USB_READ(REG_USB_EPA_INFO)|tmp)); + USB_WRITE(REG_USB_EPA_INFO,(USB_READ(REG_USB_EPA_INFO)|(epnum&0x0f))); + + dev->ep[EP_A].EP_Num = epnum; + dev->ep[EP_A].EP_Dir = epdir; + dev->ep[EP_A].EP_Type = eptype; + + USB_WRITE(REG_USB_EPA_CTL,0x00000001);//enable endpoint A + } + else if (epname == EP_B) + { + if ((epdir==Ep_In)&&(eptype==Ep_Bulk)&&(epcon==1)) + USB_WRITE(REG_USB_EPB_INFO,0x30000010); + else if ((epdir==Ep_In)&&(eptype==Ep_Int)&&(epcon==1)) + USB_WRITE(REG_USB_EPB_INFO,0x50000010); + else if ((epdir==Ep_In)&&(eptype==Ep_Iso)&&(epcon==1)) + USB_WRITE(REG_USB_EPB_INFO,0x70000010); + else if ((epdir==Ep_Out)&&(eptype==Ep_Bulk)&&(epcon==1)) + USB_WRITE(REG_USB_EPB_INFO,0x20000010); + else + return 0; + + tmp = epinf; + tmp = tmp << 8; + USB_WRITE(REG_USB_EPB_INFO,(USB_READ(REG_USB_EPB_INFO)|tmp)); + tmp = epmaxps; + tmp = tmp << 16; + USB_WRITE(REG_USB_EPB_INFO,(USB_READ(REG_USB_EPB_INFO)|tmp)); + USB_WRITE(REG_USB_EPB_INFO,(USB_READ(REG_USB_EPB_INFO)|(epnum&0x0f))); + + dev->ep[EP_B].EP_Num = epnum; + dev->ep[EP_B].EP_Dir = epdir; + dev->ep[EP_B].EP_Type = eptype; + USB_WRITE(REG_USB_EPB_CTL,0x00000001);//enable endpoint B + } + + + return 0; +} + +static void USB_Cmd_Parsing(wbusb_dev *dev) +{ + UINT32 cmd; + + cmd=USB_READ(USB_DEVICE+0x18); + dev->vcmd.Req_Type = cmd&0xff; + dev->vcmd.Req = (cmd>>8)&0xff; + + dev->vcmd.Value = (cmd>>16)&0xffff;//2,3 + cmd=USB_READ(USB_DEVICE+0x1c); + dev->vcmd.Index = cmd&0xffff;//4,5 + + dev->vcmd.Length = (cmd>>16)&0xffff;//6,7 + + if (dev->usb_enumstatus==GET_STR) + dev->vcmd.Index = 0; +} + +static void USB_All_Flag_Clear(wbusb_dev *dev) +{ + + DBGOUT("%s %d\n",__FUNCTION__,__LINE__); + dev->usb_enumstatus=0; +} + + + +static void Get_Dev_Dpr_In(wbusb_dev *dev) +{ + UINT8 i; + + DBGOUT("%s %d\n",__FUNCTION__,__LINE__); + + if (dev->vcmd.Length > 0) + { + if (dev->vcmd.Length <= 16) + { + USB_WRITE(REG_USB_CVCMD,dev->vcmd.Length); + } + else + { + dev->vcmd.Length = dev->vcmd.Length - 16; + USB_WRITE(REG_USB_CVCMD,0x10);//return data packet length is 16 + } + for (i = 0 ; i < USB_READ(REG_USB_CVCMD) ; i=i+4) + { + + switch(dev->usb_enumstatus) + { + + case GET_DEV: + USB_WRITE(REG_USB_IDATA0+i,USB_Device[dev->vcmd.Index]); + break; + + case GET_CFG: + USB_WRITE(REG_USB_IDATA0+i,USB_Config[dev->vcmd.Index]); + break; + + case GET_STR: + + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00000000) + { + USB_WRITE(REG_USB_IDATA0+i,USB_Lang_Id_String[dev->vcmd.Index]); + } + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00010000) + { + USB_WRITE(REG_USB_IDATA0+i,USB_Vender_Id_String[dev->vcmd.Index]); + } + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00020000) + { + USB_WRITE(REG_USB_IDATA0+i,USB_Device_Id_String[dev->vcmd.Index]); + } + + break; + + default: + printk("%s %d\n",__FUNCTION__,__LINE__); + break; + + }//switch end + dev->vcmd.Index = dev->vcmd.Index + 1; + }//for end + } + else + USB_WRITE(REG_USB_CVCMD,0x00); + +} + +static void USB_Init(wbusb_dev *dev) +{ + int j; + + for (j=0 ; j<6 ; j++) + { + USB_WRITE(USB_DEVICE+USBInit[j].dwAddr,USBInit[j].dwValue); + } + + dev->epnum=ENDPOINTS; + + for (j=0 ; jepnum ; j++) + { + dev->ep[j].EP_Num = 0xff; + dev->ep[j].EP_Dir = 0xff; + dev->ep[j].EP_Type = 0xff; + + } + + USB_Setup_Endpoint(dev,EP_A,1,Ep_In,Ep_Bulk,1,0,64);//Endpointer A bulkin //device -> host + USB_Setup_Endpoint(dev,EP_B,2,Ep_Out,Ep_Bulk,1,0,64);//Endpointer B bulkout //host -> device + + + USB_WRITE(REG_USB_EPA_IE,(USB_READ(REG_USB_EPA_IE)|0x00000008));//enable DMA interrupt + USB_WRITE(REG_USB_EPB_IE,(USB_READ(REG_USB_EPB_IE)|0x00000008));//enable DMA interrupt + + USB_WRITE(REG_USB_CTL,(USB_READ(REG_USB_CTL)|0x00000001));//D+ high + +} + + +static void USB_ISR_Reset_Start(void) +{ + DBGOUT("%s %d\n",__FUNCTION__,__LINE__); +} + +static void USB_ISR_Reset_End(wbusb_dev *dev) +{ + if ((USB_READ(REG_USB_EPA_CTL)&0x00000004)==0x00000004) + { + USB_WRITE(REG_USB_EPA_CTL,USB_READ(REG_USB_EPA_CTL)&0xfffffffb);//clear dma + USB_WRITE(REG_USB_EPA_CTL,USB_READ(REG_USB_EPA_CTL)|0x00000004); + } + if ((USB_READ(REG_USB_EPB_CTL)&0x00000004)==0x00000004) + { + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)&0xfffffffb);//clear dma + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)|0x00000004); + } +} + +static void USB_ISR_Suspend(wbusb_dev *dev) +{ + + + if(dev->usb_online) + { + USB_All_Flag_Clear(dev); + + USB_WRITE(REG_USB_EPA_CTL,USB_READ(REG_USB_EPA_CTL)&0xfffffffb);//clear dma busy bit + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)&0xfffffffb); + + + dev->usb_online=0; + + A_task_wake_up(dev); + B_task_wake_up(dev); + + printk("USB plugout !\n"); + } + +} + +static void USB_ISR_Resume(void) +{ + DBGOUT("%s %d\n",__FUNCTION__,__LINE__); +} + +static void USB_ISR_Dev_Des(wbusb_dev* dev) +{ + USB_All_Flag_Clear(dev); + + dev->usb_enumstatus=GET_DEV; + + if(!dev->usb_online){ + + dev->usb_online=1; + + A_task_wake_up(dev); + B_task_wake_up(dev); + + printk("USB plugin !\n"); + } + + if ((USB_READ(REG_USB_CTLS)&0x0000001f) == 0x00000008)//check usb control transfer status register + { + USB_Cmd_Parsing(dev);//read setup data + if (dev->vcmd.Length <=(USB_Device[0]&0x000000ff)) + USB_WRITE(REG_USB_ENG,0x00000008);//ACK + else + { + dev->vcmd.Length = (USB_Device[0]&0x000000ff); + USB_WRITE(REG_USB_ENG,0x00000008); + } + } + else { + USB_WRITE(REG_USB_ENG,0x00000002);//return stall + } + +} + +static void USB_ISR_Conf_Des(wbusb_dev* dev) +{ + + USB_All_Flag_Clear(dev); + dev->usb_enumstatus=GET_CFG; + + if ((USB_READ(REG_USB_CTLS)&0x0000001f) == 0x00000008) + { + USB_Cmd_Parsing(dev); + if (dev->vcmd.Length <= ((USB_Config[0]&0x00ff0000)>>16))//configure total length + USB_WRITE(REG_USB_ENG,0x00000008); + else + { + dev->vcmd.Length = ((USB_Config[0]&0x00ff0000)>>16); + USB_WRITE(REG_USB_ENG,0x00000008); + } + } + else { + USB_WRITE(REG_USB_ENG,0x00000002); + } +} + +static void USB_ISR_Str_Des(wbusb_dev* dev) +{ + + USB_All_Flag_Clear(dev); + dev->usb_enumstatus=GET_STR; + + if ((USB_READ(REG_USB_CTLS)&0x0000001f) == 0x00000008) + { + USB_Cmd_Parsing(dev); + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00000000) + { + if (dev->vcmd.Length <= (USB_Lang_Id_String[0]&0x000000ff)) + USB_WRITE(REG_USB_ENG,0x00000008); + else + { + dev->vcmd.Length = (USB_Lang_Id_String[0]&0x000000ff); + USB_WRITE(REG_USB_ENG,0x00000008); + } + } + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00010000) + { + if (dev->vcmd.Length <= (USB_Vender_Id_String[0]&0x000000ff)) + USB_WRITE(REG_USB_ENG,0x00000008); + else + { + dev->vcmd.Length = (USB_Vender_Id_String[0]&0x000000ff); + USB_WRITE(REG_USB_ENG,0x00000008); + } + } + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00020000) + { + if (dev->vcmd.Length <= (USB_Device_Id_String[0]&0x000000ff)) + USB_WRITE(REG_USB_ENG,0x00000008); + else + { + dev->vcmd.Length = (USB_Device_Id_String[0]&0x000000ff); + USB_WRITE(REG_USB_ENG,0x00000008); + } + } + } + else { + USB_WRITE(REG_USB_ENG,0x00000002); + } + +} + + +static void USB_ISR_CtlOut(void) +{ + + USB_WRITE(REG_USB_ENG,0x00000002); + USB_WRITE(REG_USB_ENG,0x00000008); + +} + + +void Outp_Byte(UINT32 addr,UINT8 value) +{ + UINT32 tmp1,tmp2; + + tmp1=USB_READ(addr&0xfffffffc); + tmp2=(UINT32)(value); + if (addr%4==0) + { + tmp1=tmp1&0xffffff00; + tmp1=tmp1|tmp2; + } + else if (addr%4==1) + { + tmp1=tmp1&0xffff00ff; + tmp1=tmp1|(tmp2<<8); + } + else if (addr%4==2) + { + tmp1=tmp1&0xff00ffff; + tmp1=tmp1|(tmp2<<16); + } + else if (addr%4==3) + { + tmp1=tmp1&0x00ffffff; + tmp1=tmp1|(tmp2<<24); + } + USB_WRITE((addr&0xfffffffc),tmp1); +} + +void Class_Data_In(void) +{ + + USB_WRITE(REG_USB_CVCMD,0x01); + Outp_Byte(REG_USB_IDATA0,0x00); +} + +void USB_ISR_Class_Cmd(wbusb_dev *dev) +{ + USB_All_Flag_Clear(dev); + + if(USB_READ(USB_DEVICE+0x18)==0xfea1) + { + dev->usb_enumstatus=CLA_CMD; + } + USB_WRITE(REG_USB_ENG,0x00000008); + +} + +static void USB_ISR_CtlIn(wbusb_dev *dev) +{ + + switch(dev->usb_enumstatus) + { + case CLA_CMD: + Class_Data_In(); + break; + + case GET_DEV: + case GET_CFG: + case GET_STR: + Get_Dev_Dpr_In(dev); + break; + + default: + USB_WRITE(REG_USB_ENG,0x00000002); + break; + + } + + USB_WRITE(REG_USB_ENG,0x00000001);//ACK for DATA-IN is Ready + +} + +static void USB_ISR_EpA_DMA_Complete(wbusb_dev *dev) +{ + + A_task_wake_up(dev); + + USB_WRITE(REG_USB_EPA_IC,0x00000008); + +} + + +static void USB_ISR_EpB_DMA_Complete(wbusb_dev *dev) +{ + if ((USB_READ(REG_USB_EPB_LENTH)-USB_READ(REG_USB_EPB_XFER))==0x0000001f) + dev->bulkonlycmd=1; + + B_task_wake_up(dev); + + USB_WRITE(REG_USB_EPB_IC,0x00000008); + + +} + + + +static void SDRAM_USB_Transfer(wbusb_dev *dev,UINT8 epname,UINT8* buf ,UINT32 Tran_Size) +{ + + if (epname == EP_A) + { + start_write(dev,buf,Tran_Size); + } + else if (epname == EP_B) + { + start_read(dev,buf,Tran_Size); + } + + return; + +} + +static void SDRAM2USB_Bulk(wbusb_dev *dev,UINT8* buf,UINT32 Tran_Size) +{ + + if ((dev->ep[EP_A].EP_Dir==Ep_In)&&(dev->ep[EP_A].EP_Type==Ep_Bulk)) + SDRAM_USB_Transfer(dev,EP_A,buf,Tran_Size); + else if ((dev->ep[EP_B].EP_Dir==Ep_In)&&(dev->ep[EP_B].EP_Type==Ep_Bulk)) + SDRAM_USB_Transfer(dev,EP_B,buf,Tran_Size); + + return; + +} + +static void USB2SDRAM_Bulk(wbusb_dev *dev, UINT8* buf ,UINT32 Tran_Size) +{ + + if ((dev->ep[EP_A].EP_Dir==Ep_Out)&&(dev->ep[EP_A].EP_Type==Ep_Bulk)) + SDRAM_USB_Transfer(dev,EP_A,buf,Tran_Size); + else if ((dev->ep[EP_B].EP_Dir==Ep_Out)&&(dev->ep[EP_B].EP_Type==Ep_Bulk)) + SDRAM_USB_Transfer(dev,EP_B,buf,Tran_Size); + + return; + +} + +void write_data(wbusb_dev *dev,UINT8* buf,UINT32 length) +{ + + if(!dev->usb_online) + return; + SDRAM2USB_Bulk(dev, buf,length); +} + +void read_data(wbusb_dev *dev,UINT8* buf,UINT32 length) +{ + + if(!dev->usb_online) + return; + USB2SDRAM_Bulk(dev,buf,length); +} + + +void paser_irq(int irq,wbusb_dev *dev) +{ + + switch(irq) + { + case RSTI: + USB_ISR_Reset_Start(); + break; + + case SUSI: + USB_ISR_Suspend(dev); + break; + + case RUMI: + USB_ISR_Resume(); + break; + + case GDEVI: + USB_ISR_Dev_Des(dev);//Get device Descriptor(); + break; + + case GCFGI: + USB_ISR_Conf_Des(dev); + break; + + case GSTRI: + USB_ISR_Str_Des(dev); + break; + + case CLAI: + USB_ISR_Class_Cmd(dev); + break; + + case CDOI: + USB_ISR_CtlOut(); + break; + + case CDII: + USB_ISR_CtlIn(dev); + break; + + case RST_ENDI: + USB_ISR_Reset_End(dev); + break; + + default: + //printk("irq: %d not handled !\n",irq); + break; + + } + + USB_WRITE(REG_USB_IC,(1<<(irq-1)));//clear irq bit + + return ; + +} + + +void wbusbd_irq(int irq, void *usbdev, struct pt_regs *r) +{ + UINT32 id,dmaid,i; + wbusb_dev *dev; + + dev=(wbusb_dev *)(usbdev); + + dmaid = USB_READ(REG_USB_EPA_IS); + + if (dmaid&0x00000008) + { + USB_ISR_EpA_DMA_Complete(dev); + } + + dmaid = USB_READ(REG_USB_EPB_IS); + + if (dmaid&0x00000008) + { + USB_ISR_EpB_DMA_Complete(dev); + } + + id = USB_READ(REG_USB_IS); + + for(i=0;i<16;i++) + { + if(id&(1<usb_online) + { + B_task_block(dev); + return -1; + } + + USB2SDRAM_Bulk(dev,cbw,0x1f); + + if (dev->bulkonlycmd) + { + dev->bulkonlycmd=0;//If DMA complete and got 31 bytes command, this will be "1" + + //dump_buffer(cbw, 0x1f); + + return 0; + } + + return -1; + +} + +static int wbusb_installirq(wbusb_dev *dev) +{ + + if (request_irq(INT_USBD, wbusbd_irq, SA_SHIRQ/*|SA_SAMPLE_RANDOM*/, + driver_name, dev) != 0) { + + return -EBUSY; + } + + Enable_Int(INT_USBD); + + return 0; + +} + + +static void USB_Irq_Init(wbusb_dev *dev) +{ + + init_waitqueue_head(&dev->wusbd_wait_a);//write + init_waitqueue_head(&dev->wusbd_wait_b);//read + + if(wbusb_installirq(dev)==0) + DBGOUT("install usb device irq ok\n"); + + USB_WRITE(REG_USB_EPA_IE,(USB_READ(REG_USB_EPA_IE)|0x00000008));//enable DMA interrupt + USB_WRITE(REG_USB_EPB_IE,(USB_READ(REG_USB_EPB_IE)|0x00000008));//enable DMA interrupt + + return ; +} + + wbusb_dev *the_controller=NULL; + + void* wbusb_register_driver(void) + { + if(the_controller) + return the_controller; + else + return NULL; + } + + +void wbusbd_probe(void) +{ + + wbusb_dev *dev = 0; +#if 0 + void *mem_base; + + mem_base = ioremap_nocache (USB_DEVICE, USB_OFFSET); + + if (!mem_base) { + DBGOUT("Error mapping USB Device 1.1 memory !!!"); + release_mem_region (USB_DEVICE, USB_OFFSET); + return ; + } +#endif + /* alloc, and start init */ + dev = kmalloc (sizeof *dev, GFP_KERNEL); + if (dev == NULL){ + DBGOUT("kmalloc error !\n"); + goto done; + } + + memset(dev, 0, sizeof *dev); + + dev->rw_data=write_data; + dev->rd_data=read_data; + dev->wait_cbw=check_cbw; + + USB_Init(dev); + + USB_Irq_Init(dev); + + the_controller=dev; + +done: + + return ; + +} + +/**************************************************************/ +/*ns24 zswan add it ,change the usb device apply to mass nand for hisense*/ +/*change the syscall to char device---20061023,by ns24 zswan***********/ +/**************************************************************/ +static char buffer[4096]; +static size_t usb_client_read(char *buf, size_t length) +{ + char *tmp = (char *)((UINT32)buffer | 0x80000000); + + //printk("Buffer : %08x, Count : %08x\n", buf, length); + if(length == 0) + return 0; + + if(length > 4096) + length = 4096; + + read_data(the_controller, tmp, length); + + if(copy_to_user(buf, tmp, length)) + return -EFAULT; + return length; +} + +static size_t usb_client_write(const char *buf, size_t length) +{ + char *tmp = (char *)((UINT32)buffer | 0x80000000); + + //printk("Buffer : %08x, Count : %08x\n", buf, length); + + if(length == 0) + return 0; + + if(length > 4096) + length = 4096; + + if(copy_from_user(tmp, buf, length)) + return -EFAULT; + + write_data(the_controller, tmp, length); + + return length; +} + +static int usb_client_get_cbw(char *buf) +{ + int retval = 0; + char *tmp = (char *)((UINT32)buffer | 0x80000000); + + retval = check_cbw(the_controller, tmp); + + if(copy_to_user(buf, tmp, 0x1f)) + return -EFAULT; + + return 0; +} + +static int wbusb_open(struct inode *ip, struct file *filp) +{ + return 0; +} + +static int wbusb_release(struct inode *ip, struct file *filp) +{ + return 0; +} + +static ssize_t wbusb_read(struct file *filp, char* buf, size_t count, loff_t *lp) +{ + return usb_client_read(buf, count); +} + +static ssize_t wbusb_write(struct file *filp, const char * buf, size_t count, loff_t *lp) +{ + return usb_client_write(buf, count); +} +static int wbusb_ioctl(struct inode *ip, struct file *filp, unsigned int cmd, unsigned long arg) +{ + int err = 0; + int retval = 0; + + if (_IOC_TYPE(cmd) != WBUSB_IOC_MAGIC) return -ENOTTY; + if (_IOC_NR(cmd) > WBUSB_IOC_MAXNR) return -ENOTTY; + + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); + + if (err) return -EFAULT; + + switch(cmd) { + case WBUSB_IOC_GETCBW: + retval = usb_client_get_cbw((char *)arg); + break; + default: + return -ENOTTY; + } + + return retval; + +} + +/**************************************************************/ +//struct cdev wbusb_cdev; +struct file_operations wbusb_fops = { + .owner = THIS_MODULE, + .open = wbusb_open, + .release = wbusb_release, + .read = wbusb_read, + .write = wbusb_write, + .ioctl = wbusb_ioctl, +}; + +static int __init wbusb_init (void) +{ + #ifdef CONFIG_BOARD_W90N745 + int result = -ENODEV; + DBGOUT("W90N745 USB Device Driver 1.0 ...\n"); + wbusbd_probe(); + result = register_chrdev(WBUSB_MAJOR, "usbclient", &wbusb_fops); + if( result < 0){ + unregister_chrdev(WBUSB_MAJOR, "usbclient"); + printk("can't get major %d\n", WBUSB_MAJOR); + return result; + } + + printk("Usb device driver by ns24 zswan designed successfully!\n"); + return 0; +#else + return 0; + +#endif +} + +static void wbusb_cleanup (void) +{ + DBGOUT("%s %d\n",__FUNCTION__,__LINE__); + unregister_chrdev(WBUSB_MAJOR, "usbclient"); + //return ; + +} + +module_init(wbusb_init); +module_exit(wbusb_cleanup); diff --git a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.h b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.h new file mode 100644 index 0000000..42d0527 --- /dev/null +++ b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_mass.h @@ -0,0 +1,250 @@ +/**************************************************************************** + * * + * Copyright (c) 2005 - 2007 Winbond Electronics Corp. All rights reserved. * + * * + ****************************************************************************/ + +/**************************************************************************** + * + * FILENAME + * w90n745_mass.h + * + * VERSION + * 1.0 + * + * DESCRIPTION + * + * + * DATA STRUCTURES + * None + * + * FUNCTIONS + * None + * + * HISTORY + * 2005/08/01 Ver 1.0 Created by PC34 Lsshi + * + * + * REMARK + * None + *************************************************************************/ + +#ifndef __W90N745_MASS_H +#define __W90N745_MASS_H +//types + +#define CONST const + +#define FALSE 0 +#define TRUE 1 + +typedef void VOID; +typedef void * PVOID; + +typedef char BOOL; +typedef char * PBOOL; + +typedef char INT8; +typedef char CHAR; +typedef char * PINT8; +typedef char * PCHAR; +typedef unsigned char UINT8; +typedef unsigned char UCHAR; +typedef unsigned char * PUINT8; +typedef unsigned char * PUCHAR; +typedef char * PSTR; +typedef const char * PCSTR; + +typedef short SHORT; +typedef short * PSHORT; +typedef unsigned short USHORT; +typedef unsigned short * PUSHORT; + +typedef short INT16; +typedef short * PINT16; +typedef unsigned short UINT16; +typedef unsigned short * PUINT16; + +typedef int INT; +typedef int * PINT; +typedef unsigned int UINT; +typedef unsigned int * PUINT; + +typedef int INT32; +typedef int * PINT32; +typedef unsigned int UINT32; +typedef unsigned int * PUINT32; + + +typedef float FLOAT; +typedef float * PFLOAT; + +typedef double DOUBLE; +typedef double * PDOUBLE; + +typedef int SIZE_T; + +typedef unsigned char REG8; +typedef unsigned short REG16; +typedef unsigned int REG32; + + +#define outpb(port,value) (*((UINT8 volatile *) (port))=value) +#define inpb(port) (*((UINT8 volatile *) (port))) +#define outphw(port,value) (*((UINT16 volatile *) (port))=value) +#define inphw(port) (*((UINT16 volatile *) (port))) +#define outpw(port,value) (*((UINT32 volatile *) (port))=value) +#define inpw(port) (*((UINT32 volatile *) (port))) + + +#define USB_WRITE(addr,data) (*((unsigned int volatile *)(addr))=data) +#define USB_READ(addr) (*((unsigned int volatile *)(addr))) +/// +#define ENDPOINTS 2 //bulkin/out +#define USB_OFFSET 0xB4 + +#define RSTI 1 +#define SUSI 2 +#define RUMI 3 +#define GDEVI 5 +#define GCFGI 6 +#define GSTRI 7 +#define CLAI 8 +#define CDOI 10 +#define CDII 11 +#define RST_ENDI 15 + +/********************************************************************************************************** + * + * USB Device Control Registers + * + **********************************************************************************************************/ +#define REG_USB_CTL (USB_DEVICE+0x00) /* USB control register */ +#define REG_USB_CVCMD (USB_DEVICE+0x04) /* USB class or vendor command register */ +#define REG_USB_IE (USB_DEVICE+0x08) /* USB interrupt enable register */ +#define REG_USB_IS (USB_DEVICE+0x0c) /* USB interrupt status register */ +#define REG_USB_IC (USB_DEVICE+0x10) /* USB interrupt status clear register */ +#define REG_USB_IFSTR (USB_DEVICE+0x14) /* USB interface and string register */ +#define REG_USB_ODATA0 (USB_DEVICE+0x18) /* USB control transfer-out port 0 register */ +#define REG_USB_ODATA1 (USB_DEVICE+0x1C) /* USB control transfer-out port 1 register */ +#define REG_USB_ODATA2 (USB_DEVICE+0x20) /* USB control transfer-out port 2 register */ +#define REG_USB_ODATA3 (USB_DEVICE+0x24) /* USB control transfer-out port 3 register */ +#define REG_USB_IDATA0 (USB_DEVICE+0x28) /* USB control transfer-in data port 0 register */ +#define REG_USB_IDATA1 (USB_DEVICE+0x2C) /* USB control transfer-in data port 1 register */ +#define REG_USB_IDATA2 (USB_DEVICE+0x30) /* USB control transfer-in data port 2 register */ +#define REG_USB_IDATA3 (USB_DEVICE+0x34) /* USB control transfer-in data port 2 register */ +#define REG_USB_SIE (USB_DEVICE+0x38) /* USB SIE status Register */ +#define REG_USB_ENG (USB_DEVICE+0x3c) /* USB Engine Register */ +#define REG_USB_CTLS (USB_DEVICE+0x40) /* USB control transfer status register */ +#define REG_USB_CONFD (USB_DEVICE+0x44) /* USB Configured Value register */ +#define REG_USB_EPA_INFO (USB_DEVICE+0x48) /* USB endpoint A information register */ +#define REG_USB_EPA_CTL (USB_DEVICE+0x4c) /* USB endpoint A control register */ +#define REG_USB_EPA_IE (USB_DEVICE+0x50) /* USB endpoint A Interrupt Enable register */ +#define REG_USB_EPA_IC (USB_DEVICE+0x54) /* USB endpoint A interrupt clear register */ +#define REG_USB_EPA_IS (USB_DEVICE+0x58) /* USB endpoint A interrupt status register */ +#define REG_USB_EPA_ADDR (USB_DEVICE+0x5c) /* USB endpoint A address register */ +#define REG_USB_EPA_LENTH (USB_DEVICE+0x60) /* USB endpoint A transfer length register */ +#define REG_USB_EPB_INFO (USB_DEVICE+0x64) /* USB endpoint B information register */ +#define REG_USB_EPB_CTL (USB_DEVICE+0x68) /* USB endpoint B control register */ +#define REG_USB_EPB_IE (USB_DEVICE+0x6c) /* USB endpoint B Interrupt Enable register */ +#define REG_USB_EPB_IC (USB_DEVICE+0x70) /* USB endpoint B interrupt clear register */ +#define REG_USB_EPB_IS (USB_DEVICE+0x74) /* USB endpoint B interrupt status register */ +#define REG_USB_EPB_ADDR (USB_DEVICE+0x78) /* USB endpoint B address register */ +#define REG_USB_EPB_LENTH (USB_DEVICE+0x7c) /* USB endpoint B transfer length register */ +#define REG_USB_EPC_INFO (USB_DEVICE+0x80) /* USB endpoint C information register */ +#define REG_USB_EPC_CTL (USB_DEVICE+0x84) /* USB endpoint C control register */ +#define REG_USB_EPC_IE (USB_DEVICE+0x88) /* USB endpoint C Interrupt Enable register */ +#define REG_USB_EPC_IC (USB_DEVICE+0x8c) /* USB endpoint C interrupt clear register */ +#define REG_USB_EPC_IS (USB_DEVICE+0x90) /* USB endpoint C interrupt status register */ +#define REG_USB_EPC_ADDR (USB_DEVICE+0x94) /* USB endpoint C address register */ +#define REG_USB_EPC_LENTH (USB_DEVICE+0x98) /* USB endpoint C transfer length register */ +#define REG_USB_EPA_XFER (USB_DEVICE+0x9c) /* USB endpoint A remain transfer length register */ +#define REG_USB_EPA_PKT (USB_DEVICE+0xa0) /* USB endpoint A remain packet length register */ +#define REG_USB_EPB_XFER (USB_DEVICE+0xa4) /* USB endpoint B remain transfer length register */ +#define REG_USB_EPB_PKT (USB_DEVICE+0xa8) /* USB endpoint B remain packet length register */ +#define REG_USB_EPC_XFER (USB_DEVICE+0xac) /* USB endpoint C remain transfer length register */ +#define REG_USB_EPC_PKT (USB_DEVICE+0xb0) /* USB endpoint C remain packet length register */ + +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define SizePerSector 512 + +#define RAMDISK + + +//extern UINT8 volatile USB_Power_Flag; // 0: bus power de-attached; 1: attached + +//bulk set +//extern UINT32 volatile Bulk_set_length; +//extern UINT8 volatile bulksetflag; +/* Define Endpoint feature */ +#define Ep_In 0x01 +#define Ep_Out 0x00 +#define Ep_Bulk 0x01 +#define Ep_Int 0x02 +#define Ep_Iso 0x03 + +#define EP_A 0x00 +#define EP_B 0x01 + + + +typedef struct +{ + UINT32 dwAddr; + UINT32 dwValue; + +}USB_INIT_T; + +typedef struct +{ + UINT8 Req_Type; + UINT8 Req; + UINT16 Value; + UINT16 Index; + UINT16 Length; +}USB_Vender_Cmd_Format_T __attribute__ ((aligned (4))); // each field of vendor command + +typedef struct { + UINT8 EP_Num; + UINT8 EP_Dir; + UINT8 EP_Type; + UINT8 p; +} USB_EP_Inf_T __attribute__ ((aligned (4))); + +///// + +//WBUSB Structs + typedef struct _wbusb_dev { + + UINT8 epnum; + UINT8 usb_online; + UINT8 bulkonlycmd; + + wait_queue_head_t wusbd_wait_a,wusbd_wait_b; + + USB_EP_Inf_T ep[2]; + USB_Vender_Cmd_Format_T vcmd ; + + enum{ + GET_DEV=1, + GET_CFG, + GET_STR, + CLA_CMD + }usb_enumstatus; + + int (*wait_cbw)(struct _wbusb_dev *dev,void* cbw); + void (*rw_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length); + void (*rd_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length); + +}wbusb_dev __attribute__ ((aligned (4))); +///// +#define WBUSB_MAJOR 250 +#define WBUSB_IOC_MAXNR 3 +#define WBUSB_IOC_MAGIC 'u' +#define WBUSB_IOC_GETCBW _IOR(WBUSB_IOC_MAGIC, 0, char *) +#define WBUSB_GETVLEN _IOR(WBUSB_IOC_MAGIC, 1, unsigned long *) +#define WBUSB_REPLUG _IOR(WBUSB_IOC_MAGIC, 2, char *) +void* wbusb_register_driver(void); + +#endif /* __WBUSB_H */ diff --git a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.c b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.c new file mode 100644 index 0000000..9fecdc3 --- /dev/null +++ b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.c @@ -0,0 +1,1477 @@ +/**************************************************************************** + * * + * Copyright (c) 2005 - 2007 Winbond Electronics Corp. All rights reserved. * + * * + ****************************************************************************/ + +/**************************************************************************** + * + * FILENAME + * w90n745_vcom.c + * + * VERSION + * 1.0 + * + * DESCRIPTION + * Winbond W90N745 USBD VCOM driver + * + * DATA STRUCTURES + * None + * + * FUNCTIONS + * None + * + * HISTORY + * 2005/08/01 Ver 1.0 + * 2005/08/16 Ver 1.1 + * + * AUTHOR + * PC34 Lsshi + * + * REMARK + * None + *************************************************************************/ + +#include +#include +#include +#include +#include +#include +//#include +#include + +#include +//#include + +#include +#include +#include +#include + +#include "w90n745_vcom.h" +//#define printk(fmt, ...) +#define DBGOUT(fmt, arg...) //printk(fmt, ##arg) + +//#define printk(fmt...) + +/* Configure USBD as VCOM in the beginning */ +#define USBDVCOM /* 2007.11.29 add, PT23 HHWu */ + +//#define SD_DEBUG +//#define SD_DEBUG_PRINT_LINE +#define SD_DEBUG_ENABLE_ENTER_LEAVE +//#define SD_DEBUG_ENABLE_MSG +//#define SD_DEBUG_ENABLE_MSG2 + +#ifdef SD_DEBUG +#define PDEBUG(fmt, arg...) printk(fmt, ##arg) +#else +#define PDEBUG(fmt, arg...) +#endif + +#ifdef SD_DEBUG_PRINT_LINE +#define PRN_LINE() PDEBUG("[%-20s] : %d\n", __FUNCTION__, __LINE__) +#else +#define PRN_LINE() +#endif + +#ifdef SD_DEBUG_ENABLE_ENTER_LEAVE +#define ENTER() PDEBUG("[%-20s] : Enter...\n", __FUNCTION__) +#define LEAVE() PDEBUG("[%-20s] : Leave...\n", __FUNCTION__) +#else +#define ENTER() +#define LEAVE() +#endif + +#ifdef SD_DEBUG_ENABLE_MSG +#define MSG(msg) PDEBUG("[%-20s] : %s\n", __FUNCTION__, msg) +#else +#define MSG(msg) +#endif + +#ifdef SD_DEBUG_ENABLE_MSG2 +#define MSG2(fmt, arg...) PDEBUG("[%-20s] : "fmt, __FUNCTION__, ##arg) +#define PRNBUF(buf, count) {int i;MSG2("CID Data: ");for(i=0;iwusbd_wait_a, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + if(USB_READ(REG_USB_EPA_CTL)&0x00000004) + { + printk("device -> host DMA busy ...\n"); + goto quit; + } + + USB_WRITE(REG_USB_EPA_ADDR,(UINT32)buf);//Tell DMA the memory address + USB_WRITE(REG_USB_EPA_LENTH,length); + + USB_WRITE(REG_USB_EPA_CTL,USB_READ(REG_USB_EPA_CTL)|0x00000004);//The memory is ready for endpoint A to access + + schedule(); + +quit: + set_current_state(TASK_RUNNING); + remove_wait_queue(&dev->wusbd_wait_a, &wait); + + return ; +} + +static void start_read(wbusb_dev *dev,UINT8* buf,UINT32 length) +{ + + DECLARE_WAITQUEUE(wait, current); + add_wait_queue(&dev->wusbd_wait_b, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + if(USB_READ(REG_USB_EPB_CTL)&0x00000004) + { + printk("host -> device DMA busy ...\n"); + goto quit; + } + USB_WRITE(REG_USB_EPB_ADDR,(UINT32)buf);//Tell DMA the memory address + USB_WRITE(REG_USB_EPB_LENTH,length); + + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)|0x00000004);//The memory is ready for endpoint A to access + + schedule(); + +quit: + set_current_state(TASK_RUNNING); + remove_wait_queue(&dev->wusbd_wait_b, &wait); + + return ; +} + +#if 0 +static void A_task_block(wbusb_dev *dev) +{ + + + DECLARE_WAITQUEUE(wait, current); + add_wait_queue(&dev->wusbd_wait_a, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + schedule(); + + set_current_state(TASK_RUNNING); + remove_wait_queue(&dev->wusbd_wait_a, &wait); + + return ; +} + +#endif + +static void A_task_wake_up(wbusb_dev *dev) +{ + + wake_up_interruptible(&dev->wusbd_wait_a); + + return ; +} + + +static void B_task_block(wbusb_dev *dev) +{ + + + DECLARE_WAITQUEUE(wait, current); + add_wait_queue(&dev->wusbd_wait_b, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + schedule(); + + set_current_state(TASK_RUNNING); + remove_wait_queue(&dev->wusbd_wait_b, &wait); + + return ; +} + +static void B_task_wake_up(wbusb_dev *dev) +{ + + wake_up_interruptible(&dev->wusbd_wait_b); + + return ; +} + + +static void C_task_block(wbusb_dev *dev) +{ + + ENTER(); +#if 0 + DECLARE_WAITQUEUE(wait, current); + add_wait_queue(&dev->wusbd_wait_c, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + schedule(); + + set_current_state(TASK_RUNNING); + remove_wait_queue(&dev->wusbd_wait_c, &wait); + +#else + + bCBlockFlag = 0; + wait_event_interruptible(dev->wusbd_wait_c, bCBlockFlag != 0); +#endif + + LEAVE(); + + return ; +} + +static void C_task_wake_up(wbusb_dev *dev) +{ + ENTER(); + +#if 1 + bCBlockFlag = 1; + wake_up_interruptible(&dev->wusbd_wait_c); + + //printk("bCBlockFlag:%x\n",bCBlockFlag); + +#endif + LEAVE(); + + return ; +} + + +static UINT8 USB_Setup_Endpoint(wbusb_dev *dev,UINT8 epname,UINT8 epnum,UINT8 epdir,UINT8 eptype, + UINT8 epcon,UINT8 epinf,UINT16 epmaxps ) +{ + UINT32 tmp; + + if (epname == EP_A) + { + if ((epdir==Ep_In)&&(eptype==Ep_Bulk)&&(epcon==1)) + USB_WRITE(REG_USB_EPA_INFO,0x30000010); + else if ((epdir==Ep_In)&&(eptype==Ep_Int)&&(epcon==1)) + USB_WRITE(REG_USB_EPA_INFO,0x50000010); + else if ((epdir==Ep_In)&&(eptype==Ep_Iso)&&(epcon==1)) + USB_WRITE(REG_USB_EPA_INFO,0x70000010); + else if ((epdir==Ep_Out)&&(eptype==Ep_Bulk)&&(epcon==1)) + USB_WRITE(REG_USB_EPA_INFO,0x20000010); + else + return 0; + tmp = epinf; + tmp = tmp << 8; + USB_WRITE(REG_USB_EPA_INFO,(USB_READ(REG_USB_EPA_INFO)|tmp)); + tmp = epmaxps; + tmp = tmp << 16; + USB_WRITE(REG_USB_EPA_INFO,(USB_READ(REG_USB_EPA_INFO)|tmp)); + USB_WRITE(REG_USB_EPA_INFO,(USB_READ(REG_USB_EPA_INFO)|(epnum&0x0f))); + + dev->ep[EP_A].EP_Num = epnum; + dev->ep[EP_A].EP_Dir = epdir; + dev->ep[EP_A].EP_Type = eptype; + + USB_WRITE(REG_USB_EPA_CTL,0x00000001);//enable endpoint A + } + else if (epname == EP_B) + { + if ((epdir==Ep_In)&&(eptype==Ep_Bulk)&&(epcon==1)) + USB_WRITE(REG_USB_EPB_INFO,0x30000010); + else if ((epdir==Ep_In)&&(eptype==Ep_Int)&&(epcon==1)) + USB_WRITE(REG_USB_EPB_INFO,0x50000010); + else if ((epdir==Ep_In)&&(eptype==Ep_Iso)&&(epcon==1)) + USB_WRITE(REG_USB_EPB_INFO,0x70000010); + else if ((epdir==Ep_Out)&&(eptype==Ep_Bulk)&&(epcon==1)) + USB_WRITE(REG_USB_EPB_INFO,0x20000010); + else + return 0; + + tmp = epinf; + tmp = tmp << 8; + USB_WRITE(REG_USB_EPB_INFO,(USB_READ(REG_USB_EPB_INFO)|tmp)); + tmp = epmaxps; + tmp = tmp << 16; + USB_WRITE(REG_USB_EPB_INFO,(USB_READ(REG_USB_EPB_INFO)|tmp)); + USB_WRITE(REG_USB_EPB_INFO,(USB_READ(REG_USB_EPB_INFO)|(epnum&0x0f))); + + dev->ep[EP_B].EP_Num = epnum; + dev->ep[EP_B].EP_Dir = epdir; + dev->ep[EP_B].EP_Type = eptype; + USB_WRITE(REG_USB_EPB_CTL,0x00000001);//enable endpoint B + } + + + return 0; +} + +static void USB_Cmd_Parsing(wbusb_dev *dev) +{ + UINT32 cmd; + + cmd=USB_READ(W90N745_USB_DEVICE+0x18); + dev->vcmd.Req_Type = cmd&0xff; + dev->vcmd.Req = (cmd>>8)&0xff; + + dev->vcmd.Value = (cmd>>16)&0xffff;//2,3 + cmd=USB_READ(W90N745_USB_DEVICE+0x1c); + dev->vcmd.Index = cmd&0xffff;//4,5 + + dev->vcmd.Length = (cmd>>16)&0xffff;//6,7 + + if (dev->usb_enumstatus==GET_STR) + dev->vcmd.Index = 0; +} + +static void USB_All_Flag_Clear(wbusb_dev *dev) +{ + + DBGOUT("%s %d\n",__FUNCTION__,__LINE__); + dev->usb_enumstatus=0; +} + + + +static void Get_Dev_Dpr_In(wbusb_dev *dev) +{ + UINT8 i; + + DBGOUT("%s %d\n",__FUNCTION__,__LINE__); + + if (dev->vcmd.Length > 0) + { + if (dev->vcmd.Length <= 16) + { + USB_WRITE(REG_USB_CVCMD,dev->vcmd.Length); + } + else + { + dev->vcmd.Length = dev->vcmd.Length - 16; + USB_WRITE(REG_USB_CVCMD,0x10);//return data packet length is 16 + } + for (i = 0 ; i < USB_READ(REG_USB_CVCMD) ; i=i+4) + { + + switch(dev->usb_enumstatus) + { + + case GET_DEV: + USB_WRITE(REG_USB_IDATA0+i,USB_Device[dev->vcmd.Index]); + break; + + case GET_CFG: + USB_WRITE(REG_USB_IDATA0+i,USB_Config[dev->vcmd.Index]); + break; + + case GET_STR: + + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00000000) + { + USB_WRITE(REG_USB_IDATA0+i,USB_Lang_Id_String[dev->vcmd.Index]); + } + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00010000) + { + USB_WRITE(REG_USB_IDATA0+i,USB_Vender_Id_String[dev->vcmd.Index]); + } + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00020000) + { + USB_WRITE(REG_USB_IDATA0+i,USB_Device_Id_String[dev->vcmd.Index]); + } + + break; + + default: + printk("%s %d\n",__FUNCTION__,__LINE__); + break; + + }//switch end + dev->vcmd.Index = dev->vcmd.Index + 1; + }//for end + } + else + USB_WRITE(REG_USB_CVCMD,0x00); + +} + +int Disable_USB(wbusb_dev *dev) +{ + ENTER(); + + USB_WRITE(REG_USB_CTL,0x0);//disable usb enginee + Disable_Int(INT_USBD); + free_irq(INT_USBD,dev); + + __usleep(1000); + + LEAVE(); + + return 0; + +} + + + +int Enable_USB(wbusb_dev *dev) +{ + ENTER(); + + USB_Init(dev); + USB_Irq_Init(dev); + __usleep(1000); + + LEAVE(); + + return 0; +} + +void Reset_USB(wbusb_dev *dev) +{ + ENTER(); + + printk("Disable USB now ...\n"); + Disable_USB(dev); + __usleep(1000000); + printk("Enable USB now ...\n"); + Enable_USB(dev); + + LEAVE(); +} + +static void USB_Init(wbusb_dev *dev) +{ + int j; + + ENTER(); + + for (j=0 ; j<6 ; j++) + { + USB_WRITE(W90N745_USB_DEVICE+USBInit[j].dwAddr,USBInit[j].dwValue); + } + + dev->epnum=ENDPOINTS; + + for (j=0 ; jepnum ; j++) + { + dev->ep[j].EP_Num = 0xff; + dev->ep[j].EP_Dir = 0xff; + dev->ep[j].EP_Type = 0xff; + + } + + dev->bulk_len=0; + + USB_Setup_Endpoint(dev,EP_A,1,Ep_In,Ep_Bulk,1,0,64);//Endpointer A bulkin //device -> host + USB_Setup_Endpoint(dev,EP_B,2,Ep_Out,Ep_Bulk,1,0,64);//Endpointer B bulkout //host -> device + + + USB_WRITE(REG_USB_EPA_IE,(USB_READ(REG_USB_EPA_IE)|0x00000008));//enable DMA interrupt + USB_WRITE(REG_USB_EPB_IE,(USB_READ(REG_USB_EPB_IE)|0x00000008));//enable DMA interrupt + + USB_WRITE(REG_USB_CTL,(USB_READ(REG_USB_CTL)|0x00000001));//D+ high + + LEAVE(); + +} + + +static void USB_ISR_Reset_Start(void) +{ + DBGOUT("%s %d\n",__FUNCTION__,__LINE__); +} + +static void USB_ISR_Reset_End(wbusb_dev *dev) +{ + if ((USB_READ(REG_USB_EPA_CTL)&0x00000004)==0x00000004) + { + USB_WRITE(REG_USB_EPA_CTL,USB_READ(REG_USB_EPA_CTL)&0xfffffffb);//clear dma + USB_WRITE(REG_USB_EPA_CTL,USB_READ(REG_USB_EPA_CTL)|0x00000004); + } + if ((USB_READ(REG_USB_EPB_CTL)&0x00000004)==0x00000004) + { + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)&0xfffffffb);//clear dma + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)|0x00000004); + } +} + +static void USB_ISR_Suspend(wbusb_dev *dev) +{ + + if(dev->usb_online) + { + USB_All_Flag_Clear(dev); + + USB_WRITE(REG_USB_EPA_CTL,USB_READ(REG_USB_EPA_CTL)&0xfffffffb);//clear dma busy bit + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)&0xfffffffb); + + + dev->usb_online=0; + + A_task_wake_up(dev); + B_task_wake_up(dev); + + printk("USB plugout !\n"); + } + +} + +static void USB_ISR_Resume(void) +{ + DBGOUT("%s %d\n",__FUNCTION__,__LINE__); +} + + +void USB_ISR_Vendor_Cmd(wbusb_dev* dev) +{ + + USB_All_Flag_Clear(dev); + + + + if ((USB_READ(REG_USB_CTLS)&0x0000001f) == 0x00000008) + { + USB_Cmd_Parsing(dev); + + if (dev->vcmd.Req_Type == 0x40) + { + dev->bulk_len=0; + dev->usb_enumstatus=VEN_CMDOUT; + + + + if (dev->vcmd.Req == 0xA0) + { + if (dev->vcmd.Value == 0x12) + { + //VCOM PC driver Vendor CMD + + dev->bulk_len=dev->vcmd.Index; + USB_WRITE(REG_USB_IE,USB_READ(REG_USB_IE)&0xfffffeff);//disable vender interrupt enable + C_task_wake_up(dev); + } + else if (dev->vcmd.Value == 0x13) + { + + USB_WRITE(REG_USB_IE,USB_READ(REG_USB_IE)|0x00000100);//enable vender interrupt enable + + if ((USB_READ(REG_USB_EPB_CTL)&0x00000004)==0x00000004) + { + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)|0x00000002);//reset + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)&0xfffffffd); + } + if ((USB_READ(REG_USB_EPB_CTL)&0x00000004)==0x00000004) + USB_WRITE(REG_USB_EPB_CTL,USB_READ(REG_USB_EPB_CTL)&0xfffffffb);//clear ready + } + } + } + else if (dev->vcmd.Req_Type == 0xc0) + dev->usb_enumstatus = VEN_CMDIN; + else + USB_WRITE(REG_USB_ENG,0x00000002); + + } + else { + USB_WRITE(REG_USB_ENG,0x00000002); + } + USB_WRITE(REG_USB_ENG,0x00000008); + USB_WRITE(REG_USB_IC,0x00000100); +} + +static void USB_ISR_Dev_Des(wbusb_dev* dev) +{ + USB_All_Flag_Clear(dev); + + dev->usb_enumstatus=GET_DEV; + + if(!dev->usb_online){ + + dev->usb_online=1; + + A_task_wake_up(dev); + B_task_wake_up(dev); + + printk("USB plugin !\n"); + } + + if ((USB_READ(REG_USB_CTLS)&0x0000001f) == 0x00000008)//check usb control transfer status register + { + USB_Cmd_Parsing(dev);//read setup data + if (dev->vcmd.Length <=(USB_Device[0]&0x000000ff)) + USB_WRITE(REG_USB_ENG,0x00000008);//ACK + else + { + dev->vcmd.Length = (USB_Device[0]&0x000000ff); + USB_WRITE(REG_USB_ENG,0x00000008); + } + } + else { + USB_WRITE(REG_USB_ENG,0x00000002);//return stall + } + +} + +static void USB_ISR_Conf_Des(wbusb_dev* dev) +{ + + USB_All_Flag_Clear(dev); + dev->usb_enumstatus=GET_CFG; + + if ((USB_READ(REG_USB_CTLS)&0x0000001f) == 0x00000008) + { + USB_Cmd_Parsing(dev); + if (dev->vcmd.Length <= ((USB_Config[0]&0x00ff0000)>>16))//configure total length + USB_WRITE(REG_USB_ENG,0x00000008); + else + { + dev->vcmd.Length = ((USB_Config[0]&0x00ff0000)>>16); + USB_WRITE(REG_USB_ENG,0x00000008); + } + } + else { + USB_WRITE(REG_USB_ENG,0x00000002); + } +} + +static void USB_ISR_Str_Des(wbusb_dev* dev) +{ + + USB_All_Flag_Clear(dev); + dev->usb_enumstatus=GET_STR; + + if ((USB_READ(REG_USB_CTLS)&0x0000001f) == 0x00000008) + { + USB_Cmd_Parsing(dev); + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00000000) + { + if (dev->vcmd.Length <= (USB_Lang_Id_String[0]&0x000000ff)) + USB_WRITE(REG_USB_ENG,0x00000008); + else + { + dev->vcmd.Length = (USB_Lang_Id_String[0]&0x000000ff); + USB_WRITE(REG_USB_ENG,0x00000008); + } + } + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00010000) + { + if (dev->vcmd.Length <= (USB_Vender_Id_String[0]&0x000000ff)) + USB_WRITE(REG_USB_ENG,0x00000008); + else + { + dev->vcmd.Length = (USB_Vender_Id_String[0]&0x000000ff); + USB_WRITE(REG_USB_ENG,0x00000008); + } + } + if ((USB_READ(REG_USB_ODATA0)&0x00ff0000) == 0x00020000) + { + if (dev->vcmd.Length <= (USB_Device_Id_String[0]&0x000000ff)) + USB_WRITE(REG_USB_ENG,0x00000008); + else + { + dev->vcmd.Length = (USB_Device_Id_String[0]&0x000000ff); + USB_WRITE(REG_USB_ENG,0x00000008); + } + } + } + else { + USB_WRITE(REG_USB_ENG,0x00000002); + } + +} + +void Vender_Data_Out(wbusb_dev* dev) +{ + + if ((USB_READ(REG_USB_CTLS)&0x0000001f) != 0) + { + + dev->vcmd.Index = dev->vcmd.Index + (USB_READ(REG_USB_CTLS)&0x0000001f); + dev->vcmd.Length = dev->vcmd.Length - (USB_READ(REG_USB_CTLS)&0x0000001f);; + + } + +} + + + +static void USB_ISR_CtlOut(wbusb_dev* dev) +{ + + if(dev->usb_enumstatus==VEN_CMDOUT) + { + + Vender_Data_Out(dev); + } + + USB_WRITE(REG_USB_ENG,0x00000002); + USB_WRITE(REG_USB_ENG,0x00000008); + +} + + +void Outp_Byte(UINT32 addr,UINT8 value) +{ + UINT32 tmp1,tmp2; + + tmp1=USB_READ(addr&0xfffffffc); + tmp2=(UINT32)(value); + if (addr%4==0) + { + tmp1=tmp1&0xffffff00; + tmp1=tmp1|tmp2; + } + else if (addr%4==1) + { + tmp1=tmp1&0xffff00ff; + tmp1=tmp1|(tmp2<<8); + } + else if (addr%4==2) + { + tmp1=tmp1&0xff00ffff; + tmp1=tmp1|(tmp2<<16); + } + else if (addr%4==3) + { + tmp1=tmp1&0x00ffffff; + tmp1=tmp1|(tmp2<<24); + } + USB_WRITE((addr&0xfffffffc),tmp1); +} + +void Class_Data_In(void) +{ + + USB_WRITE(REG_USB_CVCMD,0x01); + Outp_Byte(REG_USB_IDATA0,0x00); +} + + +void Vender_Data_In(wbusb_dev *dev) +{ + //UINT8 i; + // UINT32 tmp; + + + + if (dev->vcmd.Length > 0) + { + + + if (dev->vcmd.Length <= 16) + { + USB_WRITE(REG_USB_CVCMD,dev->vcmd.Length); + } + else + { + dev->vcmd.Length = dev->vcmd.Length - 16; + USB_WRITE(REG_USB_CVCMD,0x10); + } + + if (dev->vcmd.Req == 0x00) + { + printk("%s %d\n",__FUNCTION__,__LINE__); + + }else if (dev->vcmd.Req == 0x10) + { + printk("%s %d\n",__FUNCTION__,__LINE__); + }else if (dev->vcmd.Req == 0x04) + { + printk("%s %d\n",__FUNCTION__,__LINE__); + } + } + else + USB_WRITE(REG_USB_CVCMD,0x00); +} + + +void USB_ISR_Class_Cmd(wbusb_dev *dev) +{ + USB_All_Flag_Clear(dev); + + if(USB_READ(W90N745_USB_DEVICE+0x18)==0xfea1) + { + dev->usb_enumstatus=CLA_CMDIN; + } + USB_WRITE(REG_USB_ENG,0x00000008); + +} + +static void USB_ISR_CtlIn(wbusb_dev *dev) +{ + + switch(dev->usb_enumstatus) + { + case CLA_CMDIN: + Class_Data_In(); + break; + + case VEN_CMDIN: + Vender_Data_In(dev); + break; + + case GET_DEV: + case GET_CFG: + case GET_STR: + Get_Dev_Dpr_In(dev); + break; + + default: + USB_WRITE(REG_USB_ENG,0x00000002); + break; + + } + + USB_WRITE(REG_USB_ENG,0x00000001);//ACK for DATA-IN is Ready + +} + +static void USB_ISR_EpA_DMA_Complete(wbusb_dev *dev) +{ + + A_task_wake_up(dev); + + USB_WRITE(REG_USB_EPA_IC,0x00000008); + +} + + +static void USB_ISR_EpB_DMA_Complete(wbusb_dev *dev) +{ + if ((USB_READ(REG_USB_EPB_LENTH)-USB_READ(REG_USB_EPB_XFER))==0x0000001f) + dev->bulkonlycmd=1; + + if (dev->bulk_len!=0) + { + dev->bulk_len=0; + USB_WRITE(REG_USB_IE,USB_READ(REG_USB_IE)|0x00000100);//enable vender interrupt enable + } + + B_task_wake_up(dev); + + USB_WRITE(REG_USB_EPB_IC,0x00000008); + + +} + + + +static void SDRAM_USB_Transfer(wbusb_dev *dev,UINT8 epname,UINT8* buf ,UINT32 Tran_Size) +{ + + if (epname == EP_A) + { + start_write(dev,buf,Tran_Size); + } + else if (epname == EP_B) + { + start_read(dev,buf,Tran_Size); + } + + return; + +} + +static void SDRAM2USB_Bulk(wbusb_dev *dev,UINT8* buf,UINT32 Tran_Size) +{ + + if ((dev->ep[EP_A].EP_Dir==Ep_In)&&(dev->ep[EP_A].EP_Type==Ep_Bulk)) + SDRAM_USB_Transfer(dev,EP_A,buf,Tran_Size); + else if ((dev->ep[EP_B].EP_Dir==Ep_In)&&(dev->ep[EP_B].EP_Type==Ep_Bulk)) + SDRAM_USB_Transfer(dev,EP_B,buf,Tran_Size); + + return; + +} + +static void USB2SDRAM_Bulk(wbusb_dev *dev, UINT8* buf ,UINT32 Tran_Size) +{ + + if ((dev->ep[EP_A].EP_Dir==Ep_Out)&&(dev->ep[EP_A].EP_Type==Ep_Bulk)) + SDRAM_USB_Transfer(dev,EP_A,buf,Tran_Size); + else if ((dev->ep[EP_B].EP_Dir==Ep_Out)&&(dev->ep[EP_B].EP_Type==Ep_Bulk)) + SDRAM_USB_Transfer(dev,EP_B,buf,Tran_Size); + + return; + +} + +void write_data(wbusb_dev *dev,UINT8* buf,UINT32 length) +{ + + if(!dev->usb_online) + return; + SDRAM2USB_Bulk(dev, buf,length); +} + +void read_data(wbusb_dev *dev,UINT8* buf,UINT32 length) +{ + + if(!dev->usb_online) + return; + USB2SDRAM_Bulk(dev,buf,length); +} + + +void paser_irq(int irq,wbusb_dev *dev) +{ + + switch(irq) + { + case RSTI: + USB_ISR_Reset_Start(); + break; + + case SUSI: + USB_ISR_Suspend(dev); + break; + + case RUMI: + USB_ISR_Resume(); + break; + + case GDEVI: + USB_ISR_Dev_Des(dev);//Get device Descriptor(); + break; + + case GCFGI: + USB_ISR_Conf_Des(dev); + break; + + case GSTRI: + USB_ISR_Str_Des(dev); + break; + + case CLAI: + USB_ISR_Class_Cmd(dev); + break; + + case VENI: + USB_ISR_Vendor_Cmd(dev); + + case CDOI: + USB_ISR_CtlOut(dev); + break; + + case CDII: + USB_ISR_CtlIn(dev); + break; + + case RST_ENDI: + USB_ISR_Reset_End(dev); + break; + + + + default: + //printk("irq: %d not handled !\n",irq); + break; + + } + + USB_WRITE(REG_USB_IC,(1<<(irq-1)));//clear irq bit + + return ; + +} + + +static void wbusbd_irq(int irq, void *usbdev, struct pt_regs *r) +{ + UINT32 id,dmaid,i; + wbusb_dev *dev; + + dev=(wbusb_dev *)(usbdev); + + dmaid = USB_READ(REG_USB_EPA_IS); + + if (dmaid&0x00000008) + { + USB_ISR_EpA_DMA_Complete(dev); + } + + dmaid = USB_READ(REG_USB_EPB_IS); + + if (dmaid&0x00000008) + { + USB_ISR_EpB_DMA_Complete(dev); + } + + id = USB_READ(REG_USB_IS); + + for(i=0;i<16;i++) + { + if(id&(1<usb_online) + { + B_task_block(dev); + return -1; + } + + USB2SDRAM_Bulk(dev,cbw,0x1f); + + if (dev->bulkonlycmd) + { + dev->bulkonlycmd=0;//If DMA complete and got 31 bytes command, this will be "1" + + //dump_buffer(cbw, 0x1f); + + return 0; + } + + return -1; + +} + +static int wbusb_installirq(wbusb_dev *dev) +{ + + if (request_irq(INT_USBD, &wbusbd_irq, SA_INTERRUPT/*|SA_SAMPLE_RANDOM*/, + driver_name, dev) != 0) { + printk("Request irq error\n"); + return -EBUSY; + } + + Enable_Int(INT_USBD); + + return 0; + +} + + +static void USB_Irq_Init(wbusb_dev *dev) +{ + + ENTER(); + + init_waitqueue_head(&dev->wusbd_wait_a);//write + init_waitqueue_head(&dev->wusbd_wait_b);//read + init_waitqueue_head(&dev->wusbd_wait_c);//vcom vendor cmd + + if(wbusb_installirq(dev)==0) + printk("install usb device irq ok\n"); + + USB_WRITE(REG_USB_EPA_IE,(USB_READ(REG_USB_EPA_IE)|0x00000008));//enable DMA interrupt + USB_WRITE(REG_USB_EPB_IE,(USB_READ(REG_USB_EPB_IE)|0x00000008));//enable DMA interrupt + + + LEAVE(); + + return ; +} + + wbusb_dev *the_controller=NULL; + + void* wbusb_register_driver(void) + { + if(the_controller) + return the_controller; + else + return NULL; + } + + +void wbusbd_probe(void) +{ + wbusb_dev *dev = 0; + + ENTER(); + /* alloc, and start init */ + dev = kmalloc (sizeof *dev, GFP_KERNEL); + if (dev == NULL){ + DBGOUT("kmalloc error !\n"); + goto done; + } + + memset(dev, 0, sizeof *dev); + + dev->rw_data=write_data; + dev->rd_data=read_data; + dev->wait_cbw=check_cbw; + + USB_Init(dev); + + USB_Irq_Init(dev); + + the_controller=dev; + + LEAVE(); + +done: + + return ; + +} + +static char buffer[4096]; + +static size_t usb_client_read(char /*__user*/ *buf, size_t length) +{ + char *tmp = (char *)((UINT32)buffer | 0x80000000); + + ENTER(); + //printk("Buffer : %08x, Count : %08x\n", buf, length); + if(length == 0) + return 0; + + if(length > 4096) + length = 4096; + + read_data(the_controller, tmp, length); + + if(copy_to_user(buf, tmp, length)) + return -EFAULT; + + LEAVE(); + return length; +} + +static size_t usb_client_write(const char/* __user*/ *buf, size_t length) +{ + char *tmp = (char *)((UINT32)buffer | 0x80000000); + + ENTER(); + //printk("Buffer : %08x, Count : %08x\n", buf, length); + + if(length == 0) + return 0; + + if(length > 4096) + length = 4096; + + if(copy_from_user(tmp, buf, length)) + return -EFAULT; + + write_data(the_controller, tmp, length); + + LEAVE(); + + return length; +} + +static int usb_client_get_cbw(char *buf) +{ + int retval = 0; + char *tmp = (char *)((UINT32)buffer | 0x80000000); + + ENTER(); + + retval = check_cbw(the_controller, tmp); + + if(copy_to_user(buf, tmp, 0x1f)) + return -EFAULT; + + LEAVE(); + + return 0; +} + +static int wbusb_open(struct inode *ip, struct file *filp) +{ + ENTER(); + LEAVE(); + return 0; +} + +static int wbusb_release(struct inode *ip, struct file *filp) +{ + ENTER(); + LEAVE(); + return 0; +} + +static ssize_t wbusb_read(struct file *filp, char /*__user*/ * buf, size_t count, loff_t *lp) +{ + return usb_client_read(buf, count); +} + +static ssize_t wbusb_write(struct file *filp, const char /*__user*/ * buf, size_t count, loff_t *lp) +{ + return usb_client_write(buf, count); +} + +static int wbusb_ioctl(struct inode *ip, struct file *filp, unsigned int cmd, unsigned long arg) +{ + int err = 0; + int retval = 0; + + ENTER(); + + if (_IOC_TYPE(cmd) != WBUSB_IOC_MAGIC) return -ENOTTY; + if (_IOC_NR(cmd) > WBUSB_IOC_MAXNR) return -ENOTTY; + + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void /*__user*/ *)arg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void /*__user*/ *)arg, _IOC_SIZE(cmd)); + + if (err) return -EFAULT; + + + switch(cmd) { + case WBUSB_IOC_GETCBW: + retval = usb_client_get_cbw((char *)arg); + break; + + case WBUSB_GETVLEN: + + if(!the_controller->bulk_len) + { + //printk("waiting PC\n"); + //C_task_block(the_controller); /* 11.28 mark, PT23 HHWu */ + } + + //printk("wakeup now !\n"); + + *(unsigned long*)arg=the_controller->bulk_len; + break; + + case WBUSB_REPLUG: +#if 0 + if(*(char*)arg) + { +#endif + printk("VCOM Type !!!\n"); + USB_Device=USB_Device_VCOM; + USB_Config=USB_Config_VCOM; + USB_Device_Id_String=USB_Device_Id_String_VCOM; + USB_Vender_Id_String=USB_Vender_Id_String_VCOM; +#if 0 + } + else + { + printk("MASS Type !!!\n"); + USB_Device=USB_Device_Mass; + USB_Config=USB_Config_Mass; + USB_Device_Id_String=USB_Device_Id_String_Mass; + USB_Vender_Id_String=USB_Vender_Id_String_Mass; + } +#endif + memset(the_controller,0, sizeof *the_controller); + the_controller->rw_data=write_data; + the_controller->rd_data=read_data; + the_controller->wait_cbw=check_cbw; + Reset_USB(the_controller); + + + break; + + default: + return -ENOTTY; + } + + LEAVE(); + + return retval; + +} + +//struct cdev wbusb_cdev; + +struct file_operations wbusb_fops = { + .owner = THIS_MODULE, + .open = wbusb_open, + .release = wbusb_release, + .read = wbusb_read, + .write = wbusb_write, + .ioctl = wbusb_ioctl, +}; + +static int __init wbusb_init (void) +{ + int retval; + + ENTER(); + +#ifdef USBDVCOM + printk("VCOM Type!\n"); + USB_Device=USB_Device_VCOM; + USB_Config=USB_Config_VCOM; + USB_Device_Id_String=USB_Device_Id_String_VCOM; + USB_Vender_Id_String=USB_Vender_Id_String_VCOM; +#else + + USB_Device=USB_Device_Mass; + USB_Config=USB_Config_Mass; + USB_Device_Id_String=USB_Device_Id_String_Mass; + USB_Vender_Id_String=USB_Vender_Id_String_Mass; +#endif + + wbusbd_probe(); +#if 0 + retval = register_chrdev_region(MKDEV(WBUSB_MAJOR, 0), 1, "usbclient"); + if ( retval < 0) { + printk("wbusb : can not register chrdev region\n"); + return retval; + } + + cdev_init(&wbusb_cdev, &wbusb_fops); + wbusb_cdev.owner = THIS_MODULE; + wbusb_cdev.ops = &wbusb_fops; + retval = cdev_add(&wbusb_cdev, MKDEV(WBUSB_MAJOR, 0), 1); + if ( retval < 0) { + printk("wbusb : can not add wbusb_cdev\n"); + unregister_chrdev_region(MKDEV(WBUSB_MAJOR, 0), 1); + return retval; + } +#endif + retval = register_chrdev(WBUSB_MAJOR, "usbclient", &wbusb_fops); + if( retval < 0){ + printk("can't get major %d\n", WBUSB_MAJOR); + return retval; + } + + + printk("W90N745 USB Device Driver 1.0 Initilization Success\n"); + + + LEAVE(); + + return 0; + +} + +static void __exit wbusb_cleanup (void) +{ + ENTER(); +#if 0 + cdev_del(&wbusb_cdev); + unregister_chrdev_region(MKDEV(WBUSB_MAJOR, 0), 1); +#endif + unregister_chrdev(WBUSB_MAJOR, "smartcard"); + + Disable_USB(the_controller); + + if(the_controller) + kfree(the_controller); + + LEAVE(); + + return ; +} + +module_init(wbusb_init); +module_exit(wbusb_cleanup); + +MODULE_LICENSE("GPL"); diff --git a/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.h b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.h new file mode 100644 index 0000000..b27dfd9 --- /dev/null +++ b/uClinux-2.4.20-uc1/drivers/usb/wbusbd/w90n745_vcom.h @@ -0,0 +1,261 @@ +/**************************************************************************** + * * + * Copyright (c) 2005 - 2007 Winbond Electronics Corp. All rights reserved. * + * * + ****************************************************************************/ + +/**************************************************************************** + * + * FILENAME + * w90n745_vcom .h + * + * VERSION + * 1.0 + * + * DESCRIPTION + * + * + * DATA STRUCTURES + * None + * + * FUNCTIONS + * None + * + * HISTORY + * 2005/08/01 Ver 1.0 Created by PC34 Lsshi + * + * + * REMARK + * None + *************************************************************************/ + +#ifndef __W90N745_VCOM_H +#define __W90N745_VCOM_H +//types + +#define CONST const + +#define FALSE 0 +#define TRUE 1 + +typedef void VOID; +typedef void * PVOID; + +typedef char BOOL; +typedef char * PBOOL; + +typedef char INT8; +typedef char CHAR; +typedef char * PINT8; +typedef char * PCHAR; +typedef unsigned char UINT8; +typedef unsigned char UCHAR; +typedef unsigned char * PUINT8; +typedef unsigned char * PUCHAR; +typedef char * PSTR; +typedef const char * PCSTR; + +typedef short SHORT; +typedef short * PSHORT; +typedef unsigned short USHORT; +typedef unsigned short * PUSHORT; + +typedef short INT16; +typedef short * PINT16; +typedef unsigned short UINT16; +typedef unsigned short * PUINT16; + +typedef int INT; +typedef int * PINT; +typedef unsigned int UINT; +typedef unsigned int * PUINT; + +typedef int INT32; +typedef int * PINT32; +typedef unsigned int UINT32; +typedef unsigned int * PUINT32; + + +typedef float FLOAT; +typedef float * PFLOAT; + +typedef double DOUBLE; +typedef double * PDOUBLE; + +typedef int SIZE_T; + +typedef unsigned char REG8; +typedef unsigned short REG16; +typedef unsigned int REG32; + + +#define outpb(port,value) (*((UINT8 volatile *) (port))=value) +#define inpb(port) (*((UINT8 volatile *) (port))) +#define outphw(port,value) (*((UINT16 volatile *) (port))=value) +#define inphw(port) (*((UINT16 volatile *) (port))) +#define outpw(port,value) (*((UINT32 volatile *) (port))=value) +#define inpw(port) (*((UINT32 volatile *) (port))) + + +#define USB_WRITE(addr,data) (*((unsigned int volatile *)(addr))=data) +#define USB_READ(addr) (*((unsigned int volatile *)(addr))) +/// +#define ENDPOINTS 2 //bulkin/out +#define USB_OFFSET 0xB4 + +#define RSTI 1 +#define SUSI 2 +#define RUMI 3 +#define GDEVI 5 +#define GCFGI 6 +#define GSTRI 7 +#define CLAI 8 +#define VENI 9 +#define CDOI 10 +#define CDII 11 +#define RST_ENDI 15 +#define RST_ENDI 15 + +/********************************************************************************************************** + * + * USB Device Control Registers + * + **********************************************************************************************************/ +#define W90N745_USB_DEVICE 0xfff06000 +#define REG_USB_CTL (W90N745_USB_DEVICE+0x00) /* USB control register */ +#define REG_USB_CVCMD (W90N745_USB_DEVICE+0x04) /* USB class or vendor command register */ +#define REG_USB_IE (W90N745_USB_DEVICE+0x08) /* USB interrupt enable register */ +#define REG_USB_IS (W90N745_USB_DEVICE+0x0c) /* USB interrupt status register */ +#define REG_USB_IC (W90N745_USB_DEVICE+0x10) /* USB interrupt status clear register */ +#define REG_USB_IFSTR (W90N745_USB_DEVICE+0x14) /* USB interface and string register */ +#define REG_USB_ODATA0 (W90N745_USB_DEVICE+0x18) /* USB control transfer-out port 0 register */ +#define REG_USB_ODATA1 (W90N745_USB_DEVICE+0x1C) /* USB control transfer-out port 1 register */ +#define REG_USB_ODATA2 (W90N745_USB_DEVICE+0x20) /* USB control transfer-out port 2 register */ +#define REG_USB_ODATA3 (W90N745_USB_DEVICE+0x24) /* USB control transfer-out port 3 register */ +#define REG_USB_IDATA0 (W90N745_USB_DEVICE+0x28) /* USB control transfer-in data port 0 register */ +#define REG_USB_IDATA1 (W90N745_USB_DEVICE+0x2C) /* USB control transfer-in data port 1 register */ +#define REG_USB_IDATA2 (W90N745_USB_DEVICE+0x30) /* USB control transfer-in data port 2 register */ +#define REG_USB_IDATA3 (W90N745_USB_DEVICE+0x34) /* USB control transfer-in data port 2 register */ +#define REG_USB_SIE (W90N745_USB_DEVICE+0x38) /* USB SIE status Register */ +#define REG_USB_ENG (W90N745_USB_DEVICE+0x3c) /* USB Engine Register */ +#define REG_USB_CTLS (W90N745_USB_DEVICE+0x40) /* USB control transfer status register */ +#define REG_USB_CONFD (W90N745_USB_DEVICE+0x44) /* USB Configured Value register */ +#define REG_USB_EPA_INFO (W90N745_USB_DEVICE+0x48) /* USB endpoint A information register */ +#define REG_USB_EPA_CTL (W90N745_USB_DEVICE+0x4c) /* USB endpoint A control register */ +#define REG_USB_EPA_IE (W90N745_USB_DEVICE+0x50) /* USB endpoint A Interrupt Enable register */ +#define REG_USB_EPA_IC (W90N745_USB_DEVICE+0x54) /* USB endpoint A interrupt clear register */ +#define REG_USB_EPA_IS (W90N745_USB_DEVICE+0x58) /* USB endpoint A interrupt status register */ +#define REG_USB_EPA_ADDR (W90N745_USB_DEVICE+0x5c) /* USB endpoint A address register */ +#define REG_USB_EPA_LENTH (W90N745_USB_DEVICE+0x60) /* USB endpoint A transfer length register */ +#define REG_USB_EPB_INFO (W90N745_USB_DEVICE+0x64) /* USB endpoint B information register */ +#define REG_USB_EPB_CTL (W90N745_USB_DEVICE+0x68) /* USB endpoint B control register */ +#define REG_USB_EPB_IE (W90N745_USB_DEVICE+0x6c) /* USB endpoint B Interrupt Enable register */ +#define REG_USB_EPB_IC (W90N745_USB_DEVICE+0x70) /* USB endpoint B interrupt clear register */ +#define REG_USB_EPB_IS (W90N745_USB_DEVICE+0x74) /* USB endpoint B interrupt status register */ +#define REG_USB_EPB_ADDR (W90N745_USB_DEVICE+0x78) /* USB endpoint B address register */ +#define REG_USB_EPB_LENTH (W90N745_USB_DEVICE+0x7c) /* USB endpoint B transfer length register */ +#define REG_USB_EPC_INFO (W90N745_USB_DEVICE+0x80) /* USB endpoint C information register */ +#define REG_USB_EPC_CTL (W90N745_USB_DEVICE+0x84) /* USB endpoint C control register */ +#define REG_USB_EPC_IE (W90N745_USB_DEVICE+0x88) /* USB endpoint C Interrupt Enable register */ +#define REG_USB_EPC_IC (W90N745_USB_DEVICE+0x8c) /* USB endpoint C interrupt clear register */ +#define REG_USB_EPC_IS (W90N745_USB_DEVICE+0x90) /* USB endpoint C interrupt status register */ +#define REG_USB_EPC_ADDR (W90N745_USB_DEVICE+0x94) /* USB endpoint C address register */ +#define REG_USB_EPC_LENTH (W90N745_USB_DEVICE+0x98) /* USB endpoint C transfer length register */ +#define REG_USB_EPA_XFER (W90N745_USB_DEVICE+0x9c) /* USB endpoint A remain transfer length register */ +#define REG_USB_EPA_PKT (W90N745_USB_DEVICE+0xa0) /* USB endpoint A remain packet length register */ +#define REG_USB_EPB_XFER (W90N745_USB_DEVICE+0xa4) /* USB endpoint B remain transfer length register */ +#define REG_USB_EPB_PKT (W90N745_USB_DEVICE+0xa8) /* USB endpoint B remain packet length register */ +#define REG_USB_EPC_XFER (W90N745_USB_DEVICE+0xac) /* USB endpoint C remain transfer length register */ +#define REG_USB_EPC_PKT (W90N745_USB_DEVICE+0xb0) /* USB endpoint C remain packet length register */ + +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define SizePerSector 512 + +#define RAMDISK + + +//extern UINT8 volatile USB_Power_Flag; // 0: bus power de-attached; 1: attached + +//bulk set +//extern UINT32 volatile Bulk_set_length; +//extern UINT8 volatile bulksetflag; +/* Define Endpoint feature */ +#define Ep_In 0x01 +#define Ep_Out 0x00 +#define Ep_Bulk 0x01 +#define Ep_Int 0x02 +#define Ep_Iso 0x03 + +#define EP_A 0x00 +#define EP_B 0x01 + + + +typedef struct +{ + UINT32 dwAddr; + UINT32 dwValue; + +}USB_INIT_T; + +typedef struct +{ + UINT8 Req_Type; + UINT8 Req; + UINT16 Value; + UINT16 Index; + UINT16 Length; +}USB_Vender_Cmd_Format_T __attribute__ ((aligned (4))); // each field of vendor command + +typedef struct { + UINT8 EP_Num; + UINT8 EP_Dir; + UINT8 EP_Type; + UINT8 p; +} USB_EP_Inf_T __attribute__ ((aligned (4))); + +///// + +//WBUSB Structs + typedef struct _wbusb_dev { + + UINT8 epnum; + UINT8 usb_online; + UINT8 bulkonlycmd; + UINT32 bulk_len; + + wait_queue_head_t wusbd_wait_a,wusbd_wait_b,wusbd_wait_c; + + USB_EP_Inf_T ep[2]; + USB_Vender_Cmd_Format_T vcmd ; + + enum{ + GET_DEV=1, + GET_CFG, + GET_STR, + CLA_CMDIN, + VEN_CMDIN, + VEN_CMDOUT + }usb_enumstatus; + + int (*wait_cbw)(struct _wbusb_dev *dev,void* cbw); + void (*rw_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length); + void (*rd_data)(struct _wbusb_dev *dev,UINT8* buf,UINT32 length); + +}wbusb_dev __attribute__ ((aligned (4))); +///// + +#define WBUSB_MAJOR 250 + +#define WBUSB_IOC_MAXNR 3 + +#define WBUSB_IOC_MAGIC 'u' + +#define WBUSB_IOC_GETCBW _IOR(WBUSB_IOC_MAGIC, 0, char *) +#define WBUSB_GETVLEN _IOR(WBUSB_IOC_MAGIC, 1, unsigned long *) +#define WBUSB_REPLUG _IOR(WBUSB_IOC_MAGIC, 2, char *) + +#define INT_USBD 22 + +#endif /* __WBUSB_H */ -- cgit v0.12